Silverlight小游戏系列之"打地鼠"

打地鼠成品:

Get Microsoft Silverlight

一、老鼠与洞

打地鼠这个游戏,玩法很简单.当地鼠钻出地洞的时候用锤子敲打它,打中就得分.

所以当考虑要写这么一个小游戏的时候,首先应该想到,要写一个"地洞".

于是我说:"要有洞". 结果就有了洞:

image

注意这个洞,这可不是一般的洞.它是一个很神奇的洞,那么它是怎么组成的呢?请看下期走进科学:老鼠与洞不得不说的故事.

哈哈,跑题了.

其实这个洞,是有两层的,为了实现老鼠从动里面钻出来的效果,必须得把这个洞分为两层.一层是上面的圆口,一层是下面的草地.如图:

image

下面的图层挡住老鼠,老鼠挡住洞口.钻出来的效果就是这么实现的:

image 

既然提到老鼠了,那么就不得不详细说一下.

老鼠这么个东西,实际上就是两张图片,正常情况下是这样:

image

被打中后是这样:

image 

 

 

 

好了,介绍完洞和老鼠,下面该说说怎样整合它们了.

首先明确一点,一个洞只能有一只老鼠.

所以,每个洞里面都包含一个老鼠对象

image

老鼠有进洞和出洞两种变化,但是老鼠这个对象也没有必要直接让游戏逻辑去调用.所以,洞也要有一个出洞的方法:

 

洞的出洞方法
public void OutHole() 

    mouse.OutHole(); 
    sbOutHole.Begin(); 

    DispatcherTimer dis 
= new DispatcherTimer(); 
    dis.Interval 
= TimeSpan.FromMilliseconds(1000); 
    dis.Tick 
+= new EventHandler(dis_Tick2); 
    dis.Start(); 
}

 

void dis_Tick2(object sender, EventArgs e) 

    var dis 
= sender as DispatcherTimer; 
    
if (!mouse.IsInjured) 
        sbInHole.Begin(); 
    dis.Stop(); 
    dis.Tick 
-= dis_Tick2; 
}

 

 

 

在洞的出洞方法里调用老鼠的出洞方法,老鼠的出洞方法实际上做了一个状态切换的操作,因为老鼠在出洞之前可能已经被打过一次了

 

public void OutHole() 

    
if (imgInjured.Visibility == Visibility.Collapsed) 
    { 
        imgNormal.Visibility 
= Visibility.Visible; 
    } 
    IsInjured 
= false
}

 

 

 

调用老鼠的出洞方法,就是把老鼠的状态置为正常.

回到洞的洞的出洞方法上,为了让游戏更具可玩性,老鼠出洞和进洞都需要一段平滑过渡的动画    sbOutHole.Begin(); 便是播放出洞动画.

老鼠不可能永远呆在洞的外面,所以在1000毫秒之后,让老鼠进洞.

当然,不是每一个老鼠都有那么幸运的,有些老鼠可能会被残忍的玩家无情的用锤子击中.这时老鼠为了配合玩家的残忍心理只能摆出一副无辜的受伤姿态啦.

 

老鼠的 EvInjured(被击中)事件和IsInjured(被击中)属性

 

老鼠的被击中事件和被击中属性
        public event Action EvInjured; 

        
public bool IsInjured { getprivate set; } 

        
public Mouse() 
        { 
            
// 为初始化变量所必需 
            InitializeComponent(); 
            imgNormal.MouseLeftButtonDown 
+= new MouseButtonEventHandler(imgNormal_MouseLeftButtonDown); 
            Cursor 
= Cursors.Hand; 
        } 

        
void imgNormal_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
        { 
            
if (EvInjured != null
                EvInjured(); 
        }

 

 

 

当老鼠被击中时,会触发EvInjured事件,老鼠所在的洞在初始化的时候就已经注册这个事件了:

 

洞注册老鼠的被击中事件
        public Hole() 
        { 
            
// 为初始化变量所必需 
            InitializeComponent(); 
            mouse.EvInjured 
+= new Action(mouse_EvInjured); 
            Loaded 
+= new RoutedEventHandler(Hole_Loaded); 
        }

        
void mouse_EvInjured() 
        { 
            Injured(); 
        } 

 

 

 

洞的被击中方法:

 

public void Injured() 

    mouse.Injured(); 
    sbInHole.Begin(); 
}

 

 

调用老鼠的Injured方法,然后播放老鼠进洞动画.

 

同样的,为了让游戏逻辑清晰明了,游戏逻辑只会调用洞的被击中方法而不会去理会老鼠的被击中方法:

 

老鼠的被击中方法
 public void Injured() 

    imgNormal.Visibility 
= Visibility.Collapsed; 
    imgInjured.Visibility 
= Visibility.Visible; 
    DispatcherTimer dis 
= new DispatcherTimer(); 
    dis.Tick 
+= new EventHandler(dis_Tick); 
    dis.Interval 
= TimeSpan.FromMilliseconds(500); 
    dis.Start(); 
    IsInjured 
= true


void dis_Tick(object sender, EventArgs e) 

    var dis 
= sender as DispatcherTimer; 
    dis.Tick 
-= dis_Tick; 
    dis.Stop(); 
    imgInjured.Visibility 
= Visibility.Collapsed; 
}

 

 

老鼠被击中的方法很简单,通过改变两张图片的可见性来表示当前的状态,然后在500毫秒之后让被击中的图片不可视,因为500毫秒后老鼠的进洞动画已经播放完成了.

好了,至此老鼠与洞的故事到这里就结束啦.

 

二、游戏主逻辑

有了老鼠与洞,还得有一段逻辑代码去控制他们.

规则:

关卡:随着玩家玩的时间变更,时间越长关卡越高,而游戏速度(地鼠出洞的速度)也随之增加

地鼠出洞:在固定的间隔时间里随机地洞的地鼠出洞.

 

首先把洞铺到一块草地上(草地是一张图片):

image

通过转换把后排的洞变小,这样更有立体感.

image 

界面写好后,可以开始写逻辑了.用迭代把界面里的洞找出来并添加到一个List:

 

初始化洞列表
void GameMain_Loaded(object sender, RoutedEventArgs e) 

    gameLoop.Tick 
+= new EventHandler(gameLoop_Tick); 
    gameLoop.Interval 
= TimeSpan.FromMilliseconds(currentSpeed); 
    
foreach (var uie in gridHoles.Children) 
    { 
        
if (uie is Hole) 
        { 
            var oneHole 
= uie as Hole; 
            holes.Add(oneHole); 
            oneHole.mouse.EvInjured 
+= new Action(mouse_EvInjured); 
        } 
    } 
    msInjured 
= new MouseSound("ResImg/MoleAttack/Sound/injured.mp3"); 

 

 

主循环:

 

主循环
void gameLoop_Tick(object sender, EventArgs e) 

    passedTime 
= DateTime.Now - startTime; 
    var passSeconds 
= passedTime.Minutes * 60 + passedTime.Seconds; 
    
if (passSeconds > 15 && passSeconds < 30
    { 
        infomation.tbLevel.Text 
= "2"
        CurrentSpeed 
= 2000
    } 
    
if (passSeconds > 30 && passSeconds < 60
    { 
        infomation.tbLevel.Text 
= "3"
        CurrentSpeed 
= 1500
    } 
    
if (passSeconds > 60 && passSeconds < 120
    { 
        infomation.tbLevel.Text 
= "4"
        CurrentSpeed 
= 1000
    } 
    
if (passSeconds > 120 && passSeconds < 240
    { 
        infomation.tbLevel.Text 
= "5"
        CurrentSpeed 
= 500
    } 
    
if (passSeconds > 240
    { 
        GameOver(); 
        gameLoop.Stop(); 
    } 
    holes[GetRandomNum(
0, holes.Count)].OutHole(); 

 

 

passedTime 用来记录玩家玩游戏的时间,因为关卡是通过这个时间来增加的.

一直到一个固定的时间后,GameOver.(游戏的玩法就是这样的,到点就结束,然后分数越高说明玩得越好).

关卡判断完成后,随机出一个洞来并让这个洞的老鼠出洞.

嗯,这就是主逻辑了,简单吧?

 

三、总结

还有一些细节方面的比如分数统计,关卡显示啥的就不必说太多了.

这款游戏几乎完全使用xaml编写,只用了少部分C#代码编写逻辑,由此可见xaml的强大之处.

如能灵活的用之,便可在游戏界面上节省很多时间.

嗯,本文只是抛砖引玉,希望能够有更多的.net开发者投入到Silverlight游戏开发行列中来.

源码:https://files.cnblogs.com/zhubenwuzui/MoleAttack.rar

posted @ 2010-07-15 16:49  猪笨无罪  阅读(6702)  评论(33编辑  收藏  举报