一、背景描述
牧师与魔鬼是一款益智游戏,您将帮助牧师与魔鬼在规定时间内过河。河边有三个牧师和三个魔鬼。他们都想去这条河的对岸,但只有一艘船,这艘船每次只能载两个人。而且必须有一个人把船从一边开到另一边。在flash游戏中,您可以单击它们移动它们,然后单击go按钮将船移动到另一个方向。如果神父的人数超过了河两边的魔鬼,他们就会被杀死,游戏就结束了。你可以用很多方法来尝试。让所有牧师都活着!祝你好运!
(图片来源:百度百科)
二、MVC设计模式
MVC设计模式是一种软件架构模式,它将软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。模型负责封装与业务逻辑相关的数据和方法,视图负责显示模型的数据,控制器负责处理用户的请求和更新模型和视图。MVC设计模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。MVC设计模式也有利于提高程序的可测试性、可维护性和可扩展性。
三、项目介绍
1、对象
对象 | 数量 |
---|---|
牧师 | 3 |
魔鬼 | 3 |
船 | 1 |
陆地 | 2 |
河流 | 1 |
2、动作
动作 | 条件 | 效果 |
---|---|---|
玩家点击岸上角色 | 船上有空位 | 角色上船 |
玩家点击船上角色 | 角色上岸 | |
玩家点击船 | 船上有至少一个角色 | 开船 |
玩家点击restart | 重新开始游戏 |
3、代码
4、项目展示
5、实现过程
(1)Director
public class Director : System.Object {
private static Director _instance;
public SceneController currentSceneController { get; set; }
public static Director getInstance() {
if (_instance == null) {
_instance = new Director ();
}
return _instance;
}
}
这段代码是用C#语言实现的单例模式(Singleton Pattern)的一个例子。单例模式是一种创建型设计模式,它保证一个类只有一个实例,并提供一个全局访问点。
这段代码定义了一个名为Director的类,它有以下特点:
- 它有一个私有的静态字段_instance,用来存储唯一的实例。
- 它有一个私有的无参构造函数,防止其他类通过new关键字创建它的实例。
- 它有一个公共的静态方法getInstance,用来获取或创建唯一的实例。如果_instance为空,就创建一个新的Director对象并赋值给它;如果不为空,就直接返回它。
- 它有一个公共的属性currentSceneController,用来设置或获取当前的场景控制器。
(2)Controller:代码
这段代码定义了一个名为FirstController的类,它继承了MonoBehaviour类,并实现了SceneController和UserAction两个接口。它有以下特点:
public CoastController fromCoast;
public CoastController toCoast;
public BoatController boat;
private MyCharacterController[] characters;
它有一个常量water_pos,用来表示水面的位置。
它有一个UserGUI类型的字段userGUI,用来显示用户界面。
它有两个CoastController类型的字段fromCoast和toCoast,分别表示起始岸和目标岸。
它有一个BoatController类型的字段boat,表示船。
它有一个MyCharacterController类型的数组characters,用来存储六个角色对象(三个牧师和三个魔鬼)。
void Awake() {
Director director = Director.getInstance ();
director.currentSceneController = this;
userGUI = gameObject.AddComponent <UserGUI>() as UserGUI;
characters = new MyCharacterController[6];
loadResources ();
}
重写了Awake方法,在该方法中获取Director单例对象,并将自己设置为当前的场景控制器。然后添加UserGUI组件,并初始化characters数组。最后调用loadResources方法加载资源。
public void loadResources() {
GameObject water = Instantiate (Resources.Load ("Perfabs/Water", typeof(GameObject)), water_pos, Quaternion.identity, null) as GameObject;
water.name = "water";
fromCoast = new CoastController ("from");
toCoast = new CoastController ("to");
boat = new BoatController ();
loadCharacter ();
}
实现了loadResources方法,在该方法中实例化水面对象,并给它命名为"water"。然后创建fromCoast、toCoast和boat对象,并调用loadCharacter方法加载角色对象。
private void loadCharacter() {
for (int i = 0; i < 3; i++) {
MyCharacterController cha = new MyCharacterController ("priest");
cha.setName("priest" + i);
cha.setPosition (fromCoast.getEmptyPosition ());
cha.getOnCoast (fromCoast);
fromCoast.getOnCoast (cha);
characters [i] = cha;
}
for (int i = 0; i < 3; i++) {
MyCharacterController cha = new MyCharacterController ("devil");
cha.setName("devil" + i);
cha.setPosition (fromCoast.getEmptyPosition ());
cha.getOnCoast (fromCoast);
fromCoast.getOnCoast (cha);
characters [i+3] = cha;
}
}
实现了loadCharacter方法,在该方法中循环创建三个牧师和三个魔鬼对象,并给它们命名为"priest0"到"priest2"和"devil0"到"devil2"。然后将它们放置在fromCoast的空位上,并让它们上岸。同时将它们添加到fromCoast和characters数组中。
public void moveBoat() {
if (userGUI.status != 0 ) return;
if (boat.isEmpty ())
return;
boat.Move ();
userGUI.status = check_game_over ();
}
实现了moveBoat方法,在该方法中判断游戏状态是否为0(未结束),如果不是则返回。然后判断船是否为空,如果是则返回。否则调用boat的Move方法移动船,并更新游戏状态。
public void characterIsClicked(MyCharacterController characterCtrl) {
if (userGUI.status != 0 ) return;
if (characterCtrl.isOnBoat ()) {
CoastController whichCoast;
if (boat.get_to_or_from () == -1) { // to->-1; from->1
whichCoast = toCoast;
} else {
whichCoast = fromCoast;
}
boat.GetOffBoat (characterCtrl.getName());
characterCtrl.moveToPosition (whichCoast.getEmptyPosition ());
characterCtrl.getOnCoast (whichCoast);
whichCoast.getOnCoast (characterCtrl);
} else { // character on coast
CoastController whichCoast = characterCtrl.getCoastController ();
if (boat.getEmptyIndex () == -1) { // boat is full
return;
}
if (whichCoast.get_to_or_from () != boat.get_to_or_from ()) // boat is not on the side of character
return;
whichCoast.getOffCoast(characterCtrl.getName());
characterCtrl.moveToPosition (boat.getEmptyPosition());
characterCtrl.getOnBoat (boat);
boat.GetOnBoat (characterCtrl);
}
userGUI.status = check_game_over ();
}
实现了characterIsClicked方法,在该方法中判断游戏状态是否为0(未结束),如果不是则返回。然后判断角色对象是否在船上,如果是则执行下列操作:
声明一个CoastController类型的变量whichCoast,用来表示目标岸。
判断船的位置是在起始岸还是目标岸,如果是目标岸,则将whichCoast赋值为toCoast;如果是起始岸,则将whichCoast赋值为fromCoast。
调用boat的GetOffBoat方法让角色对象下船,并传入角色对象的名字作为参数。
调用角色对象的moveToPosition方法让角色对象移动到whichCoast的空位上,并传入空位坐标作为参数。
调用角色对象的getOnCoast方法让角色对象上岸,并传入whichCoast作为参数。
调用whichCoast的getOnCoast方法让whichCoast记录角色对象,并传入角色对象作为参数。
如果角色对象不在船上,则执行下列操作:
声明一个CoastController类型的变量whichCoast,用来表示当前岸,并调用角色对象的getCoastController方法获取当前岸。
判断船是否已满,如果是则返回。
判断船的位置是否与当前岸一致,如果不是则返回。
调用whichCoast的getOffCoast方法让角色对象下岸,并传入角色对象的名字作为参数。
调用角色对象的moveToPosition方法让角色对象移动到船的空位上,并传入空位坐标作为参数。
调用角色对象的getOnBoat方法让角色对象上船,并传入boat作为参数。
调用boat的GetOnBoat方法让船记录角色对象,并传入角色对象作为参数。
最后更新游戏状态。
int check_game_over() { // 0->not finish, 1->lose, 2->win
int from_priest = 0;
int from_devil = 0;
int to_priest = 0;
int to_devil = 0;
int[] fromCount = fromCoast.getCharacterNum ();
from_priest += fromCount[0];
from_devil += fromCount[1];
int[] toCount = toCoast.getCharacterNum ();
to_priest += toCount[0];
to_devil += toCount[1];
if (to_priest + to_devil == 6) // win
return 2;
int[] boatCount = boat.getCharacterNum ();
if (boat.get_to_or_from () == -1) { // boat at toCoast
to_priest += boatCount[0];
to_devil += boatCount[1];
} else { // boat at fromCoast
from_priest += boatCount[0];
from_devil += boatCount[1];
}
if (from_priest < from_devil && from_priest > 0) { // lose
return 1;
}
if (to_priest < to_devil && to_priest > 0) {
return 1;
}
return 0; // not finish
}
实现了check_game_over方法,在该方法中判断游戏是否结束,如果结束则返回相应的状态码,如果未结束则返回0。判断游戏是否结束的逻辑如下:
声明四个整型变量from_priest、from_devil、to_priest和to_devil,分别表示起始岸和目标岸的牧师和魔鬼数量,并初始化为0。
调用fromCoast和toCoast的getCharacterNum方法获取各自的牧师和魔鬼数量,并分别累加到相应的变量中。
如果目标岸的牧师和魔鬼数量之和等于6,说明所有角色都过河了,游戏胜利,返回2。
调用boat的getCharacterNum方法获取船上的牧师和魔鬼数量,并根据船的位置累加到相应的变量中。
如果起始岸或目标岸的魔鬼数量多于牧师数量,且牧师数量大于0,说明有牧师被吃掉了,游戏失败,返回1。
否则游戏未结束,返回0。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。