如何向此功能添加开始按钮?
Posted
技术标签:
【中文标题】如何向此功能添加开始按钮?【英文标题】:How can i add a Start button to this function? 【发布时间】:2017-12-14 15:29:10 【问题描述】:我试图弄清楚如何通过替换背景中的音频来添加一个开始按钮来玩 javascript 游戏。我遇到了这个游戏,它的工作方式是在您加载页面时在后台播放音乐并且游戏已经开始。当我删除音频链接时,玩家3生命结束后游戏暂停,如果我保留音频,那么当3生命结束时你可以看到你的积分和弹出消息,请有人帮我理解这一点
这里是游戏的链接,因此您可以查看代码并理解我要说的内容:https://jsfiddle.net/74nbrdak/embedded/result/
<div>
<canvas id="canvas" ></canvas>
</div>
<audio id="background-music" preload="auto" autoplay loop>
<source
src="https://dl.dropbox.com/s/5r3iu7kjsl0mx81/Wildfire%20Cut%20Loopable.wav" type="audio/wav">
function ShowGamesFinished()
var message = gamesfinished[Math.floor(Math.random() * gamesfinished.length)];
document.getElementById("background-music").pause();
【问题讨论】:
这看起来像不完整的代码。提供更多代码,以便我们了解发生了什么。 @AdityaDan.i 添加了一个链接,您可以在其中查看代码 【参考方案1】:当我删除音频链接时,玩家3生命结束后游戏暂停,如果我保留音频,那么当3生命结束时你可以看到你的积分和弹出消息,请有人帮忙这个我明白了
因此,在第二个场景中,当音频元素出现在页面上时,游戏会按照创建者的意图运行。
在第一个场景中,当音频元素不在页面上时,游戏可以正常运行,直到调用处理游戏结束的函数。导致该函数出现问题的原因是这一行document.getElementById("background-music").pause();
。由于音频元素不存在,它会引发错误并且不会绘制游戏结束屏幕。希望这会有所帮助
【讨论】:
这是关键!谢谢。 非常感谢!这是我无法确定的主要问题,现在我唯一需要帮助的是有一个开始/暂停按钮,这样游戏就不会在页面加载后立即开始,你能帮忙吗?var gameLoop = setInterval(Update, updateTime);
这是启动游戏的一段代码。编写一个简单的函数,将setInterval
值分配给gameLoop
。但是,要让它与所有代码一起工作,请在全局范围内声明 gameLoop 变量,然后像我提到的那样为其分配值。然后在按钮的click
事件上运行该函数。
你能告诉我另一个截图吗?你不是也必须创建一个暂停按钮吗?
如果要暂停游戏,请清除间隔gameLoop
【参考方案2】:
如果您使用的是纯 javascript 没有任何外部库,您可以初始化您的画布,然后单击按钮即可开始为画布设置动画,然后您的游戏就开始了。 如果你没有得到我的答案,请告诉我。
【讨论】:
如果您不介意,请告诉我这是什么样子的?function animate()
` c.clearRect(0,0,window.innerWidth,window.innerHeight);` ` requestAnimationFrame(animate);` ` for(var i = 0; i circle.update();
//init your canvas
init()
document.getElementById('start').onclick = function()
` //此函数将在画布中启动动画` ` animate(); `;
您能以正确的格式列出这个吗?我看起来很困惑
这里是截图的链接。 photos.app.goo.gl/kmNh6fmHPjTPedQ22
这个解决方案能解决音频问题吗?我正在尝试删除影响游戏的音频【参考方案3】:
乍一看,删除音频标签应该对 javascript 没有任何影响。音频在打开页面时播放,因为音频标签具有自动播放属性。
所有的 javascript 代码似乎都在一个脚本标签内,所以一旦页面打开,它也会自动运行。您可以尝试将 fiddle 中的整个代码包装到一个函数中,然后将其绑定到您的按钮。
类似:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
h1
font-family: Architects Daughter;
text-align: center;
font-size: 48pt;
margin-top: 50px;
margin-bottom: 0px;
h2
font-family: Architects Daughter;
text-align: center;
font-size: 28pt;
margin-top: 0px;
margin-bottom: 50px;
span
display: block;
font-family: Arial;
text-align: center;
margin-bottom: 2px;
div
display: flex;
justify-content: space-around;
canvas
border: 2px solid #CC3333;
</style>
</head>
<body>
<div>
<canvas id="canvas" ></canvas>
</div>
<button id="start_game">Start</button>
<script>
var run_game = function()
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var updateTime = 20; // Milliseconds
var keys = [false, false, false];
var score = 0;
var kills = 0;
// Player Size = 50x18
var playerHealth = 3;
var playerX = WIDTH / 2;
var playerY = HEIGHT - 20;
var playerSpeed = 6;
var lazerSpeed = 16;
var lazerReloadDistance = playerY - 120;
var lazerLoaded = true;
var lazers = [];
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var maxEnemies = 12;
var enemySpeed = 4;
var enemies = [];
function Clear()
ctx.fillStyle = "#404040";
ctx.fillRect(0, 0, WIDTH, HEIGHT);
function DrawHealth(health)
ctx.fillStyle = "#E52B50";
ctx.shadowColor = "#E52B50";
ctx.shadowBlur = 15;
ctx.font = "18px Arial";
ctx.textAlign = "start";
var hearts = "";
if (health == 3)
hearts = "<3 <3 <3";
else if (health == 2)
hearts = "<3 <3 X";
else if (health == 1)
hearts = "<3 X X";
else
hearts = "X X X";
ctx.fillText(hearts, 10, 25);
function DrawScore()
ctx.fillStyle = "#FFFF00";
ctx.shadowColor = "#FFFF00";
ctx.shadowBlur = 15;
ctx.font = "18px Arial";
ctx.textAlign = "end";
ctx.fillText(score, WIDTH - 10, 25);
function DrawPlayer(x, y)
ctx.fillStyle = "#1E90FF";
ctx.shadowColor = "#1E90FF";
ctx.shadowBlur = 15;
ctx.font = "24px Arial";
ctx.textAlign = "center";
ctx.fillText("</^\\>", x, y);
function Lazer()
this.x = playerX;
this.y = playerY - 38;
this.draw = function()
ctx.fillStyle = "#FFFF00";
ctx.shadowColor = "#FFFF00";
ctx.shadowBlur = 15;
this.y -= lazerSpeed;
ctx.fillRect(this.x, this.y, 2, 18);
function DrawLazers()
// Check if the last lazer fired is far enough away to fire another
if (lazers.length != 0)
if (lazers[lazers.length - 1].y <= lazerReloadDistance)
lazerLoaded = true;
else
lazerLoaded = true;
for (var i = 0; i < lazers.length; i++)
var currentLazer = lazers[i];
// Still on screen
if (currentLazer.y > -20)
currentLazer.draw();
else
lazers.splice(i, 1);
function Enemy(x)
this.x = x;
this.y = 0;
this.health = Math.ceil(Math.random() * 4);
this.speed = enemySpeed / this.health;
var letterIndex = Math.floor(Math.random() * letters.length);
this.letter = letters.substr(letterIndex, 1);
this.size = 24 + (this.health * 4); // Font size based on health
ctx.font = this.size+"px Arial";
this.width = ctx.measureText(this.letter).width;
this.height = this.size * 0.75; // Approximate height;
this.draw = function()
ctx.fillStyle = "#FF0040";
ctx.shadowColor = "#FF0040";
ctx.shadowBlur = 15;
ctx.font = this.size+"px Arial";
ctx.textAlign = "center";
this.y += this.speed;
ctx.fillText(this.letter, this.x, this.y);
function DrawEnemies()
// Spawn new enemies
if (Math.random() <= 0.05 && enemies.length < maxEnemies)
var randX = 40 + Math.floor(Math.random() * (WIDTH - 80));
enemies.push(new Enemy(randX));
for (var i = 0; i < enemies.length; i++)
var currentEnemy = enemies[i];
if (currentEnemy.health <= 0)
enemies.splice(i, 1);
score += 25;
kills++;
continue;
// Put enemies that passed the player back at the top
if (currentEnemy.y > HEIGHT + currentEnemy.height)
currentEnemy.y = 0;
continue;
currentEnemy.draw();
var gameOverMessages = [
"You're in a better place",
"You're Cooked!",
"You gave it your all",
"At least you tried",
"You're Ruined!",
"You're Finished!"
];
function DrawGameOver()
var message = gameOverMessages[Math.floor(Math.random() * gameOverMessages.length)];
// after deleting the audio element, this doesnt work anymore.
// document.getElementById("background-music").pause();
ctx.fillStyle = "#505050";
ctx.shadowColor = "#505050";
ctx.shadowBlur = 15;
ctx.fillRect(50, (HEIGHT / 2) - 100, WIDTH - 100, 200)
ctx.fillStyle = "#FFFFFF";
ctx.shadowColor = "#FFFFFF";
ctx.shadowBlur = 15;
ctx.textAlign = "center";
ctx.font = "36pt Arial";
ctx.fillText(message, WIDTH / 2, HEIGHT / 2 - 40);
ctx.textAlign = "end";
ctx.font = "18pt Arial";
ctx.fillText("Final Score - ", WIDTH / 2, HEIGHT / 2 + 30);
ctx.textAlign = "start";
ctx.fillStyle = "#FFFF00";
ctx.shadowColor = "#FFFF00";
ctx.fillText(score, WIDTH / 2, HEIGHT / 2 + 30);
ctx.fillStyle = "#FFFFFF";
ctx.shadowColor = "#FFFFFF";
ctx.textAlign = "end";
ctx.font = "18pt Arial";
ctx.fillText("Total Kills - ", WIDTH / 2, HEIGHT / 2 + 60);
ctx.textAlign = "start";
ctx.fillStyle = "#FF0040";
ctx.shadowColor = "#FF0040";
ctx.fillText(kills, WIDTH / 2, HEIGHT / 2 + 60);
////////////////////
// Core Functions //
////////////////////
var collidedEnemyIndex = -1;
function CheckCollision()
for (var i = 0; i < enemies.length; i++)
var currentEnemy = enemies[i];
// Check if enemy hits player. The 2 is to account for the text width of the player
if (
currentEnemy.x <= playerX - 2 + 25 + (currentEnemy.width / 2) &&
currentEnemy.x >= playerX - 2 - 25 - (currentEnemy.width / 2) &&
currentEnemy.y >= playerY - 18 &&
currentEnemy.y <= playerY + currentEnemy.height &&
collidedEnemyIndex != enemies.indexOf(currentEnemy)
)
collidedEnemyIndex = enemies.indexOf(currentEnemy);
playerHealth--;
// Reset the index of the enemy colliding with the player
if (collidedEnemyIndex == enemies.indexOf(currentEnemy) && currentEnemy.y < HEIGHT / 2)
collidedEnemyIndex = -1;
for (var j = 0; j < lazers.length; j++)
var currentLazer = lazers[j];
if (
currentLazer.x <= currentEnemy.x + (currentEnemy.width / 2) &&
currentLazer.x >= currentEnemy.x - (currentEnemy.width / 2) &&
currentLazer.y <= currentEnemy.y
)
currentEnemy.health--;
score += 10;
lazers.splice(lazers.indexOf(currentLazer), 1);
function HandleInput()
if (keys[0] == true && keys[1] == false && playerX <= WIDTH - 30)
playerX += playerSpeed;
if (keys[1] == true && keys[0] == false && playerX >= 30)
playerX -= playerSpeed;
if (keys[2])
if (lazerLoaded)
lazers.push(new Lazer());
lazerLoaded = false;
function KeysDown(e)
e.preventDefault();
// Right
if (e.keyCode == 39)
keys[0] = true;
// Left
else if (e.keyCode == 37)
keys[1] = true;
// Up/Fire
if (e.keyCode == 38)
keys[2] = true;
function KeysUp(e)
// Right
if (e.keyCode == 39)
keys[0] = false;
// Left
else if (e.keyCode == 37)
keys[1] = false;
// Up/Fire
if (e.keyCode == 38)
keys[2] = false;
document.addEventListener("keydown", KeysDown, true);
document.addEventListener("keyup", KeysUp, true);
function Update()
Clear();
HandleInput();
CheckCollision();
DrawEnemies();
DrawLazers();
DrawPlayer(playerX, playerY);
DrawHealth(playerHealth);
DrawScore();
if (playerHealth <= 0)
clearInterval(gameLoop);
DrawGameOver();
var gameLoop = setInterval(Update, updateTime);
;
document.querySelector( '#start_game' ).addEventListener( 'click', run_game );
</script>
</body>
</html>
【讨论】:
您能否将其应用于小提琴中的代码,并通过删除整个音频来查看它是否有效?如果你能给我截图,我将不胜感激 已更新完整代码。在我修复了 Aditya 的发现后,它现在可以工作了。 你是一个活生生的救星!太感谢了!还有一件事,在我点击开始之前,你看不到游戏,因为它是白色的。有没有办法显示游戏但在用户单击开始按钮之前不玩它? 你可以,但这需要对代码进行相当大的重组,这是我无法在 10 分钟内解决的问题。 “好的”解决方案是将所有渲染代码拆分为可以在之前渲染的部分,例如背景,以及必须在游戏时间运行的部分,例如敌人。但是由于 DrawPlayers() 函数已经需要玩家,你不能轻易单独运行它。 “糟糕”的解决方案是在游戏开始之前自己在画布上绘制。 我明白你的意思,那么我怎么能把游戏截图放在实际游戏上呢?我希望它工作的方式是,当用户单击开始时,图像会消失,他们可以玩下面的游戏。你知道我的意思吗?以上是关于如何向此功能添加开始按钮?的主要内容,如果未能解决你的问题,请参考以下文章