我应该使用构造函数/原型吗?
Should I be using a constructor / prototype?
function setupMapObjects() {
lootChest = new PIXI.Sprite(frame("images/chest.png", 0, 0, 50, 50));
lootChest.x = 200;
lootChest.y = 200;
lootChest.anchor.x = 0.5;
lootChest.anchor.y = 0.7;
lootChest.closed = true;
lootChest.opening;
lootChest.frameCycle = 0;
lootChest.interactive = true;
lootChest.hitArea = new PIXI.Circle(lootChest.x, lootChest.y, 10);
lootChest.on('click', openChest);
Map.addChild(lootChest);
lootChest2 = new PIXI.Sprite(frame("images/chest.png", 0, 0, 50, 50));
lootChest2.x = 400;
lootChest2.y = 400;
lootChest2.anchor.x = 0.5;
lootChest2.anchor.y = 0.7;
lootChest2.closed = true;
lootChest2.opening;
lootChest2.frameCycle = 0;
lootChest2.interactive = true;
lootChest2.hitArea = new PIXI.Circle(lootChest2.x, lootChest2.y, 10);
lootChest2.on('click', openChest);
Map.addChild(lootChest2);
};
function openingChest() {
this.texture.frame = new PIXI.Rectangle(this.frameCycle*50, 0, 50, 50);
if (this.frameCycle === 3) {
clearInterval(this.opening);
} else {
this.frameCycle++;
};
};
function openChest() {
if (distance(Player.sprite.x, Player.sprite.y, this.x, this.y) < 50) {
if (this.closed) {
this.opening = setInterval(openingChest.bind(this), 100);
this.frameCycle = 1;
this.closed = false;
};
};
};
我有 2 个宝箱精灵,点击时打开,玩家靠近。现在我正试图找出一种有效的方法来创建其中的 50 个。继续制作我已经拥有的它们会有多糟糕,还有什么选择?
函数似乎是正确的想法。毕竟,您不想为每个箱子命名(lootChest1
..lootChest50
)。更不用说,你要确保你所有的箱子都是平等的。所以这样的东西应该运作良好。
function Chest(x, y) {
this.x = x;
this.y = y;
this.anchor.x = 0.5;
this.anchor.y = 0.7;
this.closed = true;
this.opening;
this.frameCycle = 0;
this.interactive = true;
this.hitArea = new PIXI.Circle(lootChest.x, lootChest.y, 10);
this.on('click', openChest);
}
// Have them "inherit" from PIXI.Sprite
Chest.prototype = new PIXI.Sprite(frame("images/chest.png", 0, 0, 50, 50));
// How to use it
var lootChest = new Chest(200, 200);
自从我与 PIXI 合作以来已经有一段时间了,所以我不记得这种继承风格是否适用于他们的渲染系统。如果没有,您可以将其设置为工厂函数。工厂函数看起来就像您创建第一个宝箱的方式(除了您希望将其分配给局部变量),然后从函数返回该宝箱。
编辑:工厂方法如下所示:
function createChest(x, y) {
var chest = new PIXI.Sprite(frame("images/chest.png", 0, 0, 50, 50));
chest.x = x;
chest.y = y;
chest.anchor.x = 0.5;
chest.anchor.y = 0.7;
chest.closed = true;
chest.opening;
chest.frameCycle = 0;
chest.interactive = true;
chest.hitArea = new PIXI.Circle(lootChest.x, lootChest.y, 10);
chest.on('click', openChest);
return chest;
}
// How to use it
var lootChest = createChest(200, 200);
我有一个如何从 PIXI 继承的例子。雪碧,但它有点复杂。这样做的方式是允许可配置性,因为它在游戏引擎中,但如果你确切地知道你想要你的对象是什么样子,上述任何一种方法都应该很好。
一定要使用OOP(面向对象编程)。您可以创建一个Chest
对象的数组,然后只修改构造函数和原型方法,而不是一丝不苟地遍历每一个箱子。
肖姆兹做对了。
然后,如果你想,比如说,为所有箱子设置动画,只需使用 for
循环遍历Chest
数组,并轻松地对所有箱子执行一些操作。
Mike C 举了一个很好的例子,但我想进一步扩展一些与 JavaScript 原型相关的陷阱。
Mozilla在原型继承和构造函数方面有一个很好的例子
但是,在利用原型时,需要记住一些重要的陷阱,我已在此代码笔中演示了这些陷阱。
请注意,对同一对象调用的相同方法在第二次调用时的行为实际上与第一次调用不同。这是因为该对象不存储对 move
函数的给定实现的引用,而是使用调用该对象时当前驻留在其原型上的那个。
代码运行时修改Shape.prototype.move
。这很可能永远不会发生,但如果它发生了(例如,如果团队中的另一位开发人员在运行时重新定义原型上的函数,而不知道已经存在一个同名的函数),它最终可能会导致一个很难追踪的错误。
JavaScript 中的原型可能是有用的工具,但我个人更喜欢使用工厂模式来避免难以捉摸的原型相关错误的可能性。
例:
function CreateShape(newX, newY) {
return {
x = newX,
y = newY,
move = function(addX, addY){
this.x += addX;
this.y += addY;
console.info('Shape moved.');
}
}
}
通过使用此模式,每次都会创建一个新对象,该对象不与任何其他对象共享原型,这意味着无论对其他 Shape 对象或任何原型进行何种修改,它的行为都将始终相同。
只是您考虑的替代方案。我希望这有帮助!
- 如何从构造函数中调用js原型方法
- 通过原型/构造函数从复选框输出值
- Javascript:继承原型而不重新定义构造函数
- 使用sinon.js创建一个“;“间谍对象”;使用基于真实构造函数/原型的间谍方法
- 使用构造函数 - 原型从文本框输出值
- JavaScript原型构造函数只调用过一次
- JavaScript 原型构造函数语法 1 与语法 2
- 构造函数属性值应该是什么 .a 原型构造函数或对象构造函数本身
- 什么是原型?构造函数或其他对象
- 在对象上正确设置原型构造函数
- 重构JavaScript原型构造函数中的重复代码
- 是否需要在经典继承中更改子类的“原型.构造函数”
- 将实例属性放置在原型构造函数中,无论好坏
- javascript原型构造函数和instanceof
- 正在原型构造函数中创建对象引用
- 在javascript的构造函数本身中获取原型构造函数的名称
- 原型构造函数和私有属性的区别
- 为什么原型构造函数中的变量在作为属性访问时未定义
- 如何在 Typescript 中实现无原型构造函数
- 如何为原型链中的构造函数找到根原型构造函数?