0

I'm creating a canvas game and I'm working on the shooting aspect of the game. I've created a player that can move and a shooting function but I have two issues:

  1. I would like to click in the canvas and have a projectile send to the click location. What is happening is that the click trigger location is disconnected from the canvas so that if I click around the top left of the page I can aim where I shoot.

  2. I have have enabled movement with the player but I'm not sure how to link the movement of the player and update the origin of the projectile. I have set up movement functions for both player and projectile but I'm not sure where I'm going wrong.

Any help would be greatly appreciated!

https://codepen.io/blacksunmachine/pen/mdmxLxg

const canvas = document.querySelector("canvas");
const context = canvas.getContext("2d");

canvas.width = innerWidth / 2; // this takes up the whole page horizontally
canvas.height = innerHeight / 2; // this takes up the whole page verticallly

class Player {
  constructor(x, y, radius, color) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.color = color;
  }
  draw() {
    context.beginPath();
    context.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
    context.fillStyle = this.color;
    context.fill();
  }
  moveLeft() {
    this.x -= 30;
    if (this.x <= 0) {
      this.x = 0;
    }
  }
  moveRight() {
    this.x += 30;
    if (this.x >= canvas.width) {
      this.x = canvas.width;
    }
  }
  moveUp() {
    this.y -= 30;
    if (this.y <= 0) {
      this.y = 0;
    }
  }
  moveDown() {
    this.y += 30;
    if (this.y >= canvas.height) {
      this.y = canvas.height;
    }
  }
}
// player position
let newPlayer1 = new Player(canvas.width / 2, canvas.height / 2, 10, "blue");

class Projectile {
  constructor(x, y, radius, color, velocity) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.color = color;
    this.velocity = velocity;
  }
  draw() {
    context.beginPath();
    context.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
    context.fillStyle = this.color;
    context.fill();
  }
  update() {
    this.draw();
    this.x = this.x + this.velocity.x;
    this.y = this.y + this.velocity.y;
  }
  moveLeft() {
    this.x -= 30;
    if (this.x <= 0) {
      this.x = 0;
    }
  }
  moveRight() {
    this.x += 30;
    if (this.x >= canvas.width) {
      this.x = canvas.width;
    }
  }
  moveUp() {
    this.y -= 30;
    if (this.y <= 0) {
      this.y = 0;
    }
  }
  moveDown() {
    this.y += 30;
    if (this.y >= canvas.height) {
      this.y = canvas.height;
    }
  }
}

function animate() {
  requestAnimationFrame(animate);
  context.clearRect(0, 0, canvas.width, canvas.height);
  newPlayer1.draw();

  projectiles.forEach((projectile) => {
    projectile.update();
  });
}

const projectile = new Projectile(
  canvas.width / 2,
  canvas.height / 2,
  10,
  "red",
  {
    x: -1,
    y: -1,
  }
);

const projectiles = [];


// need to link shooting with movement of the character

addEventListener("click", (event) => {
    console.log(event)
    const angle = Math.atan2(
    event.clientY - canvas.height / 2,
    event.clientX - canvas.width / 2
  ); // detemine direction of click
  console.log(angle); // show where is being clicked
  const velocity = {
    // speed and direction of click
    x: Math.cos(angle) * 20,
    y: Math.sin(angle) * 20,
  };
  // from original position (in the middle of the screen) move a projectile with velocity
  projectiles.push(
    new Projectile(canvas.width / 2, canvas.height / 2, 10, "red", velocity)
  );
});

// difference in X and Y when moving the character - not using this at the moment
// let deltaX = 0;
// let deltaY = 0;

// movement keys for player 1
window.addEventListener("keydown", handleKeyDown);
function handleKeyDown(event) {
  switch (
    event.keyCode // position of letters might change when on different layouts - same in every language
  ) {
    case 37: // left
      newPlayer1.moveLeft();
         projectile.moveLeft()
      break;

    case 38: // up
      newPlayer1.moveUp();
      projectile.moveUp()
      break;

    case 39: // right
      newPlayer1.moveRight();
        projectile.moveRight()
      break;

    case 40: // down
      newPlayer1.moveDown();
      projectile.moveDown()
      break;

    default:
      console.log("you cannot move player 1 like that");
  }
  console.log(event);
}

animate();
CSK
  • 21
  • 2

1 Answers1

0

Here is the code of what i understood in your question.

canvas.addEventListener('click',(e)=>{
    try{
        let x=e.clientX;
        let y=e.clientY;
        let angle=Math.atan2(y-player.y-(player.rad/2),x-player.x-(player.rad/2));
        x=player.x+(player.rad/2);
        y=player.y+(player.rad/2);
        let vx=Math.cos(angle)*15;
        let vy=Math.sin(angle)*15;
        projectileArray.push(new Projectile(x,y,vx,vy));
    }catch(e){}
});

Variables explaination

  1. player.rad is the radius of player
  2. Here player is the object of the Player class
  3. This function fires when you click on the canvas
  4. The 15 value which i added in the line 8 and 9 of my code is just the velocity of the bullet
  5. new Projectile(x,y,cx,vy) is the bullet which takes the current x, y position which is the players position and vx, vy after resolving the components of x and y of the click position from the player
  6. projectileArray is just an array containing the bullets fired for rendering all of the bullets on the canvas

Actually this code is what i created for making my own shooting game. If you want to see how it works just click on this link to play it. Shooter Game

This link is provided strictly for you to understand how it works and not for publicising my game.

  • 1
    Thanks for sharing your code Ruthvik! interesting alternative to my code and your game looks cool! – CSK Aug 03 '21 at 19:23