扩展javascript对象

扩展javascript对象,javascript,html,html5-canvas,Javascript,Html,Html5 Canvas,我目前正在使用javascript和HTML5画布开发一个平台游戏引擎 我有一个物体,“平台”看起来像这样 var platform = function(pid,px,py,pw,ph) { //Some variables here... and then we have some functions this.step = function() { //Update / step events here } this.draw = function() {

我目前正在使用javascript和HTML5画布开发一个平台游戏引擎

我有一个物体,“平台”看起来像这样

var platform = function(pid,px,py,pw,ph) {
  //Some variables here... and then we have some functions    
  this.step = function() {
    //Update / step events here
  }
  this.draw = function() {
    //Drawing events here
  }
  //etc.
}
platforms.push(new platform(i,data[1],data[2],data[3],data[4]));
当draw()函数绘制平台时,step()函数具有碰撞检测的所有计算

我想做的是制作另一个叫做movingPlatform的对象。这将几乎与当前平台相同,只是这一个移动

我不想复制所有的碰撞检测代码,而是希望能够从平台扩展movingPlatform。。。然后能够添加一些额外的代码到step()函数中,移动平台可以。。。好。。。移动

一些附加信息

当游戏加载时,它使用CSV文件中的数据生成关卡。我有一个数组,platforms[]存储其中的所有平台

所以要创建一个平台,它看起来像这样

var platform = function(pid,px,py,pw,ph) {
  //Some variables here... and then we have some functions    
  this.step = function() {
    //Update / step events here
  }
  this.draw = function() {
    //Drawing events here
  }
  //etc.
}
platforms.push(new platform(i,data[1],data[2],data[3],data[4]));
然后,我让平台在游戏的主要步骤和绘图事件中执行步骤和绘图事件

i、 e


for(var i=0;i我将使用平台类作为移动平台对象的“基本”对象。
我将通过原型来实现这一点,原型是JavaScript对面向对象编程的实现

更多信息请点击这里
+更多关于web的文章

您可以使用Javascript原型继承功能:

var baseItem = {
    push: function(){alert('push');},
    pull: function(){alert('pull')}
}

var childItem = {}
childItem.prototype = baseItem;

childItem.push = function(){
    //call base function
    childItem.prototype.push.call(this);

    //do your custom stuff.
    alert('I did it again.');
}

childItem.push();

如果您习惯使用基于类的语言,那么在Javascript中正确继承有些棘手

如果您没有共享很多行为,您可能会发现创建一些共享方法更容易,然后使它们可用于每种平台类型的对象

//Create constructors for each type
var Platform = function(pid,px,py,pw,ph) { //By convention, constructors should start with an uppercase character
    ...
}

var MovingPlatform = function() {
    ...
}

//Create some reuseable methods
var step = function() {
    ...
}
var draw = function() {
    ...
}
var move = function() {
    ...
}

//Attach your methods to the prototypes for each constructor
Platform.prototype.step = step;
Platform.prototype.draw = draw;

MovingPlatform.prototype.step = step;
MovingPlatform.prototype.draw = draw;
MovingPlatform.prototype.move = move;

...etc

也就是说,如果你真的想建立一个合适的继承链,有很多文章可以帮助你:

而不是纯粹的继承,在这里,我将使用原型扩展,除非你建立一些大的、丑陋的工厂,只是为了说“移动平台”继承自“平台”从纯粹意义上讲,它并不是你所期望的那样

有一些担心(比如作弊),但是如果你的对象都完全基于
这个
,并且你对可能在控制台中进行黑客攻击的人没有意见,那么你真的不必担心太多

首先,了解您在
平台内所做的工作:

var MyObject = function (a) {
    this.property = a;
    this.method   = function (b) { this.property += b; };
};
每次创建一个新的
MyObject
,您都在创建一个全新版本的
.method
函数。
也就是说,如果您制作了10000份,那么该函数也将有10000份副本。
有时这是一件非常好和安全的事情。
这也可能是一件非常缓慢的事情

问题是,因为对象中的所有内容都在使用
this
,而且函数内部没有任何更改,所以创建新副本没有任何好处——只使用了额外的内存

……因此:

MyObject = function (a) {
    this.property = a;
};
MyObject.prototype.method = function (b) { this.property += b; };

var o = new MyObject(1);
o.method(2);
o.property; //3
当您调用
new X
,其中
X
在其原型上具有属性/方法时,这些属性/方法会在对象构造期间复制到对象上

这将与去:

var method = function (b) { this.property += b; },
    o = new MyObject(1);

o.method = method;
o.method(2);
o.property; // 3
除了不用自己动手做的额外工作之外。
这里的好处是每个对象使用相同的函数。
他们基本上将函数访问权交给他们的整个
this
,函数可以用它做任何事情

有一个陷阱:

var OtherObj = function (a, b) {
    var private_property = b,
        private_method = function () { return private_property; };

    this.public_property = a;
    this.unshared_method = function () { var private_value = private_method(); return private_value; };
};

OtherObj.prototype.public_method = function () {
    return private_property;
};

var obj = new OtherObj(1, "hidden");

obj.public_property;    // 1
obj.unshared_method(); // "hidden"
obj.public_method();  // err -- private_property doesn't exist
因此,假设您不太关心保持私有性,最简单的方法是创建可重用函数,该函数依赖于
this
,然后通过扩展将其提供给多个原型

// collision-handling
var testCollision   = function (target) { this./*...*/ },
    handleCollision = function (obj) { this./* ... */ };

// movement-handling
var movePlatform = function (x, y, elapsed) { this.x += this.speed.x*elapsed; /*...*/ };
// not really the cleanest timestep implementation, but it'll do for examples


var Platform = function (texture, x, y, w, h) {
        this.x = x;
        // ...
    },
    MovingPlatform = function (texture, x, y, w, h, speedX, speedY, etc) {
         this.etc = etc;//...
    }; 


Platform.prototype.testCollision   = testCollision;
Platform.prototype.handleCollision = handleCollision;

MovingPlatform.prototype. // both of the above, plus the movePlatform method
这是很多手工制作的。
这就是为什么不同库中的函数将
克隆
扩展
对象

var bunchOfComponents = {
    a : function () { },
    b : 32,
    c : { }
},

myObj = {};

copy(myObj, bunchOfComponents);

myObj.a();
myObj.b; //32

你的函数重用提高了,而手工编写正确的基于类的分层继承(带有虚拟重写、抽象和共享私有属性)的恐惧感也降低了。

阅读JavaScript中的“原型继承”。按照惯例,构造函数(即你用
new调用的那些函数)
)应该大写。@elclars prototype这可能不是正确的方法。至少,不是以真正的JS方式:
var platform\u instance=new platform(纹理、x、y、宽度、高度);MovingPlatform.prototype=platform\u instance;var mPlatform=new MovingPlatform()
。它们都将具有相同的纹理、坐标等。扩展对象构造函数的原型,如果您可以确保所有相关对象属性都是公共的,当然,这是一个很好的内存节约。但是“继承”通过使所有子实例共享单个父实例的原型是没有帮助的,这里。@elclars prototype用于函数,因为它们对于所有实例或稍后被实例隐藏的默认值都是相同的。要继承实例特定的值,可以执行以下操作:
function child(){parent.apply(这是参数)
关于原型、继承重写方法和调用super:这看起来可能是我要做的事情的最佳方法……我明天会尝试一下,谢谢!注意,这种方法通常更适合于向一组对象类型添加基本实用工具方法的情况在你有一个类型的层次结构之前,使用一个合适的继承链会更干净,因此花时间阅读它的工作原理会对你有好处。事实上,我鼓励你现在忽略我的答案,阅读其他答案中提供的链接,以及我答案底部的链接,然后再做决定。我给出的解决方案我很好用,也很容易掌握,但在将来很难扩展和维护,而且不能反映对象的逻辑层次结构。谢谢你的推荐和链接,我会查出来的。哈,谢谢这个很好的例子,它很好地清除了原型。或者只使用与co一起提供的原型