2016-05-15 119 views
0

我正在製作一個小型馬里奧遊戲。手寫體精靈動畫

但我不知道如何動畫精靈。按照實施例,我有一個運行mario.gif文件(馬里奧未在GIF捉迷藏)

Click here for the mario picture.

圖片是60×20個像素。目前,這是我的代碼。

class Character { 

    public y_: number; 
    public x_: number; 
    public nFrames: number = 30; 

    constructor(public _x: number, public _y: number) { 
     this._x = _x; 
     this._y = _y; 
    }; 

sprite: HTMLImageElement; 

    setSpriteUrl(input: string) : void { 
     this.sprite = new Image(); 
     this.sprite.src = input; 
    } 

drawSprite(): void { 
     ctx.save(); 
     ctx.beginPath(); 
     ctx.drawImage(this.sprite, 0, 0, 15, 20, this._x, this._y, 20, 20); 
      ctx.restore; 
     } 
} 

var mario = new Character(40, 50); 
mario.setSpriteUrl("graphics/mario/small/Running-mario.gif"); 

畫面的寬度之後是60個像素,有4個運行馬里奧的圖像。圖片的高度也是20像素。
60/4 = 15

ctx.drawImage(this.sprite, 0, 0, 15, 20, this._x, this._y, 20, 20); 

這會讓我覺得它我可以從15到30,它會選擇下一個馬里奧的形象。相反,它讓我從圖片中跑出2個馬里奧。
它是如何工作的?如何選擇馬里奧的每個運行階段?


如果這樣做了,精靈應該用for循環和定時器來動畫嗎?對我來說,這似乎不是最好的做法..因爲我有更多的精靈動畫,然後只有馬里奧和跑步。

+0

考慮到你試圖在畫布上畫一個GIF,我想你的問題可能是這個問題的重複http://stackoverflow.com/questions/3062229/animated-gif-in-html5-canvas – toskv

+1

在這個問題中,這個人問起他的動畫gif。我的gif文件不是動畫,而是一幅普通的圖片(請參閱鏈接)。此人也可以回答圖書館。我不是在尋找一個圖書館,我想了解(教育目的) – Romano

+0

感謝您的澄清,我會收回我的近距離投票。 :) – toskv

回答

0
class Character { 

    frameWidth: number; 
    frameHeight: number; 
    tickCount: number; 
    ticksPerFrame: number = 1; 
    frameIndex: number; 
    jump: boolean; 

    constructor(public position: Vector, public numberOfFrames : number) {} 

    sprite: HTMLImageElement; 


    setSpriteUrl(input: string) : void { 
     this.sprite = new Image(); 
     this.sprite.src = input; 
    } 

    addGravity(): void { 

     this.position.y += downForce; 
     if (this.position.y >= 415) 
      this.position.y = 415; 
    } 

    drawSprite(): void { 

     this.tickCount = this.ticksPerFrame; 

     if (this.tickCount >= this.ticksPerFrame) { 
      this.tickCount = 0; 
      if (this.frameIndex < this.numberOfFrames - 1) { 
       this.frameIndex += 1; 
      } else { 
       this.frameIndex = 0; 
      } 
     } 

     this.frameHeight = this.sprite.height; 
     this.frameWidth = this.sprite.width/this.numberOfFrames; 

     this.position.setWidth(this.frameWidth); 
     this.position.getHeight(this.frameHeight); 
     ctx.drawImage(this.sprite, 
      this.frameIndex * this.frameWidth, 0, // Start of slice 
      this.frameWidth, this.frameHeight, // Size of slice 
      this.position.x, this.position.y, 15, 20); 
    } 

} 

通過使用精靈this.sprite.heightthis.sprite.width我可以有大小動態。這樣我可以加載任何精靈。

和設置馬里奧

var mario = new Character(new Vector(40,50), 4); 
mario.setSpriteUrl("graphics/mario/small/Standing-mario.gif"); 
mario.numberOfFrames = 1; 

numberOfFrames在這種情況下,只有1。由於站在馬里奧GIF只有1中它的畫面。

但是,如果馬里奧正在運行。

function keyboardInput(event: KeyboardEvent) { 


    switch (event.keyCode) { 
     case 65: case 37: //a 
      mario.setSpriteUrl("graphics/mario/small/Running-mario-left.gif"); 
      mario.numberOfFrames = 4; 
      mario.position.x -= 10; 
      break; 

     case 38: case 87: //w 
      mario.numberOfFrames = 1; 
      mario.setSpriteUrl("graphics/mario/small/Jumping-mario.gif"); 
      if(mario.position.y < 415) { 
       return false; 
      } 
      mario.position.y -= 30; 
      break; 
     case 39: case 68: //d 
      mario.setSpriteUrl("graphics/mario/small/Running-mario.gif"); 
      mario.numberOfFrames = 4; 
      mario.position.x += 10; 
      break; 
     case 40: case 83: //s 
      mario.position.y += 20; 
      break; 
     case 32: //space 
      break; 
     default: 
      mario.setSpriteUrl("graphics/mario/small/Standing-mario.gif"); 
      mario.numberOfFrames = 1; 
      break;  
    } 

} 

如果馬里奧正在運行,則使用另一個幀數。運行馬里奧在gif內有4張圖片。製作數字幀4.

0

drawImage簽名是

ctx.drawImage(image, dx, dy) 
ctx.drawImage(image, dx, dy, dWidth, dHeight) 
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy) 
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) 

(sx, sy)是從哪裏開始複印的源圖像中的切片的開始位置。 (sWidth × sHeight)是該切片的大小。

由於你的精靈幀是水平的,所以你需要增加sx的值來繪製下一幀。

class Character { 

    frameWidth: number = 15; 
    frameHeight: number = 20; 

    constructor(
     public x: number, 
     public y: number) { } 

    sprite: HTMLImageElement; 

    setSpriteUrl(input: string) : void { 
     this.sprite = new Image(); 
     this.sprite.src = input; 
    } 

    drawSprite(frameIndex: number): void { 
     ctx.save(); 
     ctx.beginPath(); 
     ctx.drawImage(this.sprite, 
      frameIndex * this.frameWidth, 0, // Start of slice 
      this.frameWidth, this.frameHeight, // Size of slice 
      this.x, this.y);     // Destination position 
     ctx.restore(); 
    } 
} 
+0

函數'drawSprite'中的'ctx.save','beginPath'和'restore'函數沒有做任何事情,並且在函數的任務方面是重用的。這些函數可能會增加相當大的開銷,這在某些情況下會比調用drawImage要長很多。 – Blindman67

+0

謝謝!這幫了很多。我得到了動畫的工作。我會將其作爲最終答案發布。謝謝您的幫助 – Romano