0
votes

I'm relatively new to canvas and I'm trying to make a space ship type game. I have everything else I'd like down, except for the ship turning itself. I want to make the image of the ship rotate when the arrow keys are clicked.

So if the left arrow key is clicked, it will turn to face the left, and the right arrow key is clicked it will turn to face the right, and so on. I really can't figure this out, if anyone can show me how to do this I would really appreciate it.

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');


/*Variable to store score*/
var score = 0;

/*Variable that stores the players object properties*/
var x = 50;
var y = 100;
var speed = 6;
var sideLength = 50;

/*Flags to track when keypress is active*/
var down = false;
var up = false;
var left = false;
var right = false;

/*Variables that store target position and size*/
var targetX = 0;
var targetY = 0;
var targetLength = 25;

/*If a number is within range b to c*/
function isWithin(a, b, c) {
    return (a > b && a < c)
}

var countDown = 30;

/*Id to track set time*/
var id = null;

/*Listening for if one of the keys is pressed*/
canvas.addEventListener('keydown', function (event) {
    event.preventDefault();
    console.log(event.key, event.keyCode);
    if (event.keyCode === 40) {
        down = true;
    }
    if (event.keyCode === 38) {
        up = true;
    }
    if (event.keyCode === 37) {
        left = true;
    }
    if (event.keyCode === 39) {
        right = true;
    }
});

/*Listening for if one of the keys is released*/
canvas.addEventListener('keyup', function (event) {
    event.preventDefault();
    console.log(event.key, event.keyCode);
    if (event.keyCode === 40) {
        down = false;
    }
    if (event.keyCode === 38) {
        up = false;
    }
    if (event.keyCode === 37) {
        left = false;
    }
    if (event.keyCode === 39) {
        right = false;
    }
});

/*Function to show menu*/
function menu() {
    erase();
    context.fillStyle = '#000000';
    context.font = '36px Arial';
    context.textAlign = 'center';
    context.fillText('Collect The Thing', canvas.width / 2, canvas.height / 4);
    context.font = '30px Arial';
    context.fillText('Press to Start', canvas.width / 2, canvas.height / 2);

    /*Listen for click to start game*/
    canvas.addEventListener('click', startGame);
}

/*Function to start the game*/
function startGame() {
    /*reduce the countdown timer every 1 second*/
    id = setInterval(function () {
        countDown--;
    }, 1000)

    /*remove click events*/
    canvas.removeEventListener('click', startGame);

    moveTarget();

    draw();
}

/*Show game over screen*/
function endGame() {
    /*stop the countdown*/
    clearInterval(id);
    /*clear game board*/
    erase();
    context.fillStyle = '#000000';
    context.font = '36px Arial';
    context.textAlign = 'center';
    context.fillText('Finale Score: ' + score, canvas.width / 2, canvas.height / 4);
}

/*Move target to random location in canvas*/
function moveTarget() {
    targetX = Math.round(Math.random() * canvas.width - targetLength);
    targetY = Math.round(Math.random() * canvas.height - targetLength);
}

/*Clear the Canvas*/
function erase() {
    context.fillStyle = '#FFFFFF';
    context.fillRect(0, 0, 600, 500);
}

/*Main animation drawing loop with game logic*/
function draw() {
    erase();

    /*Move the player sqaure*/
    if (down) {
        y += speed;
    }
    if (up) {
        y -= speed;
    }
    if (right) {
        x += speed;
    }
    if (left) {
        x -= speed;
    }

    if (y + sideLength > canvas.height) {
        y = canvas.height - sideLength;
    }

    if (y < 0) {
        y = 0;
    }
    if (x < 0) {
        x = 0;
    }

    if (x + sideLength > canvas.width) {
        x = canvas.width - sideLength;
    }

    
    /*Collide with target*/
    if (isWithin(targetX, x, x + sideLength) || isWithin(targetX + targetLength, x, x + sideLength)) {
        if (isWithin(targetY, y, y + sideLength) || isWithin(targetY + targetLength, y, y + sideLength)) {
            /*respawn target in a random location*/
            moveTarget();
            /*Increase score by 1*/
            score++;
        }
    }

    //Draw player object
    context.fillRect(x, y, sideLength, sideLength);
    context.drawImage(baseImage, x, y, sideLength, sideLength);
   

    /*Draw target sqaure*/
    context.fillStyle = '#00FF00';
    context.fillRect(targetX, targetY, targetLength, targetLength);
    

    //Timer and Score
    context.fillStyle = '#000000';
    context.font = '24px Arial';
    context.textAlign = 'left';
    context.fillText('Score: ' + score, 10, 24);
    context.fillText('Time Remaining: ' + countDown, 10, 50);

    if (countDown <= 0) {
        endGame();
    } else {
        window.requestAnimationFrame(draw);
    }
}

baseImage= new Image();
         baseImage.src='xwing3.png'; 
         baseImage.onload= function() {
            menu();
         }



canvas.focus();
1

1 Answers

0
votes

I think in this regard you have two options.

  1. You could have a sprite for every direction that you want the ship to face, then when you draw the image, you could choose the sprite that matches.
if(left == true) {baseImage.src='xwing3left.png';}
  1. You could use the canvas rotate() method. This would make things more complicated, but it actually rotates the canvas and could give more opportunity to experiment.

It actually applies a transformation matrix to the canvas before it draws so you could do things like:

context.rotate(45);
context.fillRect(x,y,width,height);

Just be careful, because rotate always occurs around the origin, so you might need to use translate() as well to make it work the way you expect.

Hope this helps! :)