程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C#開發WPF/Silverlight動畫及游戲系列教程(Game Course):(二十五)(3)

C#開發WPF/Silverlight動畫及游戲系列教程(Game Course):(二十五)(3)

編輯:關於C語言

此方法的優點是精確,可以定位到精靈有效實體的任一像素角落;而缺點是只能在WPF中使用且性能不好,更麻煩的是必須將之放 Try{}Catch{}塊內使用,否則極易出錯,因為精靈的圖片切換太快了。

解決此問題的另一方式為通過定義精靈實體區域參數public double[] EfficaciousSection來實現,此方法也是我推薦使用的方法,兼顧WPF/Silverlight。

EfficaciousSection由4個數組成,以上圖為例,它的EfficaciousSection = new double []{80,125,50,145},其中第一個數字表示紅色區域左邊線距離圖片左的距離,第二個數字表示紅色區域右邊距離圖片左邊距離,第三個數字表示紅色區域上邊距離圖片頂部的距離,第四個數字代表紅色區域底邊距離圖片頂部的距離,上面所說的紅色區域即為精靈的有效實體區域,在後面的鼠標點擊或移動判斷中,只有當鼠標進入精靈的有效實體區域時我們才變換鼠標光標。

精靈獲得了有效實體區域,是否代表可以完美准確的捕捉精靈對象了呢?我們將窗體鼠標移動方法進行如下改進:

if (e.Source is QXSpirit) {

 QXSpirit Spirit = e.Source as QXSpirit;

 Point p = e.GetPosition(Spirit);

 if (p.X >= Spirit.EfficaciousSection[0] && p.X <= Spirit.EfficaciousSection[1]

  && p.Y >= Spirit.EfficaciousSection[2] && p.Y <= Spirit.EfficaciousSection[3]) {

  this.Cursor = Super.getCursor(1);

 } else {

  this.Cursor = Super.getCursor(0);

 }

}

然後再運行一下游戲,結果更奇怪的事情出現了:

如上圖,此時當鼠標停在主角身上時竟然沒有變換光標圖片,是代碼出問題了嗎?當然也不是。我們還是得從圖片上找原因。此時怪物的圖片遮擋住了主角,因此當鼠標懸停在主角身上時,系統卻仍然判斷當前捕獲的是“絕對無敵”,並且鼠標也未進入它的有效實體范圍,因此鼠標光標仍然是0號。

怎麼辦?搞了這麼久到頭來仍然是一場空。有朋友提出了將圖片裁剪成剛好包裹住精靈有效實體區域不就好了。想法是好的,但是將造成每一幀圖片都為不同尺寸規格,在動作中如何切換?每張圖片都得定義它距離容器Canvas左上角的距離,一個怪物幾百張圖片,每張都要定義,這將大大增加游戲的開發負擔。

難道沒有完美的解決方案了嗎?WPF/Silverlight中最不起眼但卻有著極其重要作用的神器登場了!對,就是它了:HitTest(命中測試)。

稱之為命中測試,不如叫它穿透點擊來得更形象些。因為它強大到只要游戲窗口中有的東西,它都能抓出來,想抓幾個抓幾個,想抓到什麼深度(Zindex)就抓到什麼深度;更甚者,它可以肢解封裝的控件直接抓取其內部任意對象控件;完成以上各種任務如若探囊取物搬輕盈且高效,僅僅是通過模擬鼠標點擊幾乎忽略不計的敏捷捕獲。關於HitTest的更多相關知識及原理請大家自行網上查閱,這裡不具體講解了。接下來我們看下圖:

在游戲中如何使用HitTest進行對象捕獲的原理在上圖中已經描述得非常清楚了,接下來看我如何通過代碼進行實現:

首先我定義一個精靈容器用於將捕獲到的所有精靈進行收容管理:

List<QXSpirit> SpiritList = new List<QXSpirit>();

接下來定義HitTest的過濾器HitFilter,用於篩選HitTest捕獲的對象,我們只需要捕獲QXSpirit類型對象即可,然後將之添加進精靈容器:

public HitTestFilterBehavior HitFilter(DependencyObject dObject) {

 if (dObject is QXSpirit) {

  SpiritList.Add(dObject as QXSpirit);

 }

 return HitTestFilterBehavior.Continue;

}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved