小行星子弹运动难度

时间:2017-07-14 16:15:48

标签: javascript html5 canvas

所以我在HTML5中制作了一个小行星游戏,并且我坚持使用子弹[i] .move功能的子弹运动。当我按空格键时,程序会绘制一颗子弹,但它只跟随船只,但从未离开船只。您可以在调用时直接将数字输入到函数中,但是当我为speedX和SpeedY调用对象时,子弹根本不会移动。它是用于导致问题的子弹的x和y位置吗?我的代码:

function Bullet(x, y, sx, sy) {

this.x = x;
this.y = y;
this.sx = sx;
this.sy = sy;
this.r = 1;

this.show = function() {

    ctx.fillStyle = "white";
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.r, 0, Math.PI*2);
    ctx.fill();
    ctx.closePath();

};

this.move = function() {

    this.x += this.sx;
    this.y += this.sy;

};

this.wrap = function() {

    if (this.x > width+this.r) {

        this.x = -this.r;

    } else if (this.x < -this.r) {

        this.x = width+this.r;

    }

    if (this.y > height+this.r) {

        this.y = -this.r;

    } else if (this.y < -this.r) {

        this.y = height+this.r;

    }

};

}

for (var i = 0; i < bullets.length; i++) {

    var b = bullets[i];

    bullets[i] = new Bullet(b.x, b.y, b.speedX*10, b.speedY*10);

    bullets[i].move();
    bullets[i].wrap();
    bullets[i].show();

}

if (spacePressed) {

    bullets.push({x: player.pos.x, y: player.pos.y, speedX: Math.sin(player.heading), speedY: -Math.cos(player.heading)});

};

这是我的代码:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height;

var leftPressed = false; 
var rightPressed = false;
var upPressed = false;
var spacePressed = false;

document.addEventListener("keydown", d); 
document.addEventListener("keyup", u);  

function d(e) { 
 
	if (e.keyCode == 37) { 
 
		leftPressed = true; 
 
 	} else if (e.keyCode == 39) { 
 
 		rightPressed = true; 
 
	}
	
	if (e.keyCode == 38) {
		
		upPressed = true;
		
	}
	
	if (e.keyCode == 32) {
		
		spacePressed = true;
	
	}
 
} 
 
function u(e) { 
 
	if (e.keyCode == 37) { 
 
		leftPressed = false; 
 
 	} else if (e.keyCode == 39) { 
 
 		rightPressed = false; 
 
 	} 
	
	if (e.keyCode == 38) {
		
		upPressed = false;
	
	} 
	
	if (e.keyCode == 32) {
		
		spacePressed = false;
	
	} 
 
}

function Vector(x, y) {
	
	this.x = x || 0;
	this.y = y || 0;

}

function Bullet(x, y, sx, sy) {
	
	this.x = x;
	this.y = y;
	this.sx = sx;
	this.sy = sy;
	this.r = 1;
	
	this.show = function() {
		
		ctx.fillStyle = "white";
		ctx.beginPath();
		ctx.arc(this.x, this.y, this.r, 0, Math.PI*2);
		ctx.fill();
		ctx.closePath();
		
	};
	
	this.move = function() {
		
		this.x += this.sx;
		this.y += this.sy;
		
	};
	
	this.wrap = function() {
		
		if (this.x > width+this.r) {
			
			this.x = -this.r;
			
		} else if (this.x < -this.r) {
			
			this.x = width+this.r;
			
		}
		
		if (this.y > height+this.r) {
			
			this.y = -this.r;
			
		} else if (this.y < -this.r) {
			
			this.y = height+this.r;
			
		}
		
	};
	
}

function Player() {
	
	this.pos = new Vector(width/2, height/2);
	this.r = 15;
	this.heading = 0;
	this.facingX = 0;
	this.facingY = 0;
	
	this.show = function() {
		
		ctx.strokeStyle = "white";
		ctx.save();
		ctx.translate(this.pos.x, this.pos.y);
		ctx.rotate(this.heading);
		ctx.beginPath();
		ctx.moveTo(-this.r, this.r);
		ctx.lineTo(this.r, this.r);
		ctx.lineTo(0, -this.r);
		ctx.closePath();
		ctx.restore();
		ctx.stroke();
		
	};
	
	this.move = function() {
		
		this.pos.x += this.facingX;
		this.pos.y += this.facingY;
		
		this.facingX *= 0.95;
		this.facingY *= 0.95;
			
	};
	
	this.applyForce = function() {
		
		var force = new Vector(Math.sin(this.heading), -Math.cos(this.heading));
		
		force.x *= 0.5;
		force.y *= 0.5;
		
		this.facingX += force.x;
		this.facingY += force.y;
		
	};
	
	this.rot = function(angle) {
		
		this.heading += angle;
		
	};
	
	this.wrap = function() {
		
		if (this.pos.x > width+this.r) {
			
			this.pos.x = -this.r;
			
		} else if (this.pos.x < -this.r) {
			
			this.pos.x = width+this.r;
			
		}
		
		if (this.pos.y > height+this.r) {
			
			this.pos.y = -this.r;
			
		} else if (this.pos.y < -this.r) {
			
			this.pos.y = height+this.r;
			
		}
		
	};

}

var player = new Player();

var bullets = [];

function draw() {
	
	ctx.fillStyle = "black";
	ctx.fillRect(0, 0, width, height);
	
	for (var i = 0; i < bullets.length; i++) {
		
		var b = bullets[i];
		
		bullets[i] = new Bullet(b.x, b.y, b.speedX*10, b.speedY*10);
		
		bullets[i].move();
		bullets[i].wrap();
		bullets[i].show();
		
	}
	
	if (spacePressed) {
		
		bullets.push({x: player.pos.x, y: player.pos.y, speedX: Math.sin(player.heading), speedY: -Math.cos(player.heading)});
		
	};
	
	player.wrap();
	player.move(player.facingX, player.facingY);
	player.show();
	
	if (leftPressed) {
		
		player.rot(-0.1);
		
	} else if (rightPressed) {
		
		player.rot(0.1);
		
	}
	
	if (upPressed) {
		
		player.applyForce();
		
	}
	
}

function update() {
	
	draw();
	
	requestAnimationFrame(update);
	
}

update();
<!DOCTYPE html>
<html>
	<head>
		<title> Asteroids </title>
		<style>
			body {
				font-family: Helvetica;
			}
		</style>
	</head>
	<body>
		<canvas width="500" height="500" id="canvas"></canvas>
		<script src="asteroids.js"></script>
	</body>
</html>

2 个答案:

答案 0 :(得分:1)

重新初始化Bullet对象,每个帧都是问题出现的地方。

for (var i = 0; i < bullets.length; i++) {
    bullets[i].move();
    bullets[i].wrap();
    bullets[i].show();
}

if (spacePressed) {
  bullets.push(
    new Bullet(
      player.pos.x, 
      player.pos.y, 
      Math.sin(player.heading) * 10, 
      -Math.cos(player.heading) * 10
    )
  );

  spacePressed = false;
};

这允许子弹对象相应地更新,您也可以使用instanceOf检查子弹的类型,但从长远来看,它的可读性会降低。

添加spacePressed = false是为了防止空格键一次按下多个子弹帧。

我有一个fiddle here,所以你可以看到它的实际效果。

答案 1 :(得分:0)

你是否尝试沿着子弹的不同方向移动船? 如果没有,请尝试,如果子弹保持相同的路径,我建议更新子弹的速度比船速更快