0

我目前正在使用 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 文件中的数据生成关卡。我有一个数组platforms[],它存储了其中的所有平台。

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

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

然后我让平台在游戏的主要步骤和绘制事件期间执行它们的步骤和绘制事件。

IE

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

任何帮助都是极好的。谢谢!

4

4 回答 4

2

我会将平台类用作移动平台对象的“基础”对象。我会通过原型来做​​到这一点,原型是 JavaScript 的面向对象编程的实现。

更多信息在这里JavaScript .prototype 如何工作? + 网络上的更多文章

于 2013-09-20T03:43:26.357 回答
0

You can use Javascript prototype inheritance functionality:

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

于 2013-09-20T03:51:37.103 回答
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

于 2013-09-20T04:01:36.387 回答
0

而不是纯粹的继承,在这里,我会使用原型扩展,除非你建立一些又大又丑的工厂,只是为了说“MovingPlatform”从“Platform”继承来纯粹意义上的,它不是你真正的会希望它是。

有一些问题(例如作弊),但如果您的对象完全基于this,并且您对可能在控制台中入侵的人感到满意,那么您真的不必担心太多。

首先,了解你在里面做什么Platform

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

每次你创建一个新的MyObject,你都在创建一个全新的.method函数版本。
也就是说,如果你制作 10,000 个这样的函数,也会有 10,000 个该函数的副本。
有时这是一件非常好的和安全的事情。
这也可能是一件非常缓慢的事情。

问题是,因为对象中的所有内容都在 using 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

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

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

myObj = {};

copy(myObj, bunchOfComponents);

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

你的函数重用上升了,而手动编写适当的基于类的分层继承、虚拟覆盖、抽象和共享私有属性的恐惧下降了。

于 2013-09-20T04:23:22.343 回答