我一直在尝试为我的太空侵略者游戏编写启动部分。但是,当身体加载我的一个对象(startbtn变量)时,它没有出现在画布上。
以下是我游戏的代码
<html>
<head>
<title>Space Invaders</title>
</head>
<body onload="startGame()">
<script type="text/javascript">
var startbtn;
function startGame(){
startbtn = new compenent(50, 20, "blue", 120, 10);
myGameArea.start();
}
var myGameArea = {
canvas: document.createElement("canvas"),
start: function(){
this.canvas.width = 420;
this.canvas.height = 220;
ctx = this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas,
document.body.childNodes[0]);
ctx.font="35px Verdena";
ctx.fillText("Welcome to Space Invaders",10,50);
},
clear : function(){
this.context.clearRect(0, 0, this.canvas.width ,
this.canvas.height);
}
}
function compenent(width, height, color, x, y){
this.width = width;
this.height = height;
this.x = x;
this.y = y;
this.update = function(){
ctx = myGameArea.context;
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
function updateGame(){
myGameArea.clear();
startbtn.update();
}
</script>
</body>
</html>
如果有人可以帮助我,那就太好了。
答案 0 :(得分:1)
主要问题是从未调用updateGame()
。您可以将其添加到startGame()
函数中,以在设置画布后运行。完成此操作后,蓝色框显示但不显示文本。原因是因为myGameArea.clear();
清除了myGameArea.start
函数中绘制的文本。删除myGameArea.clear();
会导致:
var startbtn;
function startGame() {
startbtn = new compenent(50, 20, "blue", 120, 10);
myGameArea.start();
updateGame();
}
var myGameArea = {
canvas: document.createElement("canvas"),
start: function() {
this.canvas.width = 420;
this.canvas.height = 220;
ctx = this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas,
document.body.childNodes[0]);
ctx.font = "35px Verdena";
ctx.fillText("Welcome to Space Invaders", 10, 50);
},
clear: function() {
this.context.clearRect(0, 0, this.canvas.width,
this.canvas.height);
}
}
function compenent(width, height, color, x, y) {
this.width = width;
this.height = height;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
function updateGame() {
//myGameArea.clear();
startbtn.update();
}
startGame(); // moved from body.onload
但是,在这一点上,很明显,在制作功能齐全的太空侵略者游戏时,存在一些潜在的设计障碍。您正在使用的w3schools教程正在尝试基本的entity-component system,但是对于初学者来说这可能会造成混淆,因此,如果没有其他问题,我鼓励您在其他教程中进行浏览。
随着示例的发展,动画具有基本组成部分:
该初始化运行一次,或者在某些情况下每当需要重置动画(或游戏级别)时运行。更新和渲染例程每秒运行多次,并共同构成主动画循环(每个动画循环每帧执行一次,因此它们实质上是同一“动画循环”功能的一部分):
----------------
| |
v |
init -----> update -----> render
这要求每个例程对他们的任务负责,别无其他。每次渲染调用都应清除屏幕,然后绘制每个可见对象。例如,init函数不应包含任何渲染代码。
还值得一提:绘制的所有内容都是一个对象(或实体)。 W3schools的教程可帮助您入门,但是如何区分button
组件和spaceInvader
组件呢?您可以将objects/classes完全分开作为初学者。
下一个抽象级别是一个状态,每个状态都有自己的init --> update --> render
函数:
---------------------------------------- ----------------------------------------
| menu state | | game state |
| | | |
| ---------------- | | ---------------- |
| | | | | | | |
| v | | | v | |
| init -----> update -----> render | | init -----> update -----> render |
---------------------------------------- ----------------------------------------
这一切对您的示例意味着什么?您正在尝试通过一些文本和按钮来设置菜单状态以开始游戏。管理一堆游戏状态可能会变得非常复杂,因此Phaser之类的图形库提供了built-in state management systems。如果希望或推迟问题,可以设计一个,然后使用变量或布尔值确定您所处的状态。对于初学者,我建议以单一状态工作,然后在必要时添加更多状态。换句话说,请考虑简化或跳过菜单状态,而改用游戏状态,直到准备好使用状态为止。
制作动画的另一个可能具有挑战性的方面是处理鼠标事件。您如何知道单击按钮的时间?至少,您需要使用event listener and some math。图书馆可以do it for you。
无论哪种方式,在JS中循环going都需要requestAnimationFrame或(不太可能/不推荐)setInterval。从MDN网络文档中查看一些basic examples。
我希望这可以为您提供一条前进的道路,并突出显示您可能需要研究的一些领域,然后再采用当前的方法。