如何从香草Javascript中的玩家中绘制子弹?

问题描述 投票:1回答:2

我正在努力制作一个向上滚动式的街机射击游戏。我已经陷入了如何从玩家向上吸引子弹到敌人的位置。我正在使用setInterval在玩家的位置重复射击动作,但是每当玩家移动指定的数量时,子弹只会跟随战斗机围绕重置间隔。

有帮助吗?

这是我目前的代码。

先感谢您。

var project, ctx, img, img2, width, height, mid, midh, startPx, startPy, audio,interval,bulletStartPx,bulletStartPy;
var score = 0;

function setUp() {
 project = document.getElementById("project");
 ctx = project.getContext("2d");
 width = 505;
 height = 900;
 mid = width/2;
 midh = height/2;
 startPx = width/2-30;
 startPy = height-150;

 audio = new Audio("bgm.mp3");
 audio.play();

 img = new Image();
 img2 = new Image();
 img.src = "bg.png";
 img2.src = "fighterjet.png"
 img.onload = function(){
   ctx.shadowColor = "#ffffff";
   ctx.shadowBlur = 15;
   ctx.drawImage(img, 0, 0);
   ctx.drawImage(img2, startPx, startPy)
 }
 
 window.addEventListener("keydown", checkKeyPress);
}

function drawObject(x, y) {
  ctx.drawImage(img2, startPx, startPy)
}

function checkKeyPress(event) {
  if (event.keyCode == "87") {//W(UP)
    ctx.clearRect(0,0,width,height);
    if (startPy >= 20) {
    startPy -= 20;
    }
    ctx.drawImage(img, 0, 0);
    ctx.drawImage(img2, startPx, startPy)
  } else if (event.keyCode == "83") {//S(DOWN)
    ctx.clearRect(0,0,width,height);
    if (startPy <= 785) {
    startPy += 20;
    }
    ctx.drawImage(img, 0, 0);
    ctx.drawImage(img2, startPx, startPy)
  } else if (event.keyCode == "65") {//A(LEFT)
    ctx.clearRect(0,0,width,height);
    if (startPx >= 0) {
    startPx -= 20;
    }
    ctx.drawImage(img, 0, 0);
    ctx.drawImage(img2, startPx, startPy)
  } else if (event.keyCode == "68") {//D(RIGHT)
    ctx.clearRect(0,0,width,height);
    if (startPx <= 410) {
    startPx += 20;
    }
    ctx.drawImage(img, 0, 0);
    ctx.drawImage(img2, startPx, startPy)
  } else if (event.keyCode == "72") {
    for (let i = 0; i < 6; i++) {
      bullets();
  }
}
}

function bullets() {
  return setInterval(function(){
          bulletStartPx = startPx+48;
          bulletStartPy = startPy-30;
          ctx.fillStyle = "gold"
          ctx.beginPath();
          ctx.arc(bulletStartPx,bulletStartPy,5,0,2*Math.PI);
          ctx.fill();
          score += 25; }, 100);
}

function GameOver(){
  document.getElementById('bm').pause();
  ctx.font = '30px Courier New'
  ctx.filltext('GAME OVER', mid, midh)
  ctx.filltext('Your score was: '+score, mid, midh+40)
}

function showScore(){
  ctx.fillStyle = '#ff0000'
  ctx.font = '18px Courier New'
  ctx.text(score, width-10, 15)
}






/*
function bullet(){
  this.x = startPx;
	this.y = startPy - 10;

  this.draw = function() {
    ctx.fillStyle = "#b20808";
    ctx.shadowColor = "#b20808";
    ctx.shadowBlur = 15;
    this.y -= bulletSpeed;
    ctx.fillRect(this.x, this.y, 2, 8);
  }
}

function fireGun(){
if (event.keyCode == "32") {
   bullet();
   }
}*/
<!DOCTYPE html>
<html>
  <head>
    <title>Project</title>
    <meta charset="utf-8">
    <script src="project.js" type="text/javascript" defer></script>
  </head>
  <body>
    <h1>Arcade Shooter</h1>
    <fieldset>
    <legend><h2>Instructions:</h2></legend>
    <h3>Press W, A, S, D to Move</h3>
    <h3>Press Space Bar to Fire</h3>
    <h3>Goal: Survive as long as you can!</h3>
    </fieldset>
    <br>
    <canvas id="project" style="border-style: solid" width=505 height=900 ></canvas>
    <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
      <input id="start" type="button" value="START THE GAME" onclick="setUp()" style="width: 300px">
  </body>
</html>
javascript html html5 function html5-canvas
2个回答
0
投票

每次发射子弹时都不想使用setInterval。您希望对每个游戏对象调用更新或绘制函数的整个游戏使用一个setInterval。例如

var game={
  //this is a list of items in the game I want to move around or do stuff
  //nothing there yet
  objects:[]
}
//this is a bullet object which can be created calling new bullet()
function Bullet(){
   //IM CHEATING HERE. DON'T DRAW TO THE DOM FOR GAMES
   //this is just a shortcut instead of drawing on a canvas
  this.object=document.createElement('div');
  this.object.style.width="10px";
  this.object.style.height="10px";
  this.object.style.position='absolute';
  this.object.style.top="100px";
  this.object.style.backgroundColor='red';
  document.body.appendChild(this.object)
  ///
  //these hold the bullet's current location on screen
  this.x=100;
  this.y=100;

  //this is the update function that gets called every frame
  this.update=function(){
     //I'm updating the bullet's y position.
    this.y-=10;
    if(this.y>0){
     
      //don't draw to the dom like this. use canvas like you were doing.
      this.object.style.top=this.y+"px";
    }
  }
}

//now let's add a bullet to the game
game.objects.push(new bullet());

//the function that updates each of our objects
function runGame(){
  for(var i=0;i<game.objects.length;i++){
      game.objects[i].update();
  }
}
//start the game
setInterval(runGame, 1000)

注意:不要像这样在DOM上绘制。像你一样使用画布。我只是把dom作为演示的捷径


0
投票

1)你需要重新定义全局变量,你将跟踪所有内容:

var gameData = {
    interval: null, // Controls the refresh
    redrawRequired: false, // Flag
    allBullets: [], // Moving bullets
    defaultBulletSpeed: 20 // Bullet speed
}

2)仅检查checkKeyPress(事件)函数中的操作,包括fireGun操作:

function checkKeyPress(event) {
    if (event.keyCode == "87") {//87 W(UP)
        if (startPy >= 20) {
            startPy -= 20;
            gameData.redrawRequired = true;
        }
    } else if (event.keyCode == "83") {//83 S(DOWN)
        if (startPy <= 785) {
            startPy += 20;
            gameData.redrawRequired = true;
        }
    } else if (event.keyCode == "65") {//65 A(LEFT)
        if (startPx >= 0) {
            startPx -= 20;
            gameData.redrawRequired = true;
        }
    } else if (event.keyCode == "68") {//68 D(RIGHT)
        if (startPx <= 410) {
            startPx += 20;
            gameData.redrawRequired = true;
        }
    } else if (event.keyCode == "72") { // 72 SPACEBAR ?? Actually H
        fireGun();
    }
}

3)以下是定义项目符号对象和firegun()函数的方法:

function Bullet() {
    // Object defining a bullet.
    this.x = startPx;
    this.y = startPy - 10;
    this.bulletSpeed = gameData.defaultBulletSpeed;
}

Bullet.prototype.draw = function () {
    // Draws the bullet on canvas...
    ctx.fillStyle = "#b20808";
    ctx.shadowColor = "#b20808";
    ctx.shadowBlur = 15;
    ctx.fillRect(this.x, this.y, 2, 8);
}

Bullet.prototype.move = function () {
    // Moves the bullet...
    this.y = this.y - this.bulletSpeed;
}


function fireGun() {
    var newBullet = new Bullet();
    gameData.allBullets.push(newBullet);
}

4)然后你决定何时重绘画布,使用一个主函数(refreshGame)和另一个函数来检查是否有要更新的项目符号(refreshBullets):

function refreshBullets() {
    var i = 0;
    var currentBullet;
    // Start by eliminating bullets out of the screen...
    while (i < gameData.allBullets.length) {
        currentBullet = gameData.allBullets[i];
        if (currentBullet.y < -10) {
            gameData.allBullets.splice(i, 1); // Remove the bullet outside of the screen.
        } else {
            currentBullet.move();
            gameData.redrawRequired = true;
            i += 1; // Next bullet...
        }
    }
}


function refreshGame() {
    refreshBullets();
    if (gameData.redrawRequired) {
        ctx.clearRect(0,0,width,height);
        ctx.drawImage(img, 0, 0, width, height);
        ctx.drawImage(img2, startPx, startPy);

        for (var i = 0; i < gameData.allBullets.length; i++) {
            gameData.allBullets[i].draw();
        }
    }
    gameData.redrawRequired = false;
}

5)最后你初始化整个,包括setUp()函数中的setInterval:

function setUp() {
    project = document.getElementById("project");
    ctx = project.getContext("2d");
    width = 505;
    height = 900;
    mid = width / 2;
    midh = height / 2;
    startPx = width / 2 - 30;
    startPy = height - 150;

    audio = new Audio("bgm.mp3");
    audio.play();

    img = new Image();
    img2 = new Image();
    img.src = "bg.png";
    img2.src = "fighterjet.png"
    img.onload = function() {
        ctx.shadowColor = "#ffffff";
        ctx.shadowBlur = 15;
        ctx.drawImage(img, 0, 0, width, height);
        ctx.drawImage(img2, startPx, startPy);
    }

    window.addEventListener("keydown", checkKeyPress);

    // Here ! And do something about that start button or the game will start over again...
    gameData.interval = window.setInterval(refreshGame, 100);
    document.getElementById("start").style.display = "none";
    project.focus();
}

备注:

  • 由于性能问题,使用setInterval的canvas方法被认为是一种糟糕的方法。尝试搜索“用画布刷新javascript间隔”,还有其他方法可以解决这个问题。 refreshRequired变量/属性只是一个占位符来解释变通方法。实际上,你必须不断重绘场景,因为背景,目标和威胁将在喷气机下方移动,你将在此过程中更新分数。
  • 在编写代码之前,你应该设计游戏,目标是什么,角色,控件,限制,级别.......纸和笔是一个好的开始。问题是,当你开始编写代码之前,当你问自己时,你会陷入困境,我如何让子弹与目标发生碰撞?如果我可以使用导弹呢?最后,您的代码将变得繁重且处理器密集,因为您尝试在创建另一个时解决问题...只是一个建议;)
© www.soinside.com 2019 - 2024. All rights reserved.