經過上面幾節的學習,慢慢的掌握了精靈的一些基本常識,可是咱們知道遊戲中游戲精靈都是富於表現能力的,而且經過不一樣的動做或者動畫去構造一個遊戲。ide
這篇文章將學習如何使用系列圖爲遊戲精靈添加動畫效果,如下面這一系列圖爲例,將其分割顯示:學習
--這個圖片是偷 深藍 的動畫
這是一張png圖片,咱們仍是須要把它加載到紋理圖形中,能夠考慮如何在精靈位圖上輪流得到獨立的精靈幀。如下編寫這個精靈幀所要先獲得的信息:this
- 精靈位圖中每一個單獨圖像(幀)的寬和高
- 精靈位圖的行與列的總數
- 指示接下來精靈位圖中將要繪製精靈幀在精靈位圖中所處的行與列的位置索引
上面的那張精靈位圖中,每一個單獨精靈幀的寬和高都是150像素,有10行1列。因此咱們要繪製它顯示在窗口上,就得從第一個精靈幀開始繪製。而這時候咱們就要編寫下面的三行代碼用來控制精靈幀的切換:spa
Point frameSize
=
new
Point(
150
,
150
);
//
每幀的長與高
Point currentFrame
=
new
Point(
0
,
0
);
//
初始化第一幀
Point sheetSize
=
new
Point(
10
,
1
);
//
定義一個10 列1行的point ,本圖片一共有一列10個小人
//
若是有多列則相應改動後面的1
上篇文章咱們有使用SpriteBatch.Draw 的重載方法,其中參數三是一個Rectangle 對象,上篇咱們不設置矩形範圍,因此給定一個NULL。而本便咱們須要使用一個 Rectangle 對象來算出該位置的源矩形。添加下面的代碼:code
spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);
spriteBatch.Draw(enemy,
//
紋理圖像
new
Vector2((graphics.GraphicsDevice.Viewport.Width
/
2
)
-
(frameSize.X
/
2
),
(graphics.GraphicsDevice.Viewport.Height
/
2
)
-
(frameSize.Y
/
2
)),
//
將系列圖放在屏幕中間播放
new
Rectangle(
currentFrame.X
*
frameSize.X,
//
當前的幀點的x 軸乘以每行移動的寬度獲得該矩形從屏幕哪一個座標畫
currentFrame.Y
*
frameSize.Y,
//
當前的幀點的Y 軸乘以每行移動的高度獲得該矩形從屏幕哪一個座標畫
frameSize.X,
//
須要畫該矩形塊的寬度爲系列圖每格小人物的寬度
frameSize.Y),
//
須要畫該矩形塊的高度爲系列圖每格小人物的高度
Color.White,
0
,
//
旋轉圖像,按角度旋轉圖像,0爲不旋轉,依次相似一、二、三、四、5等
Vector2.Zero,
//
指定旋轉的參照點
1
,
//
縮放比例,這裏是按默認比例綻開
SpriteEffects.None,
//
不翻轉圖像
0
//
紋理層深度
);
spriteBatch.End();
若是按照上面的代碼寫在Draw 裏面的話,仍是沒有動畫效果的,由於咱們一直重複的上面這張精靈位圖的第一幀,爲了產生動畫,還必須在Update 裏面完成狀態的更新:對象
++
currentFrame.X;
//
將下標要畫的X座標剃增,即改變該列的位置向下個位置轉移
if
(currentFrame.X
>=
sheetSize.X)
//
若是下標大於或者等於系列圖的當前列的數量
{
currentFrame.X
=
0
;
//
從新將下標初始化爲0
++
currentFrame.Y;
//
將將下標要畫的Y座標剃增,即改變該列的位置向下個位置轉移
if
(currentFrame.Y
>=
sheetSize.Y)
//
若是當前的要跳的行大於或等於該系列圖的總行數
{
currentFrame.Y
=
0
;
//
從新將其初始化爲0
}
}
這個時候,能夠ctrl+F5 運行遊戲,看看效果。blog
儘管遊戲看起來動畫效果不錯。但有沒有發現這個動畫的輪換速度也太快了,由於遊戲每秒更新30次狀態這個己經是很快的速度了。爲了使其可以按照咱們要求的速度進行精靈位圖切換,咱們能夠在Update 的時候作下小手腳,使其動畫速度爲可控狀態,看代碼:索引
int
timeSinceLastFrame
=
0
;
//
用來追蹤上一幀以後通過多少時間
int
millsecondPreFrame
=
100
;
//
用來指定在移動當前的幀索引以前想要等待的時間隔
修改後的Update 方法,應該是這樣子的:遊戲
protected
override
void
Update(GameTime gameTime)
{
//
Allows the game to exit
if
(GamePad.GetState(PlayerIndex.One).Buttons.Back
==
ButtonState.Pressed)
this
.Exit();
timeSinceLastFrame
+=
gameTime.ElapsedGameTime.Milliseconds;
//
每次累加遊戲的時間
if
(timeSinceLastFrame
>
millsecondPreFrame)
//
若是大於須要等待的時間
{
timeSinceLastFrame
-=
millsecondPreFrame;
//
從新加累加的時間初始化
++
currentFrame.X;
//
將下標要畫的X座標剃增,即改變該列的位置向下個位置轉移
if
(currentFrame.X
>=
sheetSize.X)
//
若是下標大於或者等於系列圖的當前列的數量
{
currentFrame.X
=
0
;
//
從新將下標初始化爲0
++
currentFrame.Y;
//
將將下標要畫的Y座標剃增,即改變該列的位置向下個位置轉移
if
(currentFrame.Y
>=
sheetSize.Y)
//
若是當前的要跳的行大於或等於該系列圖的總行數
{
currentFrame.Y
=
0
;
//
從新將其初始化爲0
}
}
}
//
TODO: Add your update logic here
base
.Update(gameTime);
}
這時,咱們再來看看這個效果:
下一篇將會學習到關於用戶輸入和碰撞檢測方面的知識。