user3501229
user3501229

Reputation: 13

Javascript- canvas shooting positioning

I want to make a spaceship shoot in a game I am making, but I dont seem to be able to get the positions of the shots to load properly. I have an array called shots[] and I want to push Shot() objects into it every N ticks when the player is holding down the mouse button. So basically I want Shot() have x property equal to my ship.x property and y=ship.y. Then I want it to have a Shot.dx property, which changes, depending on wether the cursor is above the middle of canvas or bellow (+3/-3) or left or right of the center (dy=+3/-3).

// Shooting
        var shots = [] //Bullet array

//Object, which should be the position of the bullet.
        function Shot() {
         this.x=350
         this.y=250;
         this.dx=Shoot.x
         this.dy=Shoot.y
        }

//This keeps track of the cursor position in relation to the center of canvas.
        function Shoot() {
            started = false; 
            this.mousedown = function (ev) {
                started = true; 
            };

            this.mousemove = function (ev) {
                if (started) { 
                        if (ev.clientX>=350) this.x=3;
                            else this.x=-3;
                        if (ev.clientY>=250) this.y=3;
                            else this.y=-3;
                }
            };
            this.mouseup = function (ev) {
                started = false;
            };
        }
//The problem is, that when I set this.x in Shot() to be =ship.x the values
//dont get updated and it stays undefined after I push it into the array.
//Now I have it set to the center of canvas, but that it useless because it needs
//to move with the ship, but even now I am getting weird numbers and not the numbers
//that I actually put in. dx and dy dont get updated at all.

   // Ship Model
        var ship = {
            x: 350,
            y: 250,
            lives: 3,
            invulnerable: 0,
        }

//Main function- pushes the objects into the array
        function mainLoop() {
            tick++
            count()
            interval()
            chase()
            console.log(started)
            if (started && tick%20==0) 
                    shots.push(new Shot());
            keyboard()
            display()
            check()
            requestAnimationFrame(mainLoop);
        }

// Initialization
        window.onload = function() {
          // Setting variables
            button = document.getElementById("button")
            text = document.getElementById("text")
            canvas = document.getElementById("canvas")
            ctx = canvas.getContext("2d")
            weapon = new Shoot();
            canvas.onmousedown = weapon.mousedown;
            canvas.onmousemove = weapon.mousemove;
            canvas.onmouseup = weapon.mouseup;
            requestAnimationFrame(mainLoop);
        }

//I know this is a lot of code, but its all relevant. I am new to Javascript
//so I expect this to be some sort of a trivial error.

Here is a JSfiddle, but I dont know how that works so I cant get it to draw canvas, sorry: http://jsfiddle.net/JH3M6/

Upvotes: 1

Views: 4653

Answers (1)

markE
markE

Reputation: 105015

Here's an outline of how to fire your shots:

  • create an array to hold your shot objects

  • on mousedown: set the started flag (starts firing)

  • on mousedown: set the firing position for any new shot(s) to the current mouse position

  • on mousemove: reset the firing position for any new shot(s) to the current mouse position

  • on mouseup: clear the started flag (stops firing)

In the animation loop:

  • add a shot at the current firing position if the mouse is still down
  • move all shots by their dx,dy
  • remove any shots from the shots[] array if the shot has moved off-canvas
  • clear the screen and draw the shots in their new positions

A Demo: http://jsfiddle.net/m1erickson/2f9sf/

Here's example code:

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>
<script>
$(function(){

    // canvas related vars
    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var cw=canvas.width;
    var ch=canvas.height;
    var bb=canvas.getBoundingClientRect();
    var offsetX=bb.left;
    var offsetY=bb.top;
    ctx.fillStyle="blue";

    // vars related to firing position and Shot(s)
    var shotColor=ctx.fillStyle;
    var started,mouseX,mouseY,dx,dy;

    // Shots fired
    var shots = [] //Bullet array

    //Object, which should be the position of the bullet.
    function Shot(x,y,dx,dy) {
        this.x=x;
        this.y=y;
        this.dx=dx;
        this.dy=dy;
    }
    Shot.prototype.display=function(){
        // make fillstyle blue if it's not already blue
        if(!ctx.fillStyle==shotColor){ctx.fillStyle=shotColor;}
        // draw the shot on the canvas
        ctx.fillRect(this.x,this.y,5,5);
    }

    // listen for mouse events
    canvas.onmousedown=function(e){ started=true; setFirePosition(e); }
    canvas.onmouseup=function(e){ started=false; }
    canvas.onmousemove=function(e){
        if(started){setFirePosition(e);}
    }

    // start the animation loop
    requestAnimationFrame(animate);

    // set the firing position of the next shot
    function setFirePosition(e){
        mouseX=parseInt(e.clientX-offsetX);
        mouseY=parseInt(e.clientY-offsetY);
        dx=(mouseX>=canvas.width/2)?-3:3;
        dy=(mouseY>=canvas.height/2)?-3:3;        
    }

    // animation loop
    // add shots if the mouse is down
    // move shots until they move off-canvas
    function animate(){

        // request another frame
        requestAnimationFrame(animate);

        // if the mouse is down, add a shot
        if(started){
            shots.push(new Shot(mouseX,mouseY,dx,dy));
        }

        // if no work to do, return
        if(shots.length==0){return;}

        // new array of active shots
        // "active" == shot has not moved off-canvas
        var a=[];

        // clear the canvas for this frame
        ctx.clearRect(0,0,cw,ch);

        for(var i=0;i<shots.length;i++){

            // get a shot to process
            var shot=shots[i];

            // move this shot
            shot.x+=shot.dx;
            shot.y+=shot.dy;

            // if the shot hasn't moved offscreen
            // add the shot to "a" (the replacement shots array);
            // draw this shot
            if(shot.x>=0 && shot.x<=cw && shot.y>0 && shot.y<=ch){
                a.push(shot);
                shot.display();
            }
        }

        // if shots went off-canvas, remove them from shots[]
        if(a.length<shots.length){
            shots.length=0;
            Array.prototype.push.apply(shots,a);
        }

    }

}); // end $(function(){});
</script>
</head>
<body>
    <h4>Mousedown to fire shots</h4>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

Upvotes: 1

Related Questions