前言:这次做的巡逻兵算是我做的最难的一个游戏了吧。。。
巡逻兵游戏
效果:
规则:
- 创建一个地图和若干巡逻兵(使用动画);
- 每个巡逻兵走一个3~5个边的凸多边型,位置数据是相对地址。即每次确定下一个目标位置,用自己当前位置为原点计算;
- 巡逻兵碰撞到障碍物,则会自动选下一个点为目标;
- 巡逻兵在设定范围内感知到玩家,会自动追击玩家;
- 失去玩家目标后,继续巡逻;
- 计分:玩家每次甩掉一个巡逻兵计一分,与巡逻兵碰撞游戏结束;
待改进之处:
游戏结束后,主角倒下,游戏设置重新开始按键。(目前还不会)
游戏模式:
观察者与订阅者模式
工厂模式
动作分离模式
观察者模式
通过观察者实现不同预制之间信息的传递,这里实现游戏中GameStatus(游戏状态)和CanvasStatus(分数和游戏界面显示) 的交流。
public delegate void GameScoreAction();
public static event GameScoreAction myGameScoreAction;
public delegate void GameOverAction();
public static event GameOverAction myGameOverAction;
private SceneController scene;
private int canMove = 1;
void Start () {
scene = SceneController.getInstance();
scene.setGameStatus(this);
}
void Update () {
}
//hero逃离巡逻兵,得分
public void heroEscapeAndScore() {
myGameScoreAction();
canMove = 1;
}
//巡逻兵捕获hero,游戏结束
public void patrolHitHeroAndGameover() {
myGameOverAction();
canMove = 0;
}
private int score = 0;
private int textType;
void Start () {
distinguishText();
}
void Update () {
}
void distinguishText() {
if (gameObject.name.Contains ("Score"))
textType = 0;
else {
Debug.Log (gameObject.name);
textType = 1;
}
}
void OnEnable() {
GameStatus.myGameScoreAction += gameScore;
GameStatus.myGameOverAction += gameOver;
}
void OnDisable() {
GameStatus.myGameScoreAction -= gameScore;
GameStatus.myGameOverAction -= gameOver;
}
void gameScore() {
if (textType == 0) {
score++;
this.gameObject.GetComponent<Text>().text = "Score: " + score;
}
}
void gameOver() {
if (textType == 1) {
this.gameObject.GetComponent<Text> ().text = "Game Over!";
}
这里建立delegate和Event实现委托和事件,如果得分,则使myGameScoreAction()添加事件gameScore()。
工厂模式
在工厂中实现hero和patrol的生产。
public void initPatrol(GameObject _PatrolItem) {
PatrolItem = _PatrolItem;
}
public void initHero(GameObject _Hero){
HeroItem = _Hero;
}
public GameObject getPatrol() {
GameObject newPatrol = Camera.Instantiate(PatrolItem);
return newPatrol;
}
public GameObject getHero(){
GameObject newHero = Camera.Instantiate (HeroItem);
return newHero;
}
public Vector3[] getPosSet() {
return PatrolPosSet;
}
在GameModel这个类中载入即可。
动作分离模式
在runAction中,销毁原来的动作,为下一步添加新动作。
for (int i = 0; i < waitingAdd.Count; i++) {
if (waitingAdd[i].gameObject.Equals(gameObj)) {
SSAction ac = waitingAdd[i];
waitingAdd.RemoveAt(i);
i--;
DestroyObject(ac);
}
}
foreach (KeyValuePair<int, SSAction> kv in actions) {
SSAction ac = kv.Value;
if (ac.gameObject.Equals(gameObj)) {
ac.destroy = true;
}
}
action.gameObject = gameObj;
action.transform = gameObj.transform;
action.callBack = manager;
waitingAdd.Add(action);
action.Start();
如果原来的动作序列中存在将要实现的新动作,则销毁等待队列中的动作,添加将要实现的动作,实现动作序列保存最新的动作。
游戏结束
在游戏结束时设置一个变量,当PatrolStatus中的碰撞检测为Hero时场景管理器启用更改该变量的函数,在GameModel中终止所有角色的动作,以此达到终止游戏的效果(这是我能想到的最笨的方法)。
public interface IAddAction {
void addRandomMovement(GameObject sourceObj, bool isActive);
void addDirectMovement(GameObject sourceObj);
void addStop ();
}
public void addStop(){
//1->stop 0->move
ifStop = 1;
}