javascript - 无法弄清楚在 Javascript 代码中在哪里绘制图像

标签 javascript jquery canvas

我在尝试将图像放置为“避开小行星”游戏的对象时遇到问题。我能够根据我的书“Foundation: HTML5 Canvas for Games and Entertainment”中所写的内容让游戏本身运行起来。我想比书上写的更进一步。我想用图像替换三 Angular 形的船。但是,我无法弄清楚将 this.draw 的代码放在哪里。我的教授向我们展示了一种方法。当我尝试将其实现到我的代码中时,它不想正常工作。我可以请教一些关于如何将图像放置为船的建议吗?

这是我在进行任何 this.draw 编辑之前从书中获取的工作代码:( http://jsbin.com/tukejopofo/1/ )

$(document).ready(function() {
  var canvas = $("#gameCanvas");
  var context = canvas.get(0).getContext("2d");

  //canvas dimensions
  var canvasWidth = canvas.width();
  var canvasHeight = canvas.height();
  var playGame;
  var asteroids;
  var numAsteroids;
  var player;
  var score;
  var scoreTimeout;
  var arrowUp = 38;
  var arrowRight = 39;
  var arrowDown = 40;
  var arrowLeft = 37;


  //game UI
  var ui = $("#gameUI");
  var uiIntro = $("#gameIntro");
  var uiStats = $("#gameStats");
  var uiComplete = $("#gameComplete");
  var uiPlay = $("#gamePlay");
  var uiReset = $(".gameReset");
  var uiScore = $(".gameScore");
  var soundBackground = $("#gameSoundBackground").get(0);
  var soundThrust = $("#gameSoundThrust").get(0);
  var soundDeath = $("#gameSoundDeath").get(0);

  var Asteroid = function(x, y, radius, vX) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.vX = vX;
  };

  var Player = function(x, y) {
    this.x = x;
    this.y = y;
    this.width = 24;
    this.height = 24;
    this.halfWidth = this.width / 2;
    this.halfHeight = this.height / 2;
    this.flameLength1 = 20;
    this.flameLength2 = 20;
    this.vX = 0;
    this.vY = 0;

    this.moveRight = false;
    this.moveUp = false;
    this.moveDown = false;
    this.moveLeft = false;

  };

  //Reset and start the game
  function startGame() {
    //Reset game stats
    uiScore.html("0");

    uiStats.show();

    //set up initial game settings
    playGame = false;

    asteroids = new Array();
    numAsteroids = 10;

    score = 0;

    player = new Player(150, canvasHeight / 2, 50, 50);


    for (var i = 0; i < numAsteroids; i++) {
      var radius = 5 + (Math.random() * 10);
      var x = canvasWidth + radius + Math.floor(Math.random() * canvasWidth);
      var y = Math.floor(Math.random() * canvasHeight);
      var vX = -5 - (Math.random() * 5);

      asteroids.push(new Asteroid(x, y, radius, vX));
    };

    $(window).keydown(function(e) {
      var keyCode = e.keyCode;
      if (!playGame) {
        playGame = true;
        soundBackground.currentTime = 0;
        soundBackground.play();
        animate();
        timer();
      };

      if (keyCode == arrowRight) {
        player.moveRight = true;
        if (soundThrust.paused) {
          soundThrust.currentTime = 0;
          soundThrust.play();
        }
      } else if (keyCode == arrowLeft) {
        player.moveLeft = true;
      } else if (keyCode == arrowUp) {
        player.moveUp = true;
      } else if (keyCode == arrowDown) {
        player.moveDown = true;
      }

    });

    $(window).keyup(function(e) {
      var keyCode = e.keyCode;
      if (!playGame) {
        playGame = true;
        animate();
      };

      if (keyCode == arrowRight) {
        player.moveRight = false;
        if (keyCode == arrowRight) {
          player.moveRight = false;
          soundThrust.pause();
        }


      } else if (keyCode == arrowUp) {
        player.moveUp = false;
      } else if (keyCode == arrowDown) {
        player.moveDown = false;
      } else if (keyCode == arrowLeft) {
        player.moveLeft = false;
      }
    });



    //start the animation loop
    animate();

  };

  //initialize the game environment
  function init() {
    uiStats.hide();
    uiComplete.hide();

    uiPlay.click(function(e) {
      e.preventDefault();
      uiIntro.hide();
      startGame();
    });

    uiReset.click(function(e) {
      e.preventDefault();
      uiComplete.hide();
      $(window).unbind("keyup");
      $(window).unbind("keydown");
      soundThrust.pause();
      soundBackground.pause();
      clearTimeout(scoreTimeout);
      startGame();
    });
  };

  function timer() {
    if (playGame) {
      scoreTimeout = setTimeout(function() {
        uiScore.html(++score);
        if (score % 5 == 0) {
          numAsteroids += 5;
        }
        timer();
      }, 1000);
    };
  };

  //Animation loop that does all the fun stuff
  function animate() {
    //Clear
    context.clearRect(0, 0, canvasWidth, canvasHeight);


    var asteroidsLength = asteroids.length;
    for (var i = 0; i < asteroidsLength; i++) {
      var tmpAsteroid = asteroids[i];

      tmpAsteroid.x += tmpAsteroid.vX;

      if (tmpAsteroid.x + tmpAsteroid.radius < 0) { //creates bounderies to prevent player from leaving the canvas
        tmpAsteroid.radius = 5 + (Math.random() * 10);
        tmpAsteroid.x = canvasWidth + tmpAsteroid.radius;
        tmpAsteroid.y = Math.floor(Math.random() * canvasHeight);
        tmpAsteroid.vX = -5 - (Math.random() * 5);
      }

      var dX = player.x - tmpAsteroid.x;
      var dY = player.y - tmpAsteroid.y;
      var distance = Math.sqrt((dX * dX) + (dY * dY));

      if (distance < player.halfWidth + tmpAsteroid.radius) { //checks for collision
        soundThrust.pause()

        soundDeath.currentTime = 0;
        soundDeath.play();
        //Game over
        playGame = false;
        clearTimeout(scoreTimeout);
        uiStats.hide();
        uiComplete.show();

        soundBackground.pause();

        $(window).unbind("keyup"); //unbinds keys to stop player movement at the end of the game
        $(window).unbind("keydown");
      };

      context.fillStyle = "rgb(255, 255, 255)";
      context.beginPath();
      context.arc(tmpAsteroid.x, tmpAsteroid.y, tmpAsteroid.radius, 0, Math.PI * 2, true);
      context.fill();
    };

    player.vX = 0;
    player.vY = 0;

    if (player.moveRight) {
      player.vX = 3;
    };

    if (player.moveLeft) {
      player.vX = -3;
    };

    if (player.moveUp) {
      player.vY = -3;
    };

    if (player.moveDown) {
      player.vY = 3;
    };

    player.x += player.vX;
    player.y += player.vY;

    if (player.x - player.halfWidth < 20) {
      player.x = 20 + player.halfWidth;
    } else if (player.x + player.halfWidth > canvasWidth - 20) {
      player.x = canvasWidth - 20 - player.halfWidth;
    }

    if (player.y - player.halfHeight < 20) {
      player.y = 20 + player.halfHeight;
    } else if (player.y + player.halfHeight > canvasHeight - 20) {
      player.y = canvasHeight - 20 - player.halfHeight;
    }


    if (player.moveRight) {
      context.save();
      context.translate(player.x - player.halfWidth, player.y);

      if (player.flameLength1 == 20) {
        player.flameLength1 = 15;
        (player.flameLength2 == 20)
        player.flameLength2 = 15;
      } else {
        player.flameLength1 = 20;
        player.flameLength2 = 20;
      };

      context.fillStyle = "orange";
      context.beginPath();
      context.moveTo(0, -12);
      context.lineTo(-player.flameLength1, -7);
      context.lineTo(0, -5);
      context.closePath();
      context.fill();

      context.fillStyle = "orange";
      context.beginPath();
      context.moveTo(0, 12);
      context.lineTo(-player.flameLength2, 7);
      context.lineTo(0, 5);
      context.closePath();
      context.fill();

      context.restore();

    };
    //draw ship
    context.fillStyle = "rgb(255, 0, 0)";
    context.beginPath();
    context.moveTo(player.x + player.halfWidth, player.y);
    context.lineTo(player.x - player.halfWidth, player.y - player.halfHeight);
    context.lineTo(player.x - player.halfWidth, player.y + player.halfHeight);
    context.closePath();
    context.fill();

    while (asteroids.length < numAsteroids) { //adds asteroids as the difficulty increases
      var radius = 5 + (Math.random() * 10)
      var x = Math.floor(Math.random() * canvasWidth) + canvasWidth + radius;
      var y = Math.floor(Math.random() * canvasHeight);
      var vX = -5 - (Math.random() * 5);

      asteroids.push(new Asteroid(x, y, radius, vX));
    }


    if (playGame) {
      //run the animation loop again in 33 milliseconds
      setTimeout(animate, 24);
    };
  };
  init();
});
* {
  margin: 0;
  padding: 0;
}
html,
body {
  height: 100%;
  width: 100%;
}
canvas {
  display: block;
}
body {
  background: #000;
  color: #fff;
  font-family: Verdana, Arial, sans-serif;
  font-size: 18px;
}
h1 {
  font-size: 30px;
}
h6 {
  font-size: 15px;
}
p {
  margin: 0 20px;
}
a {
  color: #fff;
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}
a.button {
  background: #185da8;
  border-radius: 5px;
  display: block;
  font-size: 30px;
  margin: 40px 0 0 350px;
  padding: 10px;
  width: 200px;
  text-align: center;
}
a.button:hover {
  background: #2488f5;
  color: #fff;
  text-decoration: none;
}
#game {
  height: 600px;
  left: 50%;
  margin: -250px 0 0 -500px;
  position: relative;
  top: 50%;
  width: 980px;
}
#gameCanvas {
  background: #001022;
  border: 5px solid green;
  background-image: url(../images/space.jpg);
  background-position: center top;
  background-repeat: no-repeat;
  background-size: cover;
}
#gameUI {
  height: 600px;
  position: absolute;
  width: 980px;
}
#gameIntro,
#gameComplete {
  background: rgba(0, 0, 0, 0.5);
  margin: 100px 0 0 10px;
  padding: 40px 0;
  text-align: center;
}
#gameStats {
  font-size: 14px;
  margin: 20px 0;
}
#gameStats .gameReset {
  margin: 20px 20px 0 0;
  position: absolute;
  right: 0;
  top: 0;
}
<body>
  <div id="game">
    <div id="gameUI">
      <div id="gameIntro">
        <h1>Debris Fields of Spiral Galaxy</h1>
        <h6>A <i>Galaxy Smuggler's Run</i> Game</h6>
        <hr>
        <p>You are Captain Amadaeus delivering goods to a dependent planet on the other side of a debris field</p>
        <p>Click <i>"Play"</i> and then press any key to start.</p>
        <p><a id="gamePlay" class="button" href="">Play!</a>
        </p>
      </div>
      <div id="gameStats">
        <p><b>Time: </b><span class="gameScore"></span> seconds</p>
        <p><a class="gameReset" href="">Reset</a>
        </p>
      </div>
      <div id="gameComplete">
        <h1>Game Over!</h1>
        <p>You survived for <span class="gameScore"></span> seconds.</p>
        <p>Would you like to give it another go?</p>

        <p><a class="gameReset button" href="">Play Again?</a>
        </p>
      </div>
    </div>
    <canvas id="gameCanvas" width="980" height="600">

    </canvas>
    <audio id="gameSoundBackground" loop>
      <source src="sounds/background.ogg">
        <source src="sounds/background.mp3">
    </audio>
    <audio id="gameSoundThrust" loop>
      <source src="sounds/thrust.ogg">
        <source src="sounds/thrust.mp3">
    </audio>
    <audio id="gameSoundDeath">
      <source src="sounds/death.ogg">
        <source src="sounds/death.mp3">
    </audio>
  </div>
</body>

这是我教授绘制图像的代码:( http://jsbin.com/rapayufafe/1/ )

// JS file for the ship

function Ship() {
	this.x = 100;
	this.y = 100;
	this.color = "yellow";
	this.fillStyle = "white";

	this.vx = 0;
	this.vy = 0;

	this.ax = 1;
	this.ay = 1;
//function "move" that will add velocity to the position of the ship
	this.move = function() {
		this.x += this.vx;
		this.y += this.vy;
		
	}//end move function
	
	//draw the ship
	this.draw=function () {
		//ship var
		var imageObj = new Image();
		imageObj.src = "images/ship.png";
	
	//save the current state of the canvas
	context.save();
	//moving the point of origin (0,0) to the ships x and y coordinates
	context.translate(this.x,this.y);
	
	context.lineStyle = this.color;
	context.fillStyle = this.fillStyle;
	
	/*context.beginPath();
	context.moveTo(25,0);
	context.lineTo(-25,25)
	context.lineTo(-25,-25)*/
	
	//draw ship
	context.drawImage(imageObj,-25,-25,50,50);
	
	context.closePath();
	context.stroke();
	context.fill();
	context.restore();
		
	}//end of draw ship
}//end ship function

/*var asteroidsLength = asteroids.length;
for (var i = 0; i < asteroidsLength; i++) {

	var tmpAsteroid = asteroids[i];

	context.fillStyle = "gray";
	context.beginPath();
	context.arc(tmpAsteroid.x, tmpAsteroid.y, tmpAsteroid.radius, 0, Math.PI*2, true);
	context.closePath();
	context.fill();
};*/

最佳答案

正如您在起始代码中所看到的,您有一个如下所示的部分:

   //draw ship
    context.fillStyle = "rgb(255, 0, 0)";
    context.beginPath();
    context.moveTo(player.x + player.halfWidth, player.y);
    context.lineTo(player.x - player.halfWidth, player.y - player.halfHeight);
    context.lineTo(player.x - player.halfWidth, player.y + player.halfHeight);
    context.closePath();
    context.fill();

只需将该代码替换为绘制图像的代码即可。

var imageObj = new Image();
imageObj.src = "images/ship.png";
context.drawImage(imageObj,player.x,player.y);

不过,我建议声明 imageObj 并在代码顶部设置源代码,在其中声明其余变量,这样您就不会在每次要绘制船舶时都加载图像。

关于javascript - 无法弄清楚在 Javascript 代码中在哪里绘制图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30519503/

相关文章:

javascript - 如何防止在选择元素上选择和复制

jquery - 如何删除嵌套 div 中存在的元素

javascript - 计算结果向量弹跳圆/球

security - 安全 Canvas - Canvas 页面上的每个 http 请求是否也应更改为 https?

javascript - 将 Canvas 元素放在前面?

javascript - 链接在通知下拉菜单中的 div 之外不起作用?

javascript - 如何滚动到带有溢出的 div 的底部或顶部

javascript - 禁止同时在多个浏览器/选项卡中登录网站

javascript - Jquery 效果Onunload

jQuery HTML 转换