扩展javascript对象

时间:2013-09-20 03:39:41

标签: javascript html5 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() {
    //Drawing events here
  }
  //etc.
}

step()函数具有用于碰撞检测的所有计算,而draw()函数绘制平台。

我想做的是创建另一个名为movingPlatform的对象。除了这个移动之外,这几乎与当前平台完全相同。

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

一些其他信息......

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

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

platforms.push(new platform(i,data[1],data[2],data[3],data[4]));

然后我让平台执行他们的步骤并在游戏的主要步骤中绘制事件并绘制事件。

for(var i=0; i<platforms.length; i++) {
platforms[i].step();
}   

任何帮助都会很棒。谢谢!

4 个答案:

答案 0 :(得分:2)

我会将平台类用作&#34; base&#34;移动平台对象的对象。 我会通过JavaScript实现面向对象编程的原型来做到这一点。

此处有更多信息How does JavaScript .prototype work? +更多网上文章

答案 1 :(得分:0)

您可以使用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();

Fiddle

答案 2 :(得分:0)

如果你习惯使用基于类的语言,那么在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

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

答案 3 :(得分:0)

除了纯粹的继承,在这里,我会选择原型扩展,除非你建造一个大而丑陋的工厂,只是为了说“MovingPlatform”从纯粹意义上继承自“平台”,它不是真的是你期望的那样。

有一些顾虑(作弊,一个),但如果你的对象都完全基于this,并且你对可能在控制台中被黑客攻击的人感到满意,那么你真的没有不用担心。

首先,了解您在Platform内所做的事情:

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

每次制作新MyObject时,您都会创建.method功能的全新版本。
也就是说,如果你制作了10,000个,那么这个功能也会有10,000个副本 有时这是一件非常安全的事情 它也可能是一件很慢的事情。

问题是,因为对象中的所有内容都使用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 XX的原型上有属性/方法,那些属性/方法会在构造过程中被复制到对象上。

这与去:

相同
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

手动很多。
这就是为什么不同库中的函数将cloneextend个对象。

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

myObj = {};

copy(myObj, bunchOfComponents);

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

你的函数重用率上升了,而用手写虚拟覆盖,摘要和共享私有属性编写适当的基于类的层次结构继承的恐惧就会消失。