RPG游戏中的设计模式之单例模式

早就想写几篇设计模式相关的博客了,最近正好在举办“2015CSDN博文大赛”,就想写几篇设计模式相关的博客,复习设计模式的同时也想借此机会学习一下Markdown。结合以前写过的一个游戏,分析几个简单的设计模式:单例模式,策略模式和工厂方法模式。

游戏简介简介

游戏是一个非常简单的RPG小游戏,游戏中主要有两类角色,分别为Hero-英雄和Enemy-敌人(怪兽),英雄是由玩家控制的角色,怪兽是系统控制的角色,其中怪兽分为不同等级,有小怪和大怪,游戏内容比较简单,就是双方发射子弹攻击对方,如果怪兽将英雄的生命值打为0,游戏结束,如果英雄将最后的大怪生命值打为0,游戏胜利。

游戏使用C#实现,游戏的源码和资料我上传到CSDN上了,可以用下面的链接下载。建议大家事先下载下来,使用VS打开工程,然后结合代码看本文,能够使大家更好地理解文中的几个设计模式。 点击下载

界面演示

本来想做成GIF动画演示的,但是由于GIF文件比较大,上传不了,这里贴张图片,展示一下游戏的界面,大家可以下载源码运行,就可以看到整个游戏运行过程了。操作说明:”X”键发射子弹,方向键控制人物的移动

游戏整体结构

打开VS工程,打开其中的类图文件ClassDiagram1.cd,就可以看到整个游戏的类图了

游戏的类图如下

简单分析一下游戏的结构

HitCheck:游戏的主控类,用来控制游戏中所有元素 游戏详细的实现过程,读者可以看源码,结合类图看源码,相信读者很快就能非常清楚整个游戏了

下面的三个部分是游戏的核心

分析游戏的时候,要把握好这三块。 下面我们就结合这个小游戏,分析三种设计模式:单例模式,策略模式和工厂方法模式。

单例模式定义

确保一个类只有一个实例,并提供一个全局访问点。[1]P177(表示在参考文献[1]的177页,下同)

经典的单例模式实现public class Singleton {private static Singleton uniqueInstance;() {}public static Singleton GetInstance(){if (uniqueInstance == null){uniqueInstance = new Singleton();}return uniqueInstance;}// other useful methods here}

总结一下单例的实现就是:一个私有,两个静态

一个私有 就是私有构造函数

单例模式的思想就是一个类只有一个实例,即外部任何类都不能实例化该类,那么什么样的类外部不能实例化呢?我们知道,实例化一个类的时候,需要调用构造函数,而一般构造函数都是public的,所以能够被外部调用,所以能够在外部实例化,当将构造函数设置为private时,外部就不能调用类的构造函数了,也就不能实例化该类了,该类只能在类的内部实例化。这个思想是实现单例模式的关键。

两个静态: 1.静态成员变量uniqueInstance,该成员变量就是类的唯一实例 2.静态方法GetInstance(),用来获取该类的唯一实例

前面提到了使用私有构造函数是实现单例模式的关键,那么下面的问题就是怎么在外部获取该单例呢?由于任何外部类都不能实例化该类,所以我们无法通过使用类的对象来调用类里面的方法获取单例(即不能通过Singleton singleton=new Singleton();singleton.GetInstance()来获取单例),只能通过类里面的静态方法,通过类名调用静态方法(Singleton.GetInstance())来获取单例,而静态方法只能调用静态成员,所以类的成员变量也必须是静态的。

适用性

当一个类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。[2]P84 对有些类来说,只有一个实例很重要,如线程池,注册表,文件系统等 虽然全局变量也可以提供全局访问点,但是不能防止你实例化多个对象

游戏中的实现

类图文件中双击HitCheck类,就能看到代码,当然也可以在工程中直接打开HitCheck.cs

主控类,负责游戏中的各种角色的管理3.Draw()—-元素的绘制public class HitCheck{//游戏中的角色private Hero myHero = null;private List<MissileHero> missileHero = new List<MissileHero>();private List<Roles> enemy = new List<Roles>();private List<Missiles> enemyMissile = new List<Missiles>();private List<Element> bombs = new List<Element>();构造函数私有化,禁止在其他地方实例化() { }private static HitCheck instance;public static HitCheck GetInstance(){if (instance == null){instance = new HitCheck();}return instance;}… }

这个代码看上去是不是很熟悉,这就是个典型的单例模式的实现:一个私有,两个静态.

为什么要使用单例模式

刚开始写游戏的时候是没有用的,慢慢发现,游戏中的角色一旦过多,角色就很难管理,如角色的产生,角色的死亡,包括角色之间的碰撞检测。一旦游戏中要增加角色需要修改的代码很多,维护量比较大,所以就想设计一个类,实现对游戏中所有角色的管理,这样就可以很方便的对游戏中的角色进行管理。这个类主要控制游戏中的所有角色,包括对所有元素的增加,删除,以及碰撞检测(如英雄是否被敌人的子弹打中),这就要求该类只能有一个实例,不能有多个实例。不然游戏就会出错,所以设计为单例。读者分析一下HitCheck的源码就非常清楚其中使用单例的原因了。

多线程问题怠惰是贫穷的制造厂。

RPG游戏中的设计模式之单例模式

相关文章:

你感兴趣的文章:

标签云: