继续使用咱们的SmallGameLib开发!
这次我们做一个玩家通过鼠标控制一只老鼠,躲避来自四面八方的小虫的攻击。
若被小虫碰到,则Game Over。
整个游戏分为3个界面,
1。 难度选择
2。 游戏主界面
3。 GAMEOVER,给出得分和评价。
难度越大,则小虫越多。
首先导入我们的SmallGameLib的各个目录,修改Config下的GameStatus,根据我们的需求,修改如下:
public enum GameStatus
{
难度选择,
开始,
游戏中,
游戏结束,
}
游戏过程中一共有2种物体,一种是主角(也就是老鼠),一种虫子。
那么我们需要将这两者从 BaseObj 派生,分别完成其构造函数,帧逻辑函数。
然后,注意,我们这里需要在游戏中进行碰撞检测,所以我们还需要重载BaseObj的getMyBounderRect()方法,来给其指定碰撞检测盒。
在调试过程中,可以将对象的 BoundVisiable 属性设成 true来观测碰撞盒。效果如下图
getMyBounderRect指定的是针对物体左上角点的一个矩形框。
如何检测两物体相撞呢?很简单,首先可以通过物体的 getBounderRect方法获取其包围框的绝对位置(针对于整个画布的位置)
然后通过 MathTools 的IsHit方法判断是否相撞,
MathTools.IsHit( obj.getBounderRect(),mouser.getBounderRect() = true 则两者相撞
整个游戏采用一个层就够了,于是在Logic下新建Layer派生自BaseLayer。
下面写我们的Layer层逻辑。层逻辑实际分4步:
1。 向所属物体派发逻辑
2。 移除窗口外的物体
3。 随机在窗口四周生成小虫
4。 判断是否有小虫和老鼠相撞
如下所示:
public override void logic() { base.logic(); removeObjectsOutside(); //随机生成block if (objects.Count < MaxBlocks) { if (MathTools.IsProbEventHappen(MakeBlockFreq)) { AddObj(new Block()); } } checkGameOver(); } private void checkGameOver() { foreach (BaseObj obj in objects) { if (obj != mouser) { if( MathTools.IsHit( obj.getBounderRect(),mouser.getBounderRect() )) GameCore.Status(GameStatus.游戏结束); } } }
base类(BaseLayer)提供的 logic()即向所属物体派发逻辑, removeObjectsOutside方法可以移除窗口外的物体。
使用MathTools的IsProbEventHappen可以以一定概率发生事件。返回为true则发生,false不发生。
最后编写我们的游戏核心,派生自 GameEngine类,需要实现状态机以及界面调度。
GameCore.cs
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using GDE.SmallGameLib; namespace CatchMouse.Logic { public class GameCore : GameEngine { public GameCore(UserControl mainPage, Canvas rootCanvas, GameStatus startStatus) : base(mainPage, rootCanvas, startStatus) { } protected override void TickGameFrameLoop(object sender, EventArgs e) { switch (gameStatus) { case GameStatus.难度选择: GameCore.LoopStop(); (mainPage as MainPage).Cursor = Cursors.Arrow; (mainPage as MainPage).ResultCanvas.Visibility = Visibility.Collapsed; (mainPage as MainPage).HardSelect.Visibility = Visibility.Visible; break; case GameStatus.开始: (mainPage as MainPage).Cursor = Cursors.None; LoopStart(); Reset(); resetScore(); (mainPage as MainPage).HardSelect.Visibility = Visibility.Collapsed; Status(GameStatus.游戏中); break; case GameStatus.游戏中: layersLogic(); updateScore(); break; case GameStatus.游戏结束: GameCore.LoopStop(); (mainPage as MainPage).Cursor = Cursors.Arrow; (mainPage as MainPage).ScoreResult.Text = (mainPage as MainPage).Score.Text; long s = Int64.Parse((mainPage as MainPage).Score.Text); (mainPage as MainPage).Pingjia.Text = getResultInfo(s,Layer.level); (mainPage as MainPage).ResultCanvas.Visibility = Visibility.Visible; break; } } private void resetScore() { (mainPage as MainPage).Score.Text = "0"; } private void updateScore() { long s = Int64.Parse((mainPage as MainPage).Score.Text); s+=1; (mainPage as MainPage).Score.Text = s.ToString(); } private String getResultInfo(long score, GameLevel level) { switch (level) { case GameLevel.简单: if (score < 500) return "你太2了"; else if (score < 1000) return "很一般啦"; else return "下次别玩简单难度了"; case GameLevel.中等: if (score < 500) return "你还是去玩简单难度吧"; else if (score < 1000) return "很一般啦"; else return "去挑战一下变态难度吧"; case GameLevel.变态: if (score < 500) return "再接再厉!"; else if (score < 1000) return "不错!很厉害了"; else if (score < 1500) return "高手!"; else return "GOD LIKE!"; } return "???"; } } }
如何在屏幕四周生成点?
使用MathTools提供的RandomBorderPoint()方法,可以随机生成一个处于边框位置的点。
最后,提供试玩地址:
http://218.240.31.225:902/testsilverlight/catchmouse/
看看你在变态难度能坚持多久~