2D платформа шутер Canvas игра | Создание функции съемки - PullRequest
0 голосов
/ 09 ноября 2018

Так что я делаю эту довольно простую игру, я бы сказал, для школьного проекта. У меня есть все основные контроллеры, работающие, прыгающие, перемещающиеся влево и вправо, но я изо всех сил пытаюсь найти способ сделать персонажа способным стрелять. Я также хотел бы сделать так, чтобы это было как перерыв между каждым выстрелом, как действие болта. Участие в столкновении не должно быть проблемой, поэтому там не требуется помощь.

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

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

Ну, вы могли бы создать функцию shoot(e), которая будет вызываться, когда пользователь нажимает, например, клавишу (keydown), а затем создает новый массив, скажем, 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.
  }
}

Надеюсь, это несколько ясно, я сам работаю над игрой типа космического шутера, почти закончил, поэтому поделился здесь некоторым из моего кода :) Не подразумевая, что он лучший, но он работает:)

0 голосов
/ 09 ноября 2018

Первое, что вы должны рассмотреть, является ли пуля сканирующим ударом или снарядом. Сканирование попадания означает, что при попадании пули пуля мгновенно поражает цель. Это можно сделать, используя приведение лучей, чтобы проверить, попадает ли он в объект. Пули на основе снаряда - когда пользователь указывает направление, пуля фактически «движется». Это может быть реализовано путем добавления массива «пуль» к игроку. Поэтому, когда игрок нажимает, к объекту маркера добавляется массив. Этот объект маркера будет нарисован сам по себе в цикле рисования и будет перемещаться от пользователя в направлении, на которое он указывает.

Добавить задержку просто, вы можете иметь переменную "перезарядки", которая является счетчиком, который длится в течение n миллисекунд. Когда пользователь срабатывает, счетчик устанавливается на n и начинает обратный отсчет до 0. Когда он достигает 0, вы можете запустить снова.

...