所以我偶然发现了一些在Phaser的html 5游戏引擎上运行的游戏代码。以下是示例代码
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
function preload() {
game.load.image('someKey','someUrl');
}
function create() {
}
function update() {
}
我试图弄清楚移相器如何通过引用函数声明并将图像添加到对象等来实现向游戏对象传递函数(预加载,创建和更新)。变量名称'游戏'。上面提供的示例是我在网络上经常看到的(或至少类似的东西)。
下面,我已经开始研究自己的游戏引擎(为了好玩),以模仿移相器并了解它们的过程。不幸的是,我无法成功地完成与上面相同的效果。
My Engine.js(Phaser copycat文件)
function Game(holderId,canvasOptions,functionDeclarations){
this.test="testing";
functionDeclarations.init();//this does not work :( because game in init() is undefined.
}
My Main.js
var game= new Game("canvas-holder",{width:1500,height:600, unit:"px"},{init:init,core:core,update:update});
function init(){
console.log(game.test);//game is undefined. Seems like a scope issue
}
我觉得这是一个范围问题。我尝试查看移相器的源代码,但它包含97k行,而ctrl + f没有任何帮助。
答案 0 :(得分:2)
传递给Phaser构造函数的Object是游戏State。查看Phaser仓库中的src/core/State.js
以获取示例状态文件,并说明每个功能和属性的用途。
我不能这么说:不要试图通读单个phaser.js文件!而是检查仓库并逐个浏览文件。他们在那里处于一个合乎逻辑且理智的结构中,并且更容易遵循这条路径。
创建Phaser游戏时,它会等待DOM Ready事件。只有当它接收到它时才会开始运行State对象,依次调用这些函数。这就是为什么你可以在game
函数中引用preload
而不是得到范围错误的原因,因为在它被调用时它就存在了。
在上面的示例中(以及在Phaser示例站点上找到的所有内容),game
被创建为全局JS对象。我们这样做纯粹是为了让示例代码更简洁,更易于操作。在生产级游戏中,你很少会真正做到这一点。查看Phaser repo,项目模板中的“资源”文件夹,那里有更好的结构化替代方案。
答案 1 :(得分:1)
在您的代码中,init
使用game
。 game
由Game
构造函数定义,该构造函数尝试在init
完成之前调用game
(因此,在分配game
之前)。这导致循环依赖,undefined
调用期间init
将为init
。
解决此问题的一种方法是延迟执行setTimeout(functionDeclarations.init, 0)
。使用init
而不是直接调用game
,您将完成构造函数,将正确的值分配给init
并执行JS文件中可能存在的任何其他内容。完成所有操作后,var m map[string]int
将被调用,每个人都会感到高兴。