2014-10-20 82 views
-1

我创建了一个Sprite类,然后从Sprite类派生出一个Dragon类。我正在尝试将操作方法​​添加到龙类中,但它不起作用。我以与将Sprite.prototype添加到Sprite类的方法相同的方式将操作方法​​添加到Dragon.prototype中,但是如果我创建了Dragon类的实例,则无法调用操作方法I在Dragon原型中定义。添加方法到原型

如果我将Dragon.prototype.action更改为Sprite.prototype.action,则代码完美工作。对于这个例子,这并不重要,但我希望能够为以后的特定类设置方法。我究竟做错了什么?我应该只是解决更多的方法名称?如果答案很明显,我表示歉意,并感谢您的帮助。

var Sprite = function(spriteSheet, rows, columns, x, y, width, height){ 
    this.frameSpeed = 1; 
    this.spriteSheet = spriteSheet; 
//The starting Location 
    this.x = x; 
    this.y = y; 
//The width and height of the sprite 
    this.width = width; 
    this.height = height; 
//Variables for movement 
    this.xSpeed = 0; 
    this.ySpeed = 0; 
//rows and columns of our spritesheet 
    this.rows = rows; 
    this.columns = columns; 
//our variables needed to animate the sprite. 
    this.sourceWidth = this.spriteSheet.width/this.columns; 
    this.sourceHeight = this.spriteSheet.height/this.rows; 
    this.sourceX = 0; 
    this.sourceY = 0; 
    this.frameCount = this.rows * this.columns; 
    this.currentFrame = 0; 
} 

Sprite.prototype.update = function(){ 

    this.y+=this.ySpeed; 
    this.x+= this.xSpeed; 

    if(this.currentFrame >= this.frameCount){ 
     this.currentFrame = 0; 
    } 

    this.row = Math.floor(this.currentFrame/this.columns); 
    this.column = Math.floor(this.currentFrame % this.columns); 

    this.currentFrame+=this.frameSpeed; 
    this.sourceX = this.column * this.sourceWidth; 
    this.sourceY = this.row * this.sourceHeight; 

} 

Sprite.prototype.draw = function(){ 
    context.drawImage(this.spriteSheet, this.sourceX, this.sourceY, this.sourceWidth, this.sourceHeight, this.x, this.y, this.width, this.height); 
} 

var mySprite = new Sprite(smiley,4,4,100,50,100,100); 

var Dragon = function(x, y, width, height){ 
    var dragon = new Sprite(dragonSheet,4,3,x,y, width,height); 
    dragon.frameSpeed = .5; 
    dragon.xSpeed = 4; 
    return dragon; 
} 

Dragon.prototype.action = function(){ 
    if(this.x>500){ 
     this.x = -100; 
    } 
} 

var dragon1 = new Dragon(70,170,80,50); 
+2

什么问题? – Mathletics 2014-10-20 20:09:18

+0

为什么在将Dragon.prototype.action更改为Sprite.prototype.action时不起作用? – 2014-10-20 20:12:23

回答

2

相反你Sprite构造函数中,Dragon功能确实return的对象 - 因此不再是一个构造函数,但仅仅工厂函数。它创建并返回一个Sprite instace,它将从Sprite.prototype继承,而不是从Dragon.prototype继承。详情请参阅What is the 'new' keyword in JavaScript?

要解决此问题,请使用Dragon作为构造函数。 this将成为该实例,并在赋予它特定于龙的属性之前初始化它,并在其上面初始化.call()Sprite函数。新创建的实例将从Dragon.prototype继承。

要正确设置了原型链,你需要Dragon.prototype继承Sprite.prototype - 让一切创造Dragon情况下,将有Sprite方法,以及像here

function Dragon(x, y, width, height) { 
    Sprite.call(this, dragonSheet, 4, 3, x, y, width, height); 
    this.frameSpeed = .5; 
    this.xSpeed = 4; 
} 
Dragon.prototype = Object.create(Sprite.prototype); 
Dragon.prototype.constructor = Dragon; 

Dragon.prototype.action = …; 

var dragon1 = new Dragon(70,170,80,50); 
+0

你介意给我看一个使用Dragon作为构造函数的例子吗? – 2014-10-20 20:15:32

+0

非常感谢。这完全解决了问题。 – 2014-10-20 20:40:08

0

的原因,当你这样做Dragon.prototype.action不叫:

var d = new Dragon(...); 
d.action(); // won't work 

是因为你是选择从Dragon构造函数返回,而不是使用this新创建Sprite对象,在与new联系时,将为您设置一个新的Dragon实例。因为你明确使用new来调用构造函数Sprint,然后返回该对象,所以该对象已经被设置为Sprite的原型(并且不知道Dragon的任何内容)。

有几种方法可以做到继承在JavaScript,但我觉得你的情况,你可以只改变你Dragon构造函数调用Sprite这一明确指定,而不是它充当新龙对象上脱身:

var Dragon = function(x, y, width, height){ 
    Sprite.call(this, dragonSheet,4,3,x,y, width,height); // act on `this` 
    this.frameSpeed = .5; 
    this.xSpeed = 4; 
    // 'return this' is implied for constructors 
}