Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS game - shooting in random directions [closed]

I am working on a HTML5 canvas / Javascript based game. It is a fighter jet game, after I pass specific score my main boss will spawn. Everything works like I wanted to but, I dont how to do boss shooting. My jet fires a single bullet verticaly but my idea was to make the boss fire in random directions. At least 3 bullets at the same time, in diferent directions. I am not using jQuery at all just normal JS. Boss moves horizontaly from border to another border, but its not shooting, so I might need a little bit of help. Any ideas ?

enter image description here

Red lines are my idea of shooting. I am capable of checking bullet / jet collision.

Some code of boss (vertical) shooting.

function BossBullet() {
    this.srcX = 1304;
    this.srcY = 0;
    this.drawX = 500;
    this.drawY = 0;
    this.width = 4;
    this.height = 16;
}

BossBullet.prototype.akt = function(X,Y) {

    this.noseX=X;
    this.noseY=Y;
};

BossBullet.prototype.draw = function() {
    ctxBullet.clearRect(0, 0, gameWidth, gameHeight);
    this.drawY += 10;

    ctxBullet.drawImage(imgSprite, this.srcX, this.srcY, this.width, this.height, this.drawX, this.drawY, this.width, this.height);
   //strela[hudba].play();
    if (this.drawY > 700) {
        this.drawY= this.noseY;
        this.drawX= this.noseX;

    }
};

and this is how it looks like. It fires single bullet from bosses nose and goes down until it reaches its Y value 0 and respawns.

enter image description here

I tried to add to this.drawY += 10; also this.drawX += 1; but this way it doesnt move at all. Any ideas how to change the directory of the bullet??

like image 641
Toesmash Avatar asked May 16 '13 15:05

Toesmash


2 Answers

LIVE DEMO (Use mouse clicks to fire bullets)

zch's answer is fine but the problem is that the HTML5 canvas coordinates system and the trigonometric cycle is different than usual and we need to do some math tricks to calculate the angle that matches the velocity update and the drawing of the bullets.

comparison between coordinates systems

Here follow the code that I used for the bullets:

// Bullet class
function Bullet(x, y, speed, angle,  width, height, colors){
    this.x = x;
    this.y = y;
    this.speed = speed;
    this.angle = angle;
    this.width = width;
    this.height = height;
    this.colors = colors;       
    this.frameCounter = 0;
}

Bullet.prototype.update = function(){        
    // (!) here we calculate the vector (vx, vy) that represents the velocity
    var vx = this.speed * Math.cos(this.angle-(Math.PI/2));
    var vy = this.speed * Math.sin(this.angle-(Math.PI/2));

    // move the bullet 
    this.x += vx;
    this.y += vy;       
}

Bullet.prototype.draw = function(context, xScroll,  yScroll){       
    context.save(); 

    if(this.angle != 0) {
        // translate to the orign of system
        context.translate(this.x-xScroll, this.y-yScroll);  
        // rotate
        context.rotate(this.angle); 
        // translate back to actual position
        context.translate(xScroll-this.x, yScroll-this.y); 
    }
    // animate the bullets (changing colors)
    context.fillStyle = this.colors[this.frameCounter % this.colors.length];    
    this.frameCounter++;

    // draw the bullet
    context.fillRect((this.x-this.width/2) - xScroll, (this.y-this.height/2) - yScroll, this.width, this.height);

    context.restore();          
}

The update and the draw methods should be called every frame for each bullet.

Now compare this code presents inside the update function

var vx = this.speed * Math.cos(this.angle-(Math.PI/2));
var vy = this.speed * Math.sin(this.angle-(Math.PI/2));

with the code below, as answered by zch.

var vx = speed * Math.cos(angle);
var vy = speed * Math.sin(angle);

It's just a math transformation to match our angle system with the canvas rotate method. This is accomplished by rotate the first system by 90 degrees.

angle system

Notice that you can also do this way:

var vx = this.speed * Math.sin(this.angle);
var vy = this.speed * -Math.cos(this.angle);

Trigonometry is your ally to make fun games!

Remember to create the fire function for your boss:

Boss.prototype.fire = function(){

    var nBullets = 3; // number of bullets to fire
    for(var x = 0; x < nBullets; ++x){  

        // angle between PI/2 and 3PI/2 (in radians)
        var angle =  (1 + 2 * Math.random()) * Math.PI / 2;

        // create a new bullet
        this.bullets.push(new Bullet(this.x, this.y, 10, angle, 2, 15, this.bulletsColors));
    }        
}

The above code assumes that your boss have an array of bullets.

See the full code and play demo

like image 153
Gustavo Carvalho Avatar answered Oct 24 '22 09:10

Gustavo Carvalho


You would need to represent bullets bullets. For each bullet you need to store its position (x, y) and velocity along each axis (vx, vy). During each unit of time increase position by velocity:

x += vx;
y += vy;

You probably want bullets shot at random angle, but constant speed. You can generate velocities using trigonometry:

var angle = 2 * Math.PI * Math.random();
var vx = speed * Math.cos(angle);
var vy = speed * Math.sin(angle);

You can limit angle to smaller range if you don't want to shot in all directions. For example for range 5/4π to 7/4π:

var angle = (5 + 2 * Math.random()) / 4 * Math.PI;
like image 33
zch Avatar answered Oct 24 '22 09:10

zch