HTML画布射击游戏:在我点击的地方没有射击,移动播放器时没有链接

Posted

技术标签:

【中文标题】HTML画布射击游戏:在我点击的地方没有射击,移动播放器时没有链接【英文标题】:HTML canvas shooting game: not shooting where I click and not linked when moving the player 【发布时间】:2021-10-04 21:54:39 【问题描述】:

我正在创建一个画布游戏,并且正在研究游戏的射击方面。我创建了一个可以移动的播放器和一个射击功能,但我有两个问题:

    我想在画布上单击并将弹丸发送到单击位置。发生的情况是点击触发位置与画布断开连接,因此如果我点击页面左上角,我可以瞄准我拍摄的位置。

    我已启用播放器的移动,但我不确定如何关联播放器的移动并更新弹丸的原点。我已经为玩家和射弹设置了运动功能,但我不确定我哪里出错了。

任何帮助将不胜感激!

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();

【问题讨论】:

这能回答你的问题吗? Real mouse position in canvas 这真的很有帮助,感谢@Billy Brown! 【参考方案1】:

这是我在你的问题中理解的代码。

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)
);

变量说明

    player.rad是玩家的半径 这里player是Player类的对象 单击画布时会触发此函数 我在代码的第 8 行和第 9 行中添加的 15 值只是子弹的速度 new Projectile(x,y,cx,vy)是子弹,它取当前x,y位置为玩家位置,vx,vy解析出点击位置的x,y分量后来自玩家 projectileArray 只是一个包含用于渲染画布上所有子弹的子弹的数组

实际上这段代码是我为制作自己的射击游戏而创建的。如果您想了解它的工作原理,只需点击此链接即可播放。 Shooter Game

此链接仅供您了解其工作原理,而非宣传我的游戏。

【讨论】:

感谢分享您的代码 Ruthvik!我的代码的有趣替代方案,您的游戏看起来很酷!

以上是关于HTML画布射击游戏:在我点击的地方没有射击,移动播放器时没有链接的主要内容,如果未能解决你的问题,请参考以下文章

CS1.6进入后无法移动和射击,提示有错误!

在移动设备上没有触发第二次点击画布

HTML5+JavaScript-ES6移动端2D飞行射击游戏

HTML5+JavaScript-ES6移动端2D飞行射击游戏

HTML5 游戏、画布还是 div?

pygame应用---射击外星人游戏