“船只”不会移动“小行星避免”游戏

时间:2015-05-26 02:43:39

标签: javascript jquery canvas

如果我说的话几乎没有任何意义,我提前道歉,我仍然是Javascript编码的新手。

我正在尝试创建一个“小行星避免”游戏,使用从“基础:HTML5 Canvas for Games and Environment”第9章中获取的Javascript代码。我的问题是我不能让“玩家的船”移动。它似乎锁定在屏幕的左上角。即使我有关键代码的变量以及如何为“keyup”和“keydown”做些什么,我也无法弄清楚如何让船只移动。

我没有得到任何语法错误,所以我猜我的代码在错误的地方,我只是不确定在哪里。如果我可以问,我可以多看一双眼睛,看看我哪里出错了吗?

这是jsbin(http://jsbin.com/dunaxakifu/

$(document).ready(function(){
	var canvas = $("#gameCanvas");
	var context = canvas.get(0).getContext("2d");
	
	//Canvas Dimension
	var canvasWidth = canvas.width();
	var canvasHeight = canvas.height();
	
	//Game Settings
	var playGame;
	
	var asteroids;
	var numAsteroids;
	
	var player;
	
	//Scoring
	var score;
	var scoreTimeout;
	
	//Key codes
	var arrowUp = 38;
	var arrowRight = 39;
	var arrowDown = 40;
	
	//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.vX = 0;
		this.vY = 0;
	
		this.moveRight = false;
		this.moveUp = false;
		this.moveDown = false;
		
		this.flameLength = 20;
	};
	
	
	//Reset and start the game
	function startGame() {
		//Reset game stats
		uiScore.html("0");
		uiStats.show();
		
		asteroids = new Array();
		numAsteroids = 10;
		


		score = 0;
		
		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));
		};
		
		player = new Player(150, canvasHeight/2);
		
		//Set up initial game settings
		playGame = false;
		
		//Keyboard events
		$(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;
			} else if (keyCode == arrowUp){
				player.moveUp = true;
			} else if (keyCode == arrowDown){
				player.moveDown = true;
			};
			
			if (soundThrust.paused){
				soundThrust.currentTime = 0;
				soundThrust.play();
			};
		});
		$(window).keyup(function(e){
			var keyCode = e.keyCode;
			
			if (keyCode == arrowRight){
				player.moveRight = false;
			} else if (keyCode == arrowUp){
				player.moveUp = false;
			} else if (keyCode == arrowDown){
				player.moveDown = false;
			};
			
			soundThrust.pause();
			
		});
		
		//Start the animation loop
		animate();
	};
	
	//Initialize the game environment
	function init() {
		uiStats.hide();
		uiComplete.hide();
		
		uiPlay.click(function(e){
			e.preventDefault();
			uiIntro.hide();
			startGame();
		});

		$(window).unbind("keyup");
		$(window).unbind("keydown");
		
		uiReset.click(function(e){
			e.preventDefault();
			uiComplete.hide();
			startGame();
			soundThrust.pause();
			soundBackground.pause();
			clearTimeout(scoreTimeout);
		});
	};
	
	//Timer
	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];
			
			var dX = player.x - tmpAsteroid.x;
			var dY = player.y - tmpAsteroid.y;
			var distance = Math.sqrt((dX*dY)+(dY*dY));
	
			if (distance < player.halfWidth+tmpAsteroid.radius){
				soundThrust.pause();
		
				soundDeath.currentTime = 0;
				soundDeath.play();
		
				//Game over
				playGame = false;
				clearTimeout(scoreTimeout);
				uiStats.hide();
				uiComplete.show();
		
				soundBackground.pause();
		
				$(window).unbind("keyup");
				$(window).unbind("keydown");
			};
			
			if(tmpAsteroid.x+tmpAsteroid.radius < 0){
				tmpAsteroid.radius = 5+(Math.random()*10);
				tmpAsteroid.x = canvasWidth+tmpAsteroid.radius;
				tmpAsteroid.y = Math.floor(Math.random()*canvasHeight);
				tmpAsteroid.vX = -5-(Math.random()*5);
			};
			
			tmpAsteroid.x += tmpAsteroid.vX;
			
			context.fillStyle = "rgb(255, 255, 255)";
			context.beginPath();
			context.arc(tmpAsteroid.x, tmpAsteroid.y, tmpAsteroid.radius, 0, Math.PI*2, true);
			context.closePath();
			context.fill();
			
			player.vX = 0;
			player.vY = 0;
			if (player.moveRight){
				player.vX = 3;
			} else {
				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.moveRight){
				context.save();
				context.translate(player.x-player.halfWidth, player.y);
				
				if (player.flameLength == 20) {
					player.flameLength = 15;
				} else {
					player.flameLength = 20;
				};
			};
			
			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;
			};
			
			context.fillStyle = "orange";
			context.beginPath();
			context.moveTo(0, -5);
			context.lineTo(-player.flameLength, 0);
			context.lineTo(0, 5);
			context.closePath();
			context.fill();
			
			context.restore();
			
			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){
				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, 33);
		};
	};
	
	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 270px;
	padding:10px;
	width:200px;
	text-align:center;
}
a.button:hover{
	background:#2488f5;
	color:#fff;
	text-decoration:none;
}
#game{
	height:600px;
	left:50%;
	margin:-300px 0 0 -400px;
	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-top: 100px;
	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;
}
<!Doctype HTML>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<title>Debris Fields of Spiral Galaxy</title>
<meta charset="utf-8">
<link href="css/game.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="js/jquery-2-1-4min.js"></script>
<script type="text/javascript" src="js/game.js"></script>
</head>
<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>
				<p>Click "Play" and then press any key to start.</p>
				<p><a id="gamePlay" class="button" href="">Play!</a></p>
			</div>
			<div id="gameStats">
				<p>Time: <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><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>
</html>

2 个答案:

答案 0 :(得分:1)

那里有很多代码,尝试直接在Player对象上调用移动函数

Player.prototype.moveUp = function() {
    this.y++;   
}
Player.prototype.moveDown = function() {
    this.y--;   
}

$(window).keyDown(function(key) {
    if(key == x) {
        Player.moveUp();
    }
    else if (key == y) {
        Player.moveDown();
    }
});

不确定这会产生什么影响,就像我这样做:B

答案 1 :(得分:1)

不确定这是否是唯一的问题,但在动画循环中您使用的是player.vYplayer.vy(注意大写/小写'Y'的差异)。

同样在动画循环中,player.vy似乎被赋予了相同的上下值

if (player.moveUp){
    player.vy = 3;
};
if (player.moveDown){
    player.vy = 3;
};

我不确定,但我认为当我点击右箭头时,if(player.moveDown)(再次在上面的代码中)评估为真。我没有进一步查看这是否是有意/期望的,或者是在右箭头之前击中箭头的结果,也许moveDown没有重置等。