我正在努力制作一个向上滚动式的街机射击游戏。我已经陷入了如何从玩家向上吸引子弹到敌人的位置。我正在使用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>
<input id="start" type="button" value="START THE GAME" onclick="setUp()" style="width: 300px">
</body>
</html>
每次发射子弹时都不想使用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作为演示的捷径
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();
}
备注: