GitHub项目地址
视频地址
游戏设计要求:
- 创建一个地图和若干巡逻兵(使用动画);
- 每个巡逻兵走一个3~5个边的凸多边型,位置数据是相对地址。即每次确定下一个目标位置,用自己当前位置为原点计算;
- 巡逻兵碰撞到障碍物,则会自动选下一个点为目标;
- 巡逻兵在设定范围内感知到玩家,会自动追击玩家;
- 失去玩家目标后,继续巡逻;
- 计分:玩家每次甩掉一个巡逻兵计一分,与巡逻兵碰撞游戏结束
程序设计要求:
- 必须使用订阅与发布模式传消息
实现的游戏规则:游戏规则非常简单,玩家通过控制来摆脱巡逻的小兵获得加分,被抓住了游戏就结束了。注意本游戏的地图没有围墙,不小心掉下去可是会导致游戏结束的。
玩家的创建:
玩家通过键盘的↑↓←→来控制小人的行走
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Com.Patrols;
public class HeroStatus : MonoBehaviour {
public int standOnArea = -1;
public delegate void GameOverAction();
void Start () {
}
void Update () {
}
private void OnGUI() {
modifyStandOnArea();
float posY = this.gameObject.transform.position.y;
if (posY <= -3.0) {
GUIStyle fontStyle = new GUIStyle();
fontStyle.fontSize = 40 ;
fontStyle.normal.background = null; //设置背景填充
fontStyle.normal.textColor= new Color(1,0,0); //设置字体颜色
GUI.Label(new Rect(Screen.width / 2, Screen.height / 2, Screen.width / 2, Screen.height / 2), "Oh! You Lose Yourself",fontStyle);
}
}
void modifyStandOnArea() {
float posX = this.gameObject.transform.position.x;
float posZ = this.gameObject.transform.position.z;
if (posZ >= FenchLocation.FenchHori) {
if (posX < FenchLocation.FenchVertLeft)
standOnArea = 0;
else if (posX > FenchLocation.FenchVertRight)
standOnArea = 2;
else
standOnArea = 1;
}
else {
if (posX < FenchLocation.FenchVertLeft)
standOnArea = 3;
else if (posX > FenchLocation.FenchVertRight)
standOnArea = 5;
else
standOnArea = 4;
}
}
}
巡逻兵的设计:
预设生成巡逻小兵,有着固定的巡逻路线,当玩家靠近时会追击玩家,追击失败则玩家得分,并继续他的设定路线巡逻,追击成功游戏结束。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Com.Patrols;
public class PatrolBehaviour : MonoBehaviour {
private IAddAction addAction;
private IGameStatusOp gameStatusOp;
public int ownIndex;
public bool isCatching; //是否感知到hero
private float CATCH_RADIUS = 3.0f;
void Start () {
addAction = SceneController.getInstance() as IAddAction;
gameStatusOp = SceneController.getInstance() as IGameStatusOp;
ownIndex = getOwnIndex();
isCatching = false;
}
void Update () {
checkNearByHero();
}
int getOwnIndex() {
string name = this.gameObject.name;
char cindex = name[name.Length - 1];
int result = cindex - '0';
return result;
}
void checkNearByHero () {
if (gameStatusOp.getHeroStandOnArea() == ownIndex) {
if (!isCatching) {
isCatching = true;
addAction.addDirectMovement(this.gameObject);
}
}
else {
if (isCatching) {
gameStatusOp.heroEscapeAndScore();
isCatching = false;
addAction.addRandomMovement(this.gameObject, false);
}
}
}
void OnCollisionStay(Collision e) {
if (e.gameObject.name.Contains("Patrol") || e.gameObject.name.Contains("fence")
|| e.gameObject.tag.Contains("FenceAround")) {
isCatching = false;
addAction.addRandomMovement(this.gameObject, false);
}
if (e.gameObject.name.Contains("Hero")) {
gameStatusOp.patrolHitHeroAndGameover();
Debug.Log("Game Over!");
}
}
}
场景控制器:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SceneController : MonoBehaviour {
private int score;
private int dropOffPatrolNum = 0;
public int patrolNum = 5;
public IPatrolFactory factory;
public PlayerController player;
public bool isGameOver = false;
public bool isWin = false;
void Rest() {
score = 0;
dropOffPatrolNum = 0;
isGameOver = false;
isWin = false;
factory.GeneratePatrol(patrolNum);
}
public void GameOver() {
dropOffPatrolNum = 0;
isGameOver = true;
factory.ReleaseAllPatrols();
}
public void YouWin() {
dropOffPatrolNum = 0;
isWin = true;
factory.ReleaseAllPatrols();
}
public void AddScore(int curScore) {
if (patrolNum < curScore) {
score += curScore;
dropOffPatrolNum++;
if (dropOffPatrolNum == patrolNum) {
YouWin();
}
}
}
private void OnGUI() {
if (GUI.Button(new Rect(20, 20, 50, 20), "Start")) {
Rest();
}
GUI.Label(new Rect(100, 20, 150, 20), "Score:" + score.ToString());
if (isGameOver) {
GUI.Label(new Rect(Screen.width / 2, Screen.height / 2, 150, 20), "GameOver");
GameOver();
score = 0;
}
if (isWin) {
GUI.Label(new Rect(Screen.width / 2, Screen.height / 2, 150, 20), "You Win!");
score = 0;
}
}
// Use this for initialization
void Start() {
factory = Singleton<IPatrolFactory>.Instance;
player = Singleton<PlayerController>.Instance;
player.initialPos();
}
}