Silverlight C# 游戏开发:自定义鼠标(一)

我们在游戏中经常应用自定义鼠标来提升游戏的画面品质,一个好的游戏怎么能没有好看的鼠标呢,关于Silverlight的各种自定义鼠标的方法很多,而我将为大家带来的是在游戏当中的应用效果,当然了,做法更加游戏化,先看下图:

Silverlight C# 游戏开发:自定义鼠标(一)

我们期望达到的效果是,鼠标移入不同的对象上显示不同的鼠标效果:

Silverlight C# 游戏开发:自定义鼠标(一)

在其他的文章中曾经看到过一些做法,都是习惯将一个控件绑定到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;
            }
            
else
                item.Visibility 
=  System.Windows.Visibility.Collapsed;
        }
            
    }
}

 

这次直接操作Children集合,通过外部添加的方式设置鼠标的不同状态和样式,这个类更多意义是封装了几个方法,以方便我们达到更便捷的操作,通过AddCursorModel增加样式模型,SetCursorModel设置样式模式,在这个基础上,可以使用状态枚举等方式,但是都需要这些方法来操作样式,如果你需要Remove,那么可以简单的自己写一个:)

这里有一个特别需要提到的是关于IsHitTestVisible,是用来阻止自定义鼠标的点击测试。

下一步,将图片添加到工程当中:

Silverlight C# 游戏开发:自定义鼠标(一)

现在,我们写一个MyCursor类,构建我们所需要的样式的图片序列。

我的鼠标
// 我的鼠标
public   class  MyCursor : CursorControl
{
    
public  MyCursor(FrameworkElement parent)
        : 
base (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来控制。

Silverlight C# 游戏开发:自定义鼠标(一)

但是,我们怎么能够控制这些样式,怎么在正确的调用SetCursorModel呢,难点在鼠标移入到一个元素,而不知道到底是什么应该触发什么鼠标的样式,为了解决这个问题,我们需要借助Tag这个Silverlight特有的属性。下面截选自Silverlight4.0的离线文档。

Silverlight C# 游戏开发:自定义鼠标(一)

于是,我们借助了一个小小的属性来完成不可告人之目的,也有更加暴力的方法就是为每个对象都增加一个独立处理的鼠标事件,但是很不好,如果游戏中的对象过多就不好办了,所以,越精简越封装越好。

我只需将MainPage.xaml写成这样:

< Canvas x:Name = " LayoutRoot " >
        
< Image x:Name = " Item01 "  Height = " 90 "  Canvas.Left = " 26 "  Source = " Res/Item01.png "  Stretch = " Fill "  Canvas.Top = " 18 "  Width = " 90 " />
        
< Image x:Name = " Item02 "  Height = " 96 "  Canvas.Left = " 263 "  Source = " Res/Item02.png "  Stretch = " Fill "  Canvas.Top = " 12 "  Width = " 51 " />
        
< Image x:Name = " Item03 "  Height = " 80 "  Canvas.Left = " 407 "  Source = " Res/Item03.png "  Stretch = " Fill "  Canvas.Top = " 24 "  Width = " 100 " />
        
< Button x:Name = " Btn_ShowWait "  Content = " 动画图标 "  Height = " 35 "  Canvas.Left = " 40 "  Canvas.Top = " 152 "  Width = " 148 " />
    
</ Canvas >

 

在后台的MainPage.cs添加和修改如下代码:

MainPage.cs代码
public   partial   class  MainPage : UserControl
{
    
public  MainPage()
    {
        InitializeComponent();
        InitializeMyPlace();
        
this .CacheMode  =   new  BitmapCache();
        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(
" 默认 " );
        
else
            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)
    {
        MyCursor.ThisCursor.SetCursorModel(
" 默认 " );
    }
}

还有一个WaitCursor控件,请直接看源代码吧,源代码下载如下:点击这里下载

现在运行效果看看怎么样呢,鼠标在上面移动看看:

获取 Microsoft Silverlight

到此,我们可以基本上完成了游戏中的自定义鼠标的雏形开发工作,关于Tag可以使用自定义的结构体来带入相关信息,毕竟对象所需要的内容是很多的,在下个关于自定义鼠标的文章中,我们一起研究一下拾取和拖拽的制作方法。

推荐Silverlight游戏开发博客:深蓝色右手

你可能感兴趣的:(silverlight)