程序清單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ū)ο筇峁┧璧闹?,這些屬性的代碼如程序清單。