程序清單4-18 ClipRegion可視化調試代碼
// Debug: draw a rectangle around the clip area so we can see what we have
// redrawn
using (Pen p = new Pen(Color.Blue))
{
backGfx.DrawRectangle(p, renderRect.X, renderRect.Y,
renderRect.Width - 1, renderRect.Height - 1);
}
運行Bounce項目時啟用該代碼,屏幕上的顯示效果如圖4-6所示。
當前繪制矩形后面的方框痕跡顯示了每一幀中的ClipRegion。由于我們只對移動區(qū)域進行更新,因此舊的繪制區(qū)域在屏幕的后面形成了一條軌跡。這可以讓我們很容易地看到在游戲運行時對哪些區(qū)域進行了繪制。
4.4.1 添加、更新和刪除對象
有三個進一步的操作可以影響到移動區(qū)域,但與對象的移動并不直接相關:即添加新對象、刪除已有對象、更新靜態(tài)對象的圖。
添加一個新對象時,即使它是完全靜止的,還是需要對它進行渲染,否則它會保持不可見直到落入到移動矩形區(qū)域中。因此,我們需要在每個對象被創(chuàng)建時在其內部設置一個名為IsNew的標志,任何設置了該標志的對象都將被包含到累加的移動矩形區(qū)域中,而不用考慮它們坐標的變化。
對象生命周期的另一個端點是終止。當一個對象不再被需要時,我們需要對屏幕區(qū)域進行重繪,使該對象從畫面中消失。因此我們需要使用一個Terminate標志,在本章中已經多次提到了它。被標記為終止的對象不會被重繪,但它們仍被認為是屬于移動矩形區(qū)域的。處理完畢后,使用RemoveTerminatedObjects函數將它們從游戲對象列表中刪除。
任何沒有使用Terminate標志但被直接從列表中刪除了的對象將仍然留在屏幕的后面,直到移動矩形將它們完全擦除掉,所以,在終止對象時要記得使用這種方法。
CGameObjectGDIBase包含了Check If Moved函數,游戲的每一步運行都會由引擎來調用該函數。該函數根據條件來查找需要進行重繪的對象(發(fā)生移動的對象、新對象或終止對象)。如果發(fā)現匹配的對象,就將其HasMoved屬性設置為true。然后在下一次調用Render函數時設置它。
最后,我們會碰到這種情形:對象的圖像被修改了,但位置并沒有發(fā)生改變。在這種情況下,需要對它進行重繪才能使用戶看到新圖像,但就我們目前所描述的條件來看,這種情況不會發(fā)生,因為對象都不是新對象,也沒有被終止且沒有發(fā)生移動。
在這種情形下,我們可以將對象的HasMoved屬性設置為true,強制對其進行重繪。當下一次調用Render函數時,該函數會查看該標志是否被設置,如果設置了,那么不論其他的屬性值如何發(fā)生變化,對象都會被重繪。