正文

游戲案例:GemDrops(7)

Windows移動(dòng)游戲開發(fā)實(shí)戰(zhàn) 作者:(美)Adam Dawes


 

程序清單8-6  渲染CObjGem類

/// <summary>

/// Draw the gem to the screen

/// </summary>

public override void Render(Graphics gfx, float interpFactor)

{

System.Drawing.Imaging.ImageAttributes imgAttributes;

base.Render(gfx, interpFactor);

// Create the transparency key for the gem graphics

imgAttributes = new System.Drawing.Imaging.ImageAttributes();

imgAttributes.SetColorKey(Color.Black, Color.Black);

// If this is not a rainbow gem...

if (_gemColor != CGemDropsGame.GEMCOLOR_RAINBOW)

{

// Then just draw its image

gfx.DrawImage(_game.GameGraphics["Gems"], GetRenderRectangle(interpFactor),

_gemColor * (int)Width, 0, (int)Width, (int)Height,

GraphicsUnit.Pixel, imgAttributes);

}

else

{

// This is a rainbow gem so we need to cycle its color.

// Add the elapsed time to our class variable

_rainbowGemUpdateTime += GameEngine.TimeSinceLastRender;

// Has 0.1 seconds elapsed?

if (_rainbowGemUpdateTime > 0.1f)

{

// Yes, so advance to the next color

_rainbowGemUpdateTime = 0;

_rainbowGemFrame += 1;

// If we reach the rainbow gem position (pass the final

// actual gem color), move back to the first

if (_rainbowGemFrame == CGemDropsGame.GEMCOLOR_RAINBOW) _rainbowGemFrame=0;

}

// Ensure the gem is considered as moved so that it re-renders in its 

// new color.

// This is important so that it still cycles when in the "next gem"

// display which isn't otherwise moving.

HasMoved = true;

// Draw its image

gfx.DrawImage(_game.GameGraphics["Gems"], GetRenderRectangle(interpFactor),

_rainbowGemFrame * (int)Width, 0, (int)Width, (int)Height,

GraphicsUnit.Pixel, imgAttributes);

}

}

寶石圖像的透明區(qū)域使用黑色背景,所以代碼中首先創(chuàng)建了一個(gè)ImageAttributes對(duì)象并指定黑色為顏色鍵,然后調(diào)用DrawImage函數(shù)來(lái)繪制該對(duì)象所代表的寶石。對(duì)于普通的寶石,我們要根據(jù)寶石顏色索引乘以寶石的寬度來(lái)計(jì)算出源圖像中需要選取的區(qū)域。這能夠索引寶石圖像,得到想要的顏色的寶石。

對(duì)于彩虹寶石,我們用_rainbowGemUpdateTime來(lái)累計(jì)上一次調(diào)用Render函數(shù)后所過(guò)去的時(shí)間,通過(guò)游戲引擎的TimeSinceLastRender屬性來(lái)得到該值。每當(dāng)該值累計(jì)達(dá)到0.1秒,我們就增加_rainbowGemFrame的值,并將_rainbowGemUpdateTime的值重置為0。通過(guò)修改時(shí)間上限(即用于同_rainbowGemUpdateTime進(jìn)行比較的值,在這里為0.1),我們可以使彩虹寶石按照我們想要的頻率來(lái)變換色彩。

CObjGem類還對(duì)基類中的一些屬性進(jìn)行了重寫:XPos、YPos、Width及Height屬性的get部分都被重寫了。這樣我們就可以根據(jù)自己的需要來(lái)計(jì)算這些屬性值,而不是對(duì)象每發(fā)生一點(diǎn)變化都要進(jìn)行更新。

對(duì)于XPos和YPos屬性,我們要利用在CGemDropsGame.Prepare函數(shù)中設(shè)置好的抽象坐標(biāo)系。通過(guò)初始化坐標(biāo)系時(shí)計(jì)算得到的BoardLeft值和BoardTop值來(lái)計(jì)算位置。函數(shù)把寶石的寬和高乘到這些值上。這里不包含絕對(duì)坐標(biāo)和硬編碼的坐標(biāo)。這個(gè)簡(jiǎn)單的方法能夠保證在所有支持的屏幕分辨率上游戲都能正確地顯示。

對(duì)于Width屬性和Height屬性,只需要通過(guò)CGemDropsGame對(duì)象就可以得到寶石的尺寸。同樣,這些值也是在調(diào)用Prepare方法時(shí)就計(jì)算好的。如果手機(jī)方向改變,導(dǎo)致加載另一套圖形集(因此寶石的Width和Height屬性會(huì)改變),那么這樣可以確保這兩個(gè)屬性值始終能返回正確的值,而不需要通知發(fā)生了變化。

游戲引擎會(huì)用到所有這4個(gè)屬性的重寫版本,它們可以很方便地為游戲?qū)ο筇峁┧璧闹?,這些屬性的代碼如程序清單。


上一章目錄下一章

Copyright ? 讀書網(wǎng) m.ranfinancial.com 2005-2020, All Rights Reserved.
鄂ICP備15019699號(hào) 鄂公網(wǎng)安備 42010302001612號(hào)