简体   繁体   English

2D Platform Shooter Canvas游戏| 创建拍摄功能

[英]2D Platform shooter Canvas game | Creating the shooting function

So I'm making this pretty basic game I would say for a school project. 因此,我正在针对学校项目开发这款非常基本的游戏。 I have all the basic controllers working, jumping, navigating left and right, but I'm struggling to find a way to make the character be able to shoot. 我让所有基本控制器都在工作,跳跃,左右导航,但我一直在努力寻找使角色能够射击的方法。 I would also like to make it so it's like a break between each shoot, like a bolt action. 我也想做到这一点,就像每次拍摄之间的休息一样,就像一个螺栓动作。 The collision part shouldn't be a problem, so no need for help there. 碰撞部分应该没有问题,因此无需任何帮助。

(function() {
 var requestAnimationFrame =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
})();

var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
width = 640,
height = 480,
player = {
x: width / 2,
y: height - 140,
width: 35,
height: 90,
speed: 3,
velX: 0,
velY: 0,
jumping: false,
grounded: false
},
keys = [],
friction = 0.8,
gravity = 0.3;

var hovedkarakterBilde = new Image();
    hovedkarakterBilde.src = "mc1.png";

var boxes = [];

// dimensions
boxes.push({
// venstre vegg
x: 0,
y: 0,
width: 10,
height: height
 });
boxes.push({
// gulv
x: 0,
y: height - 68,
 width: width,
height: 1
});

boxes.push({
x: 120,
y: 250,
width: 80,
height: 80
});
boxes.push({
 x: 170,
 y: 275,
 width: 80,
 height: 80
 });
 boxes.push({
 x: 220,
 y: 325,
 width: 80,
 height: 80
  });
boxes.push({
 x: 270,
 y: 225,
 width: 40,
 height: 40
 });

canvas.width = width;
canvas.height = height;

 function update() {
 // check keys
 if (keys[38]) {
   // up arrow or space
  if (!player.jumping && player.grounded) {
  player.jumping = true;
  player.grounded = false;
  player.velY = -player.speed * 2;
   }
  }
  if (keys[39]) {
  // right arrow
  if (player.velX < player.speed) {
  player.velX++;
   }
  }
 if (keys[37]) {
 // left arrow
 if (player.velX > -player.speed) {
  player.velX--;
  }
 }

  player.velX *= friction;
  player.velY += gravity;

  ctx.clearRect(0, 0, width, height);
  ctx.fillStyle = "black";
  ctx.beginPath();

  player.grounded = false;
  for (var i = 0; i < boxes.length; i++) {
  ctx.rect(boxes[i].x, boxes[i].y, boxes[i].width, boxes[i].height);

  var dir = colCheck(player, boxes[i]);

  if (dir === "l" || dir === "r") {
    player.velX = 0;
    player.jumping = false;
  } else if (dir === "b") {
    player.grounded = true;
    player.jumping = false;
 } else if (dir === "t") {
    player.velY *= -1;
 }
 }

 if (player.grounded) {
player.velY = 0;
}

player.x += player.velX;
player.y += player.velY;

ctx.fill();
ctx.drawImage(
hovedkarakterBilde,
player.x,
player.y,
player.width,
player.height
 );

requestAnimationFrame(update);
}



function colCheck(shapeA, shapeB) {
// get the vectors to check against
 var vX = shapeA.x + shapeA.width / 2 - (shapeB.x + shapeB.width / 2),
  vY = shapeA.y + shapeA.height / 2 - (shapeB.y + shapeB.height / 2),
  // add the half widths and half heights of the objects
  hWidths = shapeA.width / 2 + shapeB.width / 2,
  hHeights = shapeA.height / 2 + shapeB.height / 2,
  colDir = null;

 // if the x and y vector are less than the half width or half height, they 
 we must be inside the object, causing a collision
  if (Math.abs(vX) < hWidths && Math.abs(vY) < hHeights) {
 // figures out on which side we are colliding (top, bottom, left, or right)
   var oX = hWidths - Math.abs(vX),
    oY = hHeights - Math.abs(vY);
    if (oX >= oY) {
    if (vY > 0) {
      colDir = "t";
      shapeA.y += oY;
    } else {
      colDir = "b";
      shapeA.y -= oY;
     }
   } else {
     if (vX > 0) {
      colDir = "l";
      shapeA.x += oX;
    } else {
      colDir = "r";
      shapeA.x -= oX;
     }
  }
}
  return colDir;
}

document.body.addEventListener("keydown", function(e) {
keys[e.keyCode] = true;
});

document.body.addEventListener("keyup", function(e) {
 keys[e.keyCode] = false;
 });

window.addEventListener("load", function() {
update();
});    

HTML: HTML:

</head>
<body>
<canvas id="canvas" style="background: url('bakgrunn1.png')"></canvas>
 </body>
 <script src="spillv2.js"></script>

First thing you have to consider is if the bullet is hit-scan or projectile. 您首先要考虑的是子弹是命中扫描还是弹丸。 Hit-scan means when the bullet is shot, the bullet instantly hits the target. 命中扫描意味着当子弹发射时,子弹立即击中目标。 This can be done by using a ray-cast to check if it hits an object. 这可以通过使用射线投射检查是否撞击到对象来完成。 Projectile based bullets are when the user points in a direction, the bullet actually "moves". 基于弹丸的子弹是指用户指向某个方向时,子弹实际上会“移动”。 This can be implemented by adding an array of "bullets" to the player. 这可以通过向播放器添加“子弹”数组来实现。 So when the player clicks, a bullet object is added the array. 因此,当玩家单击时,将在项目列表中添加项目符号对象。 This bullet object will be drawn on it's own in the draw loop and will move from the user to the direction it's pointed at. 该项目符号对象将在绘制循环中自行绘制,并将从用户移动到其指向的方向。

Adding a delay is simple, you can have a "cooldown" variable that is a counter that lasts for n milliseconds. 添加延迟很简单,您可以拥有一个“ cooldown”变量,该变量是一个持续n毫秒的计数器。 When the user fires, the counter is set to n and starts to count down to 0. When it reaches 0, you are able to fire again. 当用户触发时,计数器设置为n并开始递减计数到0。当用户触发时,计数器便可以再次触发。

Well, you could make a shoot(e) function, which will be called when user presses (keydown) space for example and then make a new array, lets say ammo[] . 好吧,您可以创建一个shoot(e)函数, shoot(e) ,当用户按下(按键)空间然后创建一个新数组时会调用它,比如ammo[] Then, inside shoot() you will do something like: 然后,在shoot()您将执行以下操作:

const ammo = [];
let shooting = false;
function shoot(e) {
      e = e || event;
      const key = e.keyCode;
      if(shooting) return; // This will prevent from shooting more bullets while holding space
      // So you'd need to press space for each time you want to shoot.
      if(key == 32) { // Key code 32 is SPACE
         shooting = true;
         // You get the coordinates from your player, from which the bullet will shoot
         ammo.push({
         x: player.x,
         y: player.y + (player.height / 2) 

        // Player.height / 2 is basically setting the ammo at the middle of the character
        });
      }
}

And then, I presume you do all the updates in the update() function (yea, logically :D), you'll do something like: 然后,我假设您在update()函数中进行了所有更新(是的,从逻辑上说:D),您将执行以下操作:

function update() {
  // Insert it somewhere
  for(let i = 0; i < ammo.length; i++) {
    // The "theBullet" part refers to either your image for the bullet
    ctx.drawImage(theBullet, ammo[i].x, ammo[i].y;
    ammo[i].x++ // Or however fast you'd like it to go.
  }
}

Hope its somewhat clear, I am working myself on a spaceshooter type of game, almost finished, so shared some of my code here :) Not implying that its the best, but it does the work :) 希望它有点清晰,我正在自己开发一款太空射击游戏,快要完成了,所以在这里分享了我的一些代码:)并不意味着它是最好的,但是它确实可以工作:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM