簡體   English   中英

2D Platform Shooter Canvas游戲| 創建拍攝功能

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

因此,我正在針對學校項目開發這款非常基本的游戲。 我讓所有基本控制器都在工作,跳躍,左右導航,但我一直在努力尋找使角色能夠射擊的方法。 我也想做到這一點,就像每次拍攝之間的休息一樣,就像一個螺栓動作。 碰撞部分應該沒有問題,因此無需任何幫助。

(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:

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

您首先要考慮的是子彈是命中掃描還是彈丸。 命中掃描意味着當子彈發射時,子彈立即擊中目標。 這可以通過使用射線投射檢查是否撞擊到對象來完成。 基於彈丸的子彈是指用戶指向某個方向時,子彈實際上會“移動”。 這可以通過向播放器添加“子彈”數組來實現。 因此,當玩家單擊時,將在項目列表中添加項目符號對象。 該項目符號對象將在繪制循環中自行繪制,並將從用戶移動到其指向的方向。

添加延遲很簡單,您可以擁有一個“ cooldown”變量,該變量是一個持續n毫秒的計數器。 當用戶觸發時,計數器設置為n並開始遞減計數到0。當用戶觸發時,計數器便可以再次觸發。

好吧,您可以創建一個shoot(e)函數, shoot(e) ,當用戶按下(按鍵)空間然后創建一個新數組時會調用它,比如ammo[] 然后,在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
        });
      }
}

然后,我假設您在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.
  }
}

希望它有點清晰,我正在自己開發一款太空射擊游戲,快要完成了,所以在這里分享了我的一些代碼:)並不意味着它是最好的,但是它確實可以工作:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM