目录
本游戏项目(魔鬼与牧师)的动作管理类(CCActionManager)
前言
魔鬼与牧师(Devil and Priest)是一个经典的智力解谜游戏,玩家需要帮助三位魔鬼和三位牧师,将所有的牧师带过河,同时还要确保牧师不会被魔鬼吃掉。
下面是游戏的规则和背景故事:
规则:
1. 在河的一边有三个魔鬼、三个牧师以及一条船。
2. 船最多可以承载两个角色(牧师或魔鬼)且必须承载一个角色。
3. 当河的一侧的魔鬼数量大于牧师数量时,魔鬼会吃掉牧师。
4. 玩家需要将所有的牧师都安全地运送到另一侧的河岸,而且保证没有牧师被魔鬼吃掉。
背景故事:
有三个牧师和三个魔鬼被困在一座孤岛上,他们想要回到对岸。但是,这座孤岛上有一条河,河上只有一艘小船,而且这条河非常危险,同时魔鬼会吃掉牧师。他们需要找到一种方法使所有的牧师都能够安全地过河。
玩家需要根据规则,使用合适的策略移动牧师和魔鬼,以确保所有的牧师都能够安全地过河。游戏中的挑战在于玩家需要平衡每一步的移动,避免牧师被魔鬼吃掉,并且在规定的条件下完成游戏。
魔鬼与牧师游戏是一个简单而有趣的逻辑解谜游戏,可以帮助玩家锻炼思维能力和问题解决能力。
首先我们先来看一下这个游戏的视频演示吧:
本次项目的代码地址为:
Github地址
魔鬼与牧师游戏的MVC实现回顾
在上一个实验(上一个实验的博客地址)中,我们利用基础的MVC架构来实现了魔鬼与牧师的游戏,在这里我们将会简单地回顾一下魔鬼与牧师游戏的MVC实现,具体的内容实现请参考上一篇博客内容。
MVC的UML设计图
我们在实现游戏时,将会创建model、controller以及view的脚本文件,分别实现相对应的功能。同时最核心的脚本代码就是controller里面的firstcontroller,同时还有导演类、用户交互类以及GUI类等等,我们首先看一下该游戏项目的UML设计图吧:
Models
Models负责的是各个游戏对象的属性和基本行为,包括人物角色(魔鬼、牧师),船,以及河的两岸。船和岸是作为一个容器,需要有容纳人物的位置,也需要记录每个位置对应的xyz坐标。而且它们都需要有一定的方法去返回自身的信息,比如在左还是右、是第几个人物、返回对象类型的方法等等。同时还需要使用一个models中的position类记录一下各个游戏对象的位置信息,以供后面的类中调用。
View
View就是与用户交互的接口,其中需要接受来自用户的点击信息,并且根据点击的物体不同而传递不同的信息。还有就是反馈,游戏开始或结束需要反馈相应的信息给用户,也就是一个简单的GUI界面。比如游戏结束返回Game Over信息,游戏胜利就返回you win信息,以及倒计时游戏的剩余时间等。
Controllers
控制器Controllers的目的就是需要将M和V连接起来,从而控制全局,不仅需要从Models中获取相应的信息,并且利用这些信息判断他们的位置,还需要从View中获取相应的用户输入,进行相应的物体移动,在Models和View之间充当桥梁的作用。同时在主要的控制器FirstController还需要判断游戏的进行程度,也就是需要判断输赢,并且将输赢信息通过回调函数返回给View,从而达到反馈的目的。总而言之,控制器就是整个游戏得以进行的大脑,控制了整个游戏的进行逻辑以及实现。
动作分离基本思路
从上一个实验我们可以知道,使用MVC架构虽然比较直观,但是会发现我们的控制器Controllers比较臃肿,比较复杂,承担的任务比较重。所以是绝对有必要给控制器分配几个“手下”,为其承担一部分的任务的。那么,应该如何分配“手下”呢?而到了这里就是今天的主题啦——动作
动作分离版本的UML设计图
首先,我们还是需要先看一下该游戏项目的UML设计图,该UML设计图是基于动作分离版本的,在前一个实验的基础上增加了CCAction的动作类,同时对控制器Controllers做了一定的修改,下面是本次实验的UML设计图:
动作回调函数接口(ISSActionCallback)
在动作执行完毕后,都会执行回调函数执行别的操作,以及实现与这个动作相关的代码。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//枚举了动作事件的类型:开始和完成
public enum SSActionEventType:int { Started, Competeted }
//一个接口,用于在动作完成时进行回调
public interface ISSActionCallback
{
//source为一个SSAction类型的参数,表示触发事件的动作对象
//events为一个SSActionEventType类型的参数,表示事件类型,默认为Competeted
void SSActionEvent(SSAction source,
SSActionEventType events = SSActionEventType.Competeted,
int intParam = 0 ,
string strParam = null,
Object objectParam = null);
}