EaselJS图案 - 解释差异

3

我看过两个关于Easeljs的教程,一个是David Rousset的,另一个是Lee Brimelow的。我不确定哪一个更好,以及它们之间的区别是什么。以下是David Rousset的示例:

(function (window) {
function Player(imgPlayer, x_start, x_end) {
    this.initialize(imgPlayer, x_start, x_end);
}
Player.prototype = new createjs.BitmapAnimation();

// public properties:

Player.prototype.alive = true;

// constructor:
Player.prototype.BitmapAnimation_initialize = Player.prototype.initialize; //unique to avoid overiding base class

var quaterFrameSize;

Player.prototype.initialize = function (imgPlayer, x_end) {
    var localSpriteSheet = new createjs.SpriteSheet({
        images: [imgPlayer], //image to use
        frames: { width:64, height:64, regX:32, regY: 32 },
        animations: {
            walk: [0, 9, "walk", 4]
        }
    });

    createjs.SpriteSheetUtils.addFlippedFrames(localSpriteSheet, true, false, false);

    this.BitmapAnimation_initialize(localSpriteSheet);
    this.x_end = x_end;

    quaterFrameSize = this.spriteSheet.getFrame(0).rect.width / 4;

    // start playing the first sequence:
    this.gotoAndPlay("idle");     //animate
    this.isInIdleMode = true;

}

Player.prototype.tick = function () {
//specific tick function for the player
}

    window.Player = Player;
} (window));

并且示例2(Lee Brimelow):

(function(window) {

function Player(){


    // Adding the easeljs bitmap as a property of Player:       
    this.view = new createjs.Bitmap("assets/pics/player1.png")

    // Setting som local parameters
    var height          = stage.canvas.height;
    var width           = stage.canvas.width;
    var playerRadius            = 70;
    var offset          = 200;
    var x               = 0;
    var y                   = 0;

    this.view.regX = this.view.regY = playerRadius;

    // Adding the tickfunction below
    this.view.onTick    = tick;



}

function tick(e) {

//

}

window.Player = Player;
})(window);

请忽略一个使用BitmapAnimation而另一个只是基本的Bitmap。

在Example1中:

1)将以下行替换为相同吗:

Player.prototype.alive = true;

使用:

this.alive = true;

2) 以下术语含义是什么:

Player.prototype.BitmapAnimation_initialize = Player.prototype.initialize; //unique to avoid overiding base class

我不明白评论的意思...

3) 这行代码是否添加到初始化函数的开头:

Player.prototype = new createjs.BitmapAnimation();

我不确定在示例1中新建Player()时实际发生了什么。

4) 将tick作为Player的属性设置会导致你必须在主要的tick函数中调用此tick函数,使用easljs的内置onTick事件处理程序(如示例2中所做)是否更好?

上述模式中哪种是“最佳实践”,为什么?

此外,这两个模式都依赖于创建Player对象的main.js文件(并且Player对象被设置为window的属性)。为了避免全局范围内的影响或能够在像node.js这样的环境中使用此代码,将主要的main.js也包装成一个对象,并将此Main对象作为参数传递给函数,是否更好呢?

假设你制作了这个main js:

Main = {
init: function() {
    //set up and create Player
    var player = new Player;
},
//then adding som properties, variables to Main... for instance
propA: 0 
}

你认为这是否可行?


这是个人偏好问题。选择你理解和喜欢的一个并开始使用它。我投票关闭此问题,因为它太广泛了,答案主要是意见而不是具体事实。 - WiredPrairie
1个回答

4

两种方法的不同之处:

这两种方法通常(如果用于预期目的)并不用于同一目的。第一种模式是用于继承,而第二种模式是用于MVC(请搜索Model View Controller模式)。个人更喜欢第一个模式,因为EaselJS内部也使用了该模式,您可能需要在更大的项目中考虑MVC,而EaselJS应用程序(通常)则不需要。

另外:如果要利用MVC和继承,则最有可能在某些时候还必须使用第一种模式。我个人从未在JS / EaselJS项目中体验到MVC模式的任何优势(但是在其他大多数语言中都可以,但JS除外),但可能有很多人不同意这一观点,我同意他们在其他大多数语言中的观点。


回答你的其他问题:

  1. 不,它们不同。如果您将this.alive = true;编写到initialize方法中,则在代码运行时始终会得到相同的结果,但严格来说,即使这也与设置原型属性不同(但这涉及到JS内部功能)。

  2. Player类“继承”自BitmapAnimation,并且该模式(在此情况下还使用了EaselJS)提供了使每个类具有initialize-方法的功能。因此,在为Player定义initialize方法之前,将原始的initialize方法“保存”为BitmapAnimation_initialize,稍后从新的initialize方法中调用它,距离15行。

  3. 那行代码基本上是将BitmapAnimation的所有功能“注入”(或继承),以便在创建新Player时,您可以使用例如:myPlayer.gotoAndPlay('animation'),但实际上gotoAndPlay()BitmapAnimation中的一个方法。

  4. 确实,最好使用onTick..,如果对象是舞台的子元素,则会自动调用,而tick可能仍来自EaselJS的早期版本(虽然不太确定)。

最佳实践是哪种模式:

我认为对于EaselJS来说,第一种模式是最佳实践,因为这也是EaselJS自己的类使用的模式。(有一些小差异,如名称空间)。对于大型项目,您可能需要考虑MVC。


谢谢@olsn,非常好的答案。我对onTick和tick进行了更多的研究,并发现onTick已经被弃用,推荐使用"tick"事件。在将来的版本中将会被删除。我不知道为什么,这是一个很好的属性。至于问题1,我想把this.alive属性设置为Player对象的公共属性,而不是在initialize方法之外直接设置,但我猜这样行不通? - Øyvind
如果您将其设置在方法之外,它将成为“function(window){...}”的属性,因此根本没有任何影响,因为这是一个匿名函数,您以后将无法访问它。使用“.prototye.XXX”方式将使其成为“public”属性,因此当您创建玩家时,可以检查“myPlayer.isAlive”。还要注意,“public”和“private”不是JS当前自己支持的内容。 - olsn
第二个例子与MVC有什么关系?我只能看到是揭示模块模式。 - Bergi
严格来说,代码示例本身只是模拟了一个视图控制器模式,但很少有关于该模式的解释没有模型 - 这就是为什么我写了MVC,以免与谷歌搜索混淆 - 但它不是揭示模块模式,因为RMP是返回揭示对象的函数(例如:http://blog.alexanderdickson.com/javascript-revealing-module-pattern),第二个示例并没有这样做,第二个示例的任何属性都可以被认为是公共的。 - olsn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接