我一直在编写游戏引擎,我想重新组织我的代码以使其更加模块化。目前,我有一个名为Isometric
的主函数,它接受画布来绘制。
var iso = new Isometric('canvas');
到目前为止一切顺利。接下来,我有.newMap()
来创建新地图。
var map = iso.newMap(10,1,10); // Creates 10x1x10 map
但是,我想改变它,因为.map属性可能会有一些混淆(因为这会返回一个名为map 的数组)。
我希望语法看起来像这样:
iso.Map.create(10,1,10);
所以我尝试过这样的事情:
function Isometric(id) {
this.Map = function() {
this.create = function() {
}
}
}
但是当我去访问它时,我意识到第二级this
仍然指的是同一个第一级。所以,我无法创建Map对象的子类。
我已经看了几种不同的方法,但没有一种方法有明确的例子,我也无法让它们发挥作用。
其中,我知道您可以使用prototype
和Object.create()
,但我没有取得多大成功。
我该怎么做?
我的另一个解决方案是做这样的事情:
function Isometric('id') {
this.Map = {
'create': function() { },
'load': function() {}
}
}
然后像
一样访问它iso.Map['create'];
但我根本不喜欢这样。这样做有什么干净的方法吗?
我的主要兴趣是在.map中使用第三级方法..create()的示例。如果你能提供我尚未找到的与我的问题相关的文件,那就太好了。但即使是mozilla文档似乎也无济于事。
答案 0 :(得分:1)
我认为在这里做的恰当的事情是在 Isometric 构造函数下命名 Map 构造函数。以下是你可以采取的措施。
function Isometric(id) {
this.id = id;
}
Isometric.prototype = {
constructor: Isometric,
test: function() {
return "I'm an instance of Isometric.";
}
};
这里我们执行命名空间并向Map构造函数添加create()
辅助方法以创建其实例。
Isometric.Map = function Map(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
}
Isometric.Map.prototype = {
constructor: Isometric.Map,
test: function() {
return "I'm an instance of Isometric.Map.";
}
};
// Helper method to create `Map` instances
Isometric.Map.create = function create(x, y, z) {
return new Isometric.Map(x, y, z);
};
<强>用法强>:
var iso = new Isometric('id123');
var map = new Isometric.Map(0, 7, 99);
var map2 = Isometric.Map.create(1, 2, 3);
iso.test(); //=> "I'm an instance of Isometric."
map.test(); //=> "I'm an instance of Isometric.Map."
map2.test(); //=> "I'm an instance of Isometric.Map."
重要的是要注意我们刚刚执行的命名空间可以防止与ES6中的新Map
类发生冲突(新JS版) - 更多关于ES6地图的信息:{ {3}}。
话虽如此,将代码命名为一个主要对象(你可以称之为app
)并且只在全局范围内使用该命名空间总是很重要。
在您的情况下,您可以执行以下示例:
;(function(win) {
// Isometric
function Isometric(id) {
this.id = id;
}
Isometric.prototype = {
constructor: Isometric,
test: function() {
return "I'm an instance of Isometric.";
}
};
// Map
function Map(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
}
Map.prototype = {
constructor: Map,
test: function() {
return "I'm an instance of Isometric.Map.";
}
};
// Helper method to create `Map` instances
Map.create = function create(x, y, z) {
return new Map(x, y, z);
};
// Namespace Map under Isometric
Isometric.Map = Map;
// Expose globally
// --------------------
win.app = {
Isometric: Isometric
};
}(this));
示例:强>
var nativeMap = new Map();
nativeMap.set('name', 'joe'); //=> {"name" => "joe"}
var myMap = new app.Isometric.Map(33, 7, 99);
myMap.test(); //=> "I'm an instance of Isometric.Map."
// Native map wasn't affected (good)
nativeMap.test(); //=> TypeError: undefined is not a function
答案 1 :(得分:0)
我会将其他答案保留为接受,因为它更详细,甚至告诉我我的代码可能会被原样弃用。
话虽这么说,我想重新讨论Felix King的解决方案。我将想出一种结合两种想法的方法(使用命名空间和使用Felix),但这里有部分解决方案。
function Isometric(id) {
this.Map = function() {
this.create = function() {
return 5;
};
};
}
这就是我的设置。 5只是一个任意值。
var iso = new Isometric(); // New instance of Isometric()
var mapping = new iso.Map(); // Access to Iso's mapping functions
var map = mapping.create(); // Should return a map array
console.log(map); // Prints 5
对于关注此事的任何人,如果您想了解我最终如何实现它,那么请参阅我的Github项目:https://github.com/joshlalonde/IsometricJS
我将在本周末的某个时间播放代码。
再次感谢大家的帮助!祝所有试图做类似事情的人好运。