我应该如何包装我的引擎
How should I wrap up my engine?
我正在为Javascript创建一个游戏引擎,或者更像是一个由有用的类和函数组成的大型库。我计划在服务器端和客户端使用它进行一些科学模拟,因此功能范围将非常广泛,但它始终围绕虚拟世界(例如游戏(展开。
不过,我不知道如何包装它。如果我只提供所有类,它会污染全局命名空间,这是非常糟糕的。我可以将所有内容放在一个充当命名空间的对象中吗?框架本身应该是一个可以实例化的类吗?
如果选择后一个选项,如何处理类(构造函数(中的类?
var Engine = function()
{
this.someVar = 4;
}
Engine.prototype.Scene = function()
{
this.entities = [];
//What if the scene object needs some classes that are in the engine? How does it get it's parent engine object?
}
Engine.prototype.Scene.prototype.render = function()
{
//"this" should now represent an instance of a scene. But how can I get someVar from the engine? How can I traverse up in the hierarchy of classes?
}
我更喜欢使用有时被称为"揭示模块"的东西(...模式(。它看起来像:
var Engine = (function($)
{
$ = $ || {};
var someVar = 4;
$.Scene = function()
{
this.entities = [];
}
$.Scene.prototype.render = function()
{
// this function can access someVar just fine because of JavaScript's scoping rules
}
return $;
})(Engine);
这使用所谓的立即调用的函数表达式(以下称为 IIFE(在引擎对象中形成闭包。由于 JavaScript 对范围的处理,IIFE 中定义的任何函数都可以访问someVar
。然而,这意味着,如果函数想要引用您在 IIFE 中定义的someVar
,则没有函数可以定义自己的someVar
。
魔力来自返回语句。您可以看到返回了一个对象,并且在此对象中,您必须定义任何要"公共"的内容。
然后可以通过 Engine.Scene
访问构造函数、实用程序方法等,这可以很好地为您的代码命名。
至于$
参数,这是为了让您可以将Engine
传递给每个文件中的函数,添加一些方法/属性/构造函数(如果不存在,则创建一个新方法/属性/构造函数(,然后将返回值传递给另一个 IIFE 进行进一步扩展。
这是许多流行的JavaScript框架中使用的方法,包括jQuery,dojo和LimeJS。
场景.js:
var Engine = (function ($) {
// this creates a new object if Engine is undefined in the
// invocation below, and keeps the old object otherwise.
// alternatively: if ($ === undefined) { $ = new Object; }
$ = $ || {};
$.foo = "foo";
$.Scene = function () {
// blah blah
}
// Engine holds either a newly created object,
// or the old one if it was already defined
return $;
})(Engine);
雪碧.js:
var Engine = (function ($) {
$ = $ || {};
$.Sprite = function () {
// totally works
this.bar = $.foo;
}
return $;
})(Engine);
然后,您可以将它们与以下内容一起使用:
<script type="text/javascript" src="bar.js"></script>
<script type="text/javascript" src="foo.js"></script>
<script type="text/javascript">
var mySprite = new Engine.Sprite;
var myScene = new Engine.Scene;
</script>
你可以用任何你喜欢的东西代替$
,$$
很常见,或者你可以很聪明。它只是您要添加到的全局对象的占位符。
我认为你不需要甚至不应该像那样组织你的课程。即使 Scene 和 Engine 类是相关的,Scene 类也不必是 Render 的子类。请改用平面类层次结构,这将更易于维护和扩展。
最后,您确实应该将所有这些类放在同一个命名空间下,以免污染全局命名空间。
// Define the namespace only if it doesn't already exist. That
// way you can split the definition of your classes in various
// files, without having to worry in which order they are loaded.
if (typeof gameEngine === 'undefined') gameEngine = {};
gameEngine.Engine = function()
{
this.someVar = 4;
}
gameEngine.Scene = function()
{
this.entities = [];
}
// Add a new function to define which
// scene the Engine should render:
gameEngine.Engine.prototype.setScene = function(scene)
{
this.scene = scene;
}
gameEngine.Engine.prototype.render = function()
{
// render this.scene
}
- 为什么不't Javascript对我的输入值进行了一些重新检查
- 可以't让我的if语句处理js中的html表单输入
- 我的单元测试选项是什么
- 将输入字段中的文本提交到我的数据库,同时将其添加到我的列表中
- 我的职位回报太快了,如何做出承诺
- 我的jQuery插件参数没有正确启动,遇到了问题
- 如何识别我的网站中的慢速设备
- 如何将JSON数据导入我的ejs模板
- JQuery添加元素需要在我的js之前再次添加JQuery脚本
- 知道为什么我的旋转木马不会自动更改图片吗
- 我的模板未被解析
- 无法将数据从firebase获取到我的html页面
- 角度图表;t显示在我的页面中
- 自定义运行时Can'在谷歌应用引擎中看不到我的自定义日志
- 我应该如何包装我的引擎
- 是否可以使用渠道 API 从另一个域连接到我的应用引擎
- 从javascript访问我的应用引擎端点
- 表达式引擎2.2.2;为什么我的CSS不能在任何地方工作?
- 应用引擎通道API's Javascript客户端使用我的onError回调
- 我应该在我的Javascript游戏引擎中使用DOM片段作为Shadow DOM吗