天天看點

Silverlight C# 遊戲開發:自定義滑鼠(一)

我們在遊戲中經常應用自定義滑鼠來提升遊戲的畫面品質,一個好的遊戲怎麼能沒有好看的滑鼠呢,關于Silverlight的各種自定義滑鼠的方法很多,而我将為大家帶來的是在遊戲當中的應用效果,當然了,做法更加遊戲化,先看下圖:

<a target="_blank" href="http://blog.51cto.com/attachment/201111/122138363.jpg"></a>

我們期望達到的效果是,滑鼠移入不同的對象上顯示不同的滑鼠效果:

<a target="_blank" href="http://blog.51cto.com/attachment/201111/122149490.jpg"></a>

在其他的文章中曾經看到過一些做法,都是習慣将一個控件綁定到MainPage的MouseMove上,我所用做法也是一樣,但是較之更加“密封”一些,比如先建立一個CursorBase類(我是喜歡直接寫代碼,而不是用控件老搞定^_^):

public class CursorBase : Canvas  

{  

public CursorBase(FrameworkElement parent)  

parent.MouseMove += new MouseEventHandler(parent_MouseMove);  

parent.Cursor = Cursors.None;  

Canvas.SetZIndex(this, 9999);   

}  

//将父對象的滑鼠移動事件增加到這裡  

void parent_MouseMove(object sender, MouseEventArgs e)  

Point pt = e.GetPosition(sender as UIElement);  

X = pt.X;  

Y = pt.Y;  

//一套簡單的坐标控制  

public double X  

get { return Canvas.GetLeft(this); }  

set { Canvas.SetLeft(this, value); }  

public double Y  

get { return Canvas.GetTop(this); }  

set { Canvas.SetTop(this, value); }  

}   

這是一個自定義滑鼠的基本類,特别提一下構造函數添加的FrameworkElement,這是代表MainPage的父對象傳入,當然了,也可以傳入其他的元素做父對象,就要看你要将自定義滑鼠應用在什麼地方了。  

但是這隻是通過代碼寫一個控件而已,如果呈現這些圖檔呢,于是下面再寫一個控制類:  

Model控制類   

public class CursorControl : CursorBase  

public CursorControl(FrameworkElement parent)  

: base(parent)  

this.CacheMode = new BitmapCache();  

this.IsHitTestVisible = false;  

//添加一個滑鼠模型  

public void AddCursorModel(string name, FrameworkElement model)  

this.Children.Add(model);  

if (this.Children.Count != 1)  

model.Visibility = Visibility.Collapsed;  

else  

model.Visibility = Visibility.Visible;  

model.Name = name;  

//從圖檔添加滑鼠模型  

public void AddCursorModelFromImage(string name, Uri uri)  

AddCursorModel(name, new Image() { Source = new BitmapImage(uri) });  

//正在顯示的模型名字  

string ModelName = "預設";  

//獲得正在顯示的模型名字  

public string GetCursorModel()  

return ModelName;  

//設定要顯示的滑鼠模型  

public void SetCursorModel(string name)  

foreach (FrameworkElement item in this.Children)  

if (item.Name == name)  

item.Visibility = System.Windows.Visibility.Visible;  

ModelName = name;  

item.Visibility = System.Windows.Visibility.Collapsed;  

這次直接操作Children集合,通過外部添加的方式設定滑鼠的不同狀态和樣式,這個類更多意義是封裝了幾個方法,以友善我們達到更便捷的操作,通過AddCursorModel增加樣式模型,SetCursorModel設定樣式模式,在這個基礎上,可以使用狀态枚舉等方式,但是都需要這些方法來操作樣式,如果你需要Remove,那麼可以簡單的自己寫一個:)

這裡有一個特别需要提到的是關于IsHitTestVisible,是用來阻止自定義滑鼠的點選測試。

下一步,将圖檔添加到工程當中:

<a target="_blank" href="http://blog.51cto.com/attachment/201111/122205113.jpg"></a>

現在,我們寫一個MyCursor類,建構我們所需要的樣式的圖檔序列。

我的滑鼠

//我的滑鼠  

public class MyCursor : CursorControl  

public MyCursor(FrameworkElement parent)  

base.AddCursorModelFromImage("預設", new Uri(@"/CustomCursor01;component/Res/Cursor/" + 0 + ".png", UriKind.Relative));  

base.AddCursorModelFromImage("禁止", new Uri(@"/CustomCursor01;component/Res/Cursor/" + 1 + ".png", UriKind.Relative));  

base.AddCursorModelFromImage("攻擊", new Uri(@"/CustomCursor01;component/Res/Cursor/" + 2 + ".png", UriKind.Relative));  

base.AddCursorModelFromImage("魔法", new Uri(@"/CustomCursor01;component/Res/Cursor/" + 3 + ".png", UriKind.Relative));  

base.AddCursorModel("等待", new WaitCursor());  

ThisCursor = this;  

public static MyCursor ThisCursor = null;  

為了更加友善的控制自定義的滑鼠,增加了一個ThisCursor用來儲存最新的Cursor,我通常認為界面中隻有一個滑鼠,是以這樣做法更加直接明了,除非你使用了全局的控制方法:)

WaitCursor是一個UserControl,裡面加入了一些動畫和效果,并不是所有的滑鼠樣式都是圖檔,而我們的方法中提供了對控件的支援,關于WaitCursor控件請下載下傳源代碼自行檢視吧。

下一步就是如何控制它們,現在我需要布局元素,然後為他們起上名字分别叫Item01、Item02、Item03、Btn_ShowWait,當滑鼠移入的時候就可以直接通過ThisCursor來控制。

<a target="_blank" href="http://blog.51cto.com/attachment/201111/122220435.jpg"></a>

但是,我們怎麼能夠控制這些樣式,怎麼在正确的調用SetCursorModel呢,難點在滑鼠移入到一個元素,而不知道到底是什麼應該觸發什麼滑鼠的樣式,為了解決這個問題,我們需要借助Tag這個Silverlight特有的屬性。下面截選自Silverlight4.0的離線文檔。

于是,我們借助了一個小小的屬性來完成不可告人之目的,也有更加暴力的方法就是為每個對象都增加一個獨立處理的滑鼠事件,但是很不好,如果遊戲中的對象過多就不好辦了,是以,越精簡越封裝越好。

我隻需将MainPage.xaml寫成這樣:

&lt;Canvas x:Name="LayoutRoot"&gt; 

&lt;Image x:Name="Item01" Height="90" Canvas.Left="26" Source="Res/Item01.png" Stretch="Fill" Canvas.Top="18" Width="90"/&gt; 

&lt;Image x:Name="Item02" Height="96" Canvas.Left="263" Source="Res/Item02.png" Stretch="Fill" Canvas.Top="12" Width="51"/&gt; 

&lt;Image x:Name="Item03" Height="80" Canvas.Left="407" Source="Res/Item03.png" Stretch="Fill" Canvas.Top="24" Width="100"/&gt; 

&lt;Button x:Name="Btn_ShowWait" Content="動畫圖示" Height="35" Canvas.Left="40" Canvas.Top="152" Width="148"/&gt; 

&lt;/Canvas&gt; 

在背景的MainPage.cs添加和修改如下代碼:

MainPage.cs代碼

public partial class MainPage : UserControl  

public MainPage()  

InitializeComponent();  

InitializeMyPlace();  

LayoutRoot.Children.Insert(0,new Image() { Source = new BitmapImage(new Uri(@"/CustomCursor01;component/Res/map01.jpg", UriKind.Relative)) });  

LayoutRoot.Children.Add(new MyCursor(this));  

public void InitializeMyPlace()  

Item01.Tag = "攻擊";  

Item02.Tag = "魔法";  

Item03.Tag = "禁止";  

Item01.MouseEnter += new MouseEventHandler(Item_MouseEnter);  

Item02.MouseEnter += new MouseEventHandler(Item_MouseEnter);  

Item03.MouseEnter += new MouseEventHandler(Item_MouseEnter);  

Item01.MouseLeave += new MouseEventHandler(Item_MouseLeave);  

Item02.MouseLeave += new MouseEventHandler(Item_MouseLeave);  

Item03.MouseLeave += new MouseEventHandler(Item_MouseLeave);  

Btn_ShowWait.Click += new RoutedEventHandler(Btn_ShowWait_Click);  

void Btn_ShowWait_Click(object sender, RoutedEventArgs e)  

if (MyCursor.ThisCursor.GetCursorModel() == "等待")   

MyCursor.ThisCursor.SetCursorModel("預設");  

MyCursor.ThisCursor.SetCursorModel("等待");  

void Item_MouseEnter(object sender, MouseEventArgs e)  

MyCursor.ThisCursor.SetCursorModel((sender as FrameworkElement).Tag as string);  

void Item_MouseLeave(object sender, MouseEventArgs e)  

到此,我們可以基本上完成了遊戲中的自定義滑鼠的雛形開發工作,關于Tag可以使用自定義的結構體來帶入相關資訊,畢竟對象所需要的内容是很多的,在下個關于自定義滑鼠的文章中,我們一起研究一下拾取和拖拽的制作方法。

本文轉自nowpaper 51CTO部落格,原文連結:http://blog.51cto.com/nowpaper/712365