牧师与魔鬼小游戏
零、写在前面
-
自定义的数据类不要继承Unity的MonoBehavior类,一开始在判断游戏角色对象是否为空的时候,即判断是否== null ,发现判断的结果一直为true,后来发现是因为Character类继承了MonoBehavior类,此类及其子类均不允许被new出来,Unity重载了UnityEngine 命名空间下的Object的== 运算符,故导致了== 的使用出现了问题。 -
此次作业运用了MVC架构,体会到了模块之间低耦合度的好处,在修改代码时很方便,只需要找到对应的模块进行修改,修改结果不会对其它模块造成太大的影响。各个模块的明确分工,职责驱动使得整个项目能够方向明确地推进。 -
利用组件的概念,当对象添加了Moveable组件,则其具有了移动的功能,当对象添加了GUIClick组件,则其具有对鼠标点击做出反应的功能,由此实现了代码的重用。 -
通过运用facade设计模式也进一步体验到接口是如何实现解耦合的——控制器去完成UserAction接口,即UserAction实现了用户动作和控制器的解耦合。
一、 项目配置
二、游戏提及的事物
三、玩家动作表(规则表)
玩家动作 | 前提条件 | 结果 |
---|
点击岸上的牧师或魔鬼 | 船上有空位 | 被点击的牧师或魔鬼移动到船上 | 点击船上的牧师或魔鬼 | 无 | 被点击的牧师或魔鬼移动到岸上 | 点击GO按钮 | 船上有乘客 | 船移动到对岸 | 点击Rstart按钮 | 无 | 游戏重置 |
四、 实现过程和方法
1. 总体设计思路
2. 模块分析
Model部分
-
Character
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
?
public class Character {
? ?readonly GameObject character;
? ?readonly int type; //0-priest 1-devil
? ?readonly Moveable moveableScript;// 移动脚本组件
? ?readonly GUIClick _GUIClick;// 响应鼠标点击组件
?
? ?private bool isOnBoat;// 是否在船上
? ?private bool isFinished;//是否已经过河
?
? ?// 构造函数,根据传入的字符串选择创建牧师对象或者魔鬼对象
? ?public Character(string sel){
? ? ? ?// 动态加载预制
? ? ? ?if(sel == "priest"){
? ? ? ? ? ?character = Object.Instantiate(Resources.Load("Prefabs/priest", typeof(GameObject)),Vector3.zero, Quaternion.identity, null) as GameObject;
? ? ? ? ? ?type = 0;
? ? ? }
? ? ? ?else{
? ? ? ? ? ?character = Object.Instantiate(Resources.Load("Prefabs/devil", typeof(GameObject)),Vector3.zero, Quaternion.identity, null) as GameObject;
? ? ? ? ? ?type = 1;
? ? ? }
? ? ? ?// 为对象添加移动和点击响应组件
? ? ? ?moveableScript = character.AddComponent (typeof(Moveable)) as Moveable;
? ? ? ?_GUIClick = character.AddComponent(typeof(GUIClick)) as GUIClick;
? ? ? ?_GUIClick.bindCharacter(this);
? ? ? ?// 初始化变量
? ? ? ?isOnBoat = false;
? ? ? ?isFinished = false;
? }
?
? ?public int getType(){
? ? ? ?return type;
? }
?
? ?public void setName(string name) {
? ? ? ?character.name = name;
? }
?
? ?public string getName() {
return character.name;
}
?
? ?public void getOnBoat(Boat boat){
? ? ? ?// 设置transform为船的子组件,这样当船移动的时候就可以随着船移动
? ? ? ?character.transform.parent = boat.getGameobj().transform;
? ? ? ?isOnBoat = true;
? }
?
? ?public void getOffBoat(){
? ? ? ?character.transform.parent = null;
? ? ? ?isOnBoat = false;
? }
?
? ?public void getOnLand(Land land){
? ? ? ?if(land.getType() == 0){
? ? ? ? ? ?isFinished = false;
? ? ? }
? ? ? ?else{
? ? ? ? ? ?isFinished = true;
? ? ? }
? ? ? ?isOnBoat = false;
? }
?
? ?public bool getIsOnBoat(){
? ? ? ?return isOnBoat;
? }
?
? ?public void setPosition(Vector3 pos){
? ? ? ?character.transform.position = pos;
? }
?
? ?public void moveToPosition(Vector3 pos){
? ? ? ?moveableScript.setDestination(pos);
? }
?
? ?public bool getIsFinished(){
? ? ? ?return isFinished;
? }
?
? ?// 重置对象
? ?public void reset(){
? ? ? ?moveableScript.reset();
? ? ? ?// 如果对象已经过河
? ? ? ?if(isFinished){
? ? ? ? ? ?// 通过导演对象获取当前场景的控制器,取得其控制的Land对象
? ? ? ? ? ?Land endLand = (Director.getInstance ().currentSceneController as FirstController).endLand;
? ? ? ? ? ?endLand.leaveLand(this);
? ? ? ? ? ?Land startLand = (Director.getInstance ().currentSceneController as FirstController).startLand;
? ? ? ? ? ?getOnLand(startLand);
? ? ? ? ? ?setPosition(startLand.getOnLand(this));
? ? ? }
? ? ? ?// 如果对象在船上
? ? ? ?if(isOnBoat){
? ? ? ? ? ?getOffBoat();
? ? ? ? ? ?Land startLand = (Director.getInstance ().currentSceneController as FirstController).startLand;
? ? ? ? ? ?Boat boat = (Director.getInstance ().currentSceneController as FirstController).boat;
? ? ? ? ? ?boat.removePassenger(this);
? ? ? ? ? ?getOnLand(startLand);
? ? ? ? ? ?setPosition(startLand.getOnLand(this));
? ? ? }
? ? ? ?character.transform.parent = null; ? ? ? ?
? }
?
} -
Boat
-
主要就是实现船对象,其主要的数据是一个GameObject对象,通过Object.Instantiate函数动态加载预制中的船模型。 -
通过维护一个Character类数组,实现船上乘客的更新。 -
主要功能包括:添加乘客、移除乘客、获得当前船上牧师和魔鬼的数量,以及通过moveable组件控制GameObject对象的移动。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
?
public class Boat{
? ?readonly GameObject boat;
? ?readonly Moveable moveableScript;
? ?readonly Vector3 startPos = new Vector3(-1.95F,0.68F,0);// 在起始岸边的位置
? ?readonly Vector3 endPos = new Vector3(1.95F,0.68F,0);// 在终点岸边的位置
? ?readonly Vector3 startFirstPos = new Vector3(-2.3F,1.15F,0);// 在起始岸边船的第一个座位位置
? ?readonly Vector3 startSecondPos = new Vector3(-1.54F,1.15F,0);// 在起始岸边船的第二个座位位置
? ?readonly Vector3 endFirstPos = new Vector3(1.54F,1.15F,0);// 在终点岸边船的第一个座位位置
? ?readonly Vector3 endSecondPos = new Vector3(2.37F,1.15F,0);// 在终点岸边船的第二个座位位置
?
? ?private Character[] passenger;// 乘客对象数组,存放船上的对象
? ?private int curPosition;//当前船在哪个岸边 0-start 1-end
? ?private int count;// 船上人数
?
? ?public Boat(){
? ? ? ?// 初始化对象数组,一开始船上无人,故置为空
? ? ? ?passenger = new Character[2];
? ? ? ?passenger[0] = null;
? ? ? ?passenger[1] = null;
? ? ? ?// 动态加载船的预制
? ? ? ?boat = Object.Instantiate (Resources.Load ("Prefabs/boat", typeof(GameObject)), startPos, Quaternion.identity, null) as GameObject;
boat.name = "boat";
? ? ? ?// 添加moveable组件使得船可以移动
? ? ? ?moveableScript = boat.AddComponent (typeof(Moveable)) as Moveable;
? ? ? ?// 初始变量
? ? ? ?curPosition = 0;
? ? ? ?count = 0;
? }
?
? ?public void move(){
? ? ? ?if(curPosition == 0){
? ? ? ? ? ?moveableScript.setDestination(endPos);
? ? ? ? ? ?curPosition = 1;
? ? ? }
? ? ? ?else{
? ? ? ? ? ?moveableScript.setDestination(startPos);
? ? ? ? ? ?curPosition = 0;
? ? ? }
? }
?
? ?public bool isEmpty(){
? ? ? ?return count == 0;
? }
?
? ?public bool isFull(){
? ? ? ?return count == 2;
? }
?
? ?public bool addPassenger(Character ch){
? ? ? ?if(count == 2){
? ? ? ? ? ?return false;
? ? ? }
? ? ? ?// 找到空位置
? ? ? ?for(int i = 0;i < 2;++i){
? ? ? ? ? ?if(passenger[i] == null){
? ? ? ? ? ? ? ?passenger[i] = ch;
? ? ? ? ? ? ? ?break;
? ? ? ? ? }
? ? ? }
? ? ? ?count++;
? ? ? ?return true;
? }
?
? ?public bool removePassenger(Character ch){
? ? ? ?if(count == 0){
? ? ? ? ? ?return false;
? ? ? }
? ? ? ?// 找到要删除的乘客
? ? ? ?for(int i = 0;i < 2;++i){
? ? ? ? ? ?if(passenger[i] != null && passenger[i].getName() == ch.getName()){
? ? ? ? ? ? ? ?passenger[i] = null;
? ? ? ? ? }
? ? ? }
? ? ? ?count--;
? ? ? ?return true;
? }
?
? ?public int getCurPosition(){
? ? ? ?return curPosition;
? }
?
? ?public Vector3 getEmptyPosition(){
? ? ? ?// 若船已满,则返回坐标(0,0,0)
? ? ? ?if(count == 2){
? ? ? ? ? ?return new Vector3(0,0,0);
? ? ? }
? ? ? ?if(curPosition == 0){
? ? ? ? ? ?if(passenger[0] == null){
? ? ? ? ? ? ? ?return startFirstPos;
? ? ? ? ? }
? ? ? ? ? ?else{
? ? ? ? ? ? ? ?return startSecondPos;
? ? ? ? ? }
? ? ? }
? ? ? ?else{
? ? ? ? ? ?if(passenger[0] == null){
? ? ? ? ? ? ? ?return endFirstPos;
? ? ? ? ? }
? ? ? ? ? ?else{
? ? ? ? ? ? ? ?return endSecondPos;
? ? ? ? ? }
? ? ? }
? }
?
? ?public GameObject getGameobj(){
? ? ? ?return boat;
? }
?
?
? ?public int getNumOfPriest(){
? ? ? ?int res = 0;
? ? ? ?for(int i = 0;i < 2;++i){
? ? ? ? ? ?if(passenger[i] != null && passenger[i].getType() == 0){
? ? ? ? ? ? ? ?res++;
? ? ? ? ? }
? ? ? }
? ? ? ?return res;
? }
?
? ?public int getNumOfDevil(){
? ? ? ?int res = 0;
? ? ? ?for(int i = 0;i < 2;++i){
? ? ? ? ? ?if(passenger[i] != null && passenger[i].getType() == 1){
? ? ? ? ? ? ? ?res++;
? ? ? ? ? }
? ? ? }
? ? ? ?return res;
? }
?
? ?public void reset(){
? ? ? ?count = 0;
? ? ? ?passenger[0] = null;
? ? ? ?passenger[1] = null;
? ? ? ?// 若船在终点,则回到起始岸
? ? ? ?if(curPosition == 1){
? ? ? ? ? ?moveableScript.setDestination(startPos);
? ? ? ? ? ?curPosition = 0;
? ? ? }
? }
} -
Land
-
实现的是河岸对象,包含了一个GameObject对象,t对象,通过Object.Instantiate函数动态加载预制中的河岸模型。 -
Land类主要通过维护三个数组:当前河岸上的对象数组、位置数组、位置状态数组,这三者的下标一一对应。河岸上有六个位置,用于放置游戏角色,当某个位置上有角色的时候,即该位置被占有,此时位置状态数组相同下标对应的值会由变为1. -
因此,当有新的角色要上岸时,会先通过查找位置状态数组找到空位置,然后返回相同下标的位置数组的值,并将该对象存入相同下标的对象数组中,实际上就是一个哈希的过程。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
?
public class Land{
? ?private GameObject land;
? ?readonly Vector3 startPos = new Vector3(-6.6F,0,0);// 起始岸的位置
readonly Vector3 endPos = new Vector3(6.6F,0,0);// 终点岸的位置
? ?
? ?private int type;//河岸类型 0-start 1-end
? ?private int count;// 岸上人数
? ?private Character[] curCharacter;// 当前岸上的角色
? ?readonly Vector3[] place;// 岸上的六个位置坐标 角色数组下标和位置数组下标保持一致
? ?private int[] emptyPlace;// 岸上六个位置的情况 0-empty 1-not empty
?
? ?public Land(string sel){
? ? ? ?place = new Vector3[6];
? ? ? ?if(sel == "start"){
? ? ? ? ? ?land = Object.Instantiate(Resources.Load("Prefabs/land", typeof(GameObject)),startPos, Quaternion.identity, null) as GameObject;
? ? ? ? ? ?land.name = "start";
? ? ? ? ? ?type = 0;
? ? ? ? ? ?count = 0;
? ? ? ? ? ?for(int i = 0;i < 6;++i){
? ? ? ? ? ? ? ?place[i] = new Vector3(-3.5F-0.8F*i,1.5F,0);
? ? ? ? ? }
? ? ? }
? ? ? ?else{
? ? ? ? ? ?land = Object.Instantiate(Resources.Load("Prefabs/land", typeof(GameObject)),endPos, Quaternion.identity, null) as GameObject;
? ? ? ? ? ?land.name = "end";
? ? ? ? ? ?type = 1;
? ? ? ? ? ?count = 0;
? ? ? ? ? ?for(int i = 0;i < 6;++i){
? ? ? ? ? ? ? ?place[i] = new Vector3(3.5F+0.8F*i,1.5F,0);
? ? ? ? ? }
? ? ? }
? ? ? ?curCharacter = new Character[6];
? ? ? ?emptyPlace = new int[6];
? ? ? ?for(int i = 0;i < 6;++i){
? ? ? ? ? ?curCharacter[i] = null;
? ? ? }
? ? ? ?for(int i = 0;i < 6;++i){
? ? ? ? ? ?emptyPlace[i] = 0;
? ? ? }
? }
?
? ?public int getType(){
? ? ? ?return type;
? }
?
? ?public int getCount(){
? ? ? ?return count;
? }
?
? ?public Vector3 getOnLand(Character ch){
? ? ? ?int index = 0;
? ? ? ?// 找到空位置,将角色放入对应下标的角色数组中,方便后面查找删除
? ? ? ?while(true){
? ? ? ? ? ?if(emptyPlace[index] == 0){
? ? ? ? ? ? ? ?emptyPlace[index] = 1;
? ? ? ? ? ? ? ?curCharacter[index] = ch;
? ? ? ? ? ? ? ?count++;
? ? ? ? ? ? ? ?break;
? ? ? ? ? }
? ? ? ? ? ?else{
? ? ? ? ? ? ? ?index++;
? ? ? ? ? }
? ? ? }
? ? ? ?// 返回角色所在位置
? ? ? ?return place[index];
? }
?
? ?public void leaveLand(Character ch){
? ? ? ?for(int i = 0;i < 6;++i){
? ? ? ? ? ?if( curCharacter[i] != null && curCharacter[i].getName() == ch.getName()){
? ? ? ? ? ? ? ?curCharacter[i] = null;
? ? ? ? ? ? ? ?emptyPlace[i] = 0;
? ? ? ? ? ? ? ?count--;
? ? ? ? ? ? ? ?return;
? ? ? ? ? }
? ? ? } ?
? }
?
? ?public Vector3 getEmptyPosition(){
? ? ? ?for(int i = 0;i < 6;++i){
? ? ? ? ? ?if(emptyPlace[i] == 0){
? ? ? ? ? ? ? ?return place[i];
? ? ? ? ? }
? ? ? }
? ? ? ?return new Vector3(0,0,0);
? }
?
? ?public int getNumOfPriest(){
? ? ? ?int res = 0;
? ? ? ?for(int i = 0;i < 6;++i){
? ? ? ? ? ?if(curCharacter[i] == null){
? ? ? ? ? ? ? ?continue;
? ? ? ? ? }
? ? ? ? ? ?if(curCharacter[i].getType() == 0){
? ? ? ? ? ? ? ?res++;
? ? ? ? ? }
? ? ? }
? ? ? ?return res;
? }
?
? ?public int getNumOfDevil(){
? ? ? ?int res = 0;
? ? ? ?for(int i = 0;i < 6;++i){
? ? ? ? ? ?if(curCharacter[i] == null){
? ? ? ? ? ? ? ?continue;
? ? ? ? ? }
? ? ? ? ? ?if(curCharacter[i].getType() == 1){
? ? ? ? ? ? ? ?res++;
? ? ? ? ? }
? ? ? }
? ? ? ?return res;
? }
?
? ?public void reset(){
? ? ? ?if(type == 0){
? ? ? ? ? ?for(int i = 0;i < 6;++i){
? ? ? ? ? ? ? ?emptyPlace[i] = 1;
? ? ? ? ? }
? ? ? ? ? ?count = 6;
? ? ? }
? ? ? ?else{
? ? ? ? ? ?for(int i = 0;i < 6;++i){
? ? ? ? ? ? ? ?emptyPlace[i] = 0;
? ? ? ? ? }
? ? ? ? ? ?count = 0;
? ? ? }
? }
}
View部分
-
_GUI
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
?
public class _GUI : MonoBehaviour{
? ?private SceneController sc;
? ?private UserAction ac;
? ?private GUIStyle style;
? ?private int status;
? ?private Texture2D priest;
? ?private Texture2D devil;
? ?private Texture2D rule;
?
? ?void Start(){
? ? ? ?style = new GUIStyle();
style.fontSize = 40;
? ? ? ?// 获得控制器,通过控制器更新model部分的数据
? ? ? ?sc = Director.getInstance ().currentSceneController;
? ? ? ?ac = Director.getInstance().currentSceneController as UserAction;
? ? ? ?status = (Director.getInstance ().currentSceneController as FirstController).status;
? ? ? ?// 动态加载图片
? ? ? ?priest = Instantiate (Resources.Load ("Pictures/牧师", typeof(Texture2D))) as Texture2D;
? ? ? ?devil = Instantiate (Resources.Load ("Pictures/恶魔", typeof(Texture2D))) as Texture2D;
? ? ? ?rule = Instantiate (Resources.Load ("Pictures/规则", typeof(Texture2D))) as Texture2D;
?
? ? ? ?// Debug.Log("Screen.width"+Screen.width);
? ? ? ?// Debug.Log(" Screen.height"+ Screen.height);
? }
?
?
? ?void OnGUI(){
? ? ? ?// 同步游戏状态
? ? ? ?status = (Director.getInstance ().currentSceneController as FirstController).status;
? ? ? ?if(GUI.Button(new Rect(795,490, 120, 120),"GO")){
? ? ? ? ? ?if(status == 0){
? ? ? ? ? ? ? ?ac.goButtonIsClicked();
? ? ? ? ? }
? ? ? }
? ? ? ?if(GUI.Button(new Rect(1095,490, 120, 120), "Restart")){
? ? ? ? ? ?ac.restart();
? ? ? }
? ? ? ?if(status == 1){
? ? ? ? ? ?GUI.Label(new Rect(800,100,300,250),devil);
? ? ? ? ? ?GUI.Label(new Rect(247, 50, 100, 50), "You lose!",style);
? ? ? }
? ? ? ?if(status == 2){
? ? ? ? ? ?GUI.Label(new Rect(800,100,300,250),priest);
? ? ? ? ? ?GUI.Label(new Rect(247, 50, 100, 50), "You win!",style);
? ? ? }
? ? ? ?GUI.Label(new Rect(0,800,1500,1500),rule);
? }
}
Controller部分
这一部分基本就是按照课程网站上的指示做
-
Director
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
?
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;
? }
}
? -
SceneController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
?
public interface SceneController {
? ?void loadResources ();
? ?void checkGameStatus();
} -
FirstController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
?
public class FirstController : MonoBehaviour, SceneController, UserAction{
? ?readonly Vector3 water_pos = new Vector3(0,-0.4F,0);// 河流预制的位置
? ?
public Land startLand;// 起始河岸
? ?public Land endLand;// 终点河岸
public Boat boat;// 船
public int status;//游戏状态 0-gaming 1-lose 2-win
?
private Character[] characters;// 六个游戏角色
private _GUI userGUI;// GUI组件
?
? ?
void Awake() {
// 将自身设置为当前场记
Director director = Director.getInstance ();
director.currentSceneController = this;
// 将GUI作为一个组件
userGUI = gameObject.AddComponent <_GUI>() as _GUI;
characters = new Character[6];
// 加载游戏资源
loadResources();
}
?
// 实现SceneController接口,加载游戏资源
? ?public void loadResources() {
GameObject water = Instantiate (Resources.Load ("Prefabs/river", typeof(GameObject)), water_pos, Quaternion.identity, null) as GameObject;
water.name = "water";
startLand = new Land ("start");
endLand = new Land ("end");
boat = new Boat();
loadCharacter ();
}
?
// 实现SceneController接口,检查游戏状态 0->not finish, 1->lose, 2->win
public void checkGameStatus() {
// 船在出发点
int startNumOfPriest = startLand.getNumOfPriest();
int startNumOfDevil = startLand.getNumOfDevil();
int endNumOfPriest = endLand.getNumOfPriest();
int endNumOfDevil = endLand.getNumOfDevil();
int boatNumOfPriest = boat.getNumOfPriest();
int boatNumOfDevil = boat.getNumOfDevil();
if(endNumOfPriest + endNumOfDevil + boatNumOfPriest + boatNumOfDevil == 6){
status = 2;
return ;
}
if(boat.getCurPosition() == 1){
if((startNumOfPriest ?< startNumOfDevil && startNumOfPriest > 0)||(endNumOfPriest + ?boatNumOfPriest < endNumOfDevil + boatNumOfDevil && endNumOfPriest + ?boatNumOfPriest > 0)){
status = 1;
return ;
}
}
else{
if((startNumOfPriest + boatNumOfPriest < startNumOfDevil + boatNumOfDevil && startNumOfPriest + boatNumOfPriest > 0) || (endNumOfPriest < endNumOfDevil && endNumOfPriest > 0)){
status = 1;
return ;
}
}
status = 0;
}
?
// 加载游戏对象
? ?private void loadCharacter() {
for (int i = 0; i < 3; i++) {
Character ch = new Character("priest");
ch.setName("priest" + i);
ch.getOnLand(startLand);
ch.setPosition (startLand.getOnLand(ch));
characters[i] = ch;
}
?
for (int i = 0; i < 3; i++) {
Character ch = new Character("devil");
ch.setName("devil" + i);
ch.setPosition (startLand.getOnLand(ch));
ch.getOnLand(startLand);
characters [i+3] = ch;
}
}
?
// 实现UserAction接口的goButtonIsClicked函数
public void goButtonIsClicked(){
if(!boat.isEmpty()){
boat.move();
checkGameStatus();
}
}
?
// 实现UserAction接口的characterIsClicked函数
public void characterIsClicked(Character ch){
// 角色在船上
if(ch.getIsOnBoat()){
if(boat.getCurPosition() == 0){
ch.moveToPosition(startLand.getOnLand(ch));
ch.getOnLand(startLand);
}
else{
ch.moveToPosition(endLand.getOnLand(ch));
ch.getOnLand(endLand);
}
ch.getOffBoat();
boat.removePassenger(ch);
}
// 角色在岸上
else{
if(!boat.isFull()){
if(ch.getIsFinished() && boat.getCurPosition() == 1){
ch.getOnBoat(boat);
endLand.leaveLand(ch);
ch.moveToPosition(boat.getEmptyPosition());
boat.addPassenger(ch);
}
if(!ch.getIsFinished() && boat.getCurPosition() == 0){
ch.getOnBoat(boat);
startLand.leaveLand(ch);
ch.moveToPosition(boat.getEmptyPosition());
boat.addPassenger(ch);
}
}
?
}
}
?
// 重置游戏
public void restart(){
status = 0;
for(int i = 0;i < 6;++i){
characters[i].reset();
}
boat.reset();
startLand.reset();
endLand.reset();
}
}
组件部分
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
?
public class GUIClick : MonoBehaviour{
? ?UserAction action;
? ?Character bindingCharacter;// 组件当前绑定的角色对象
? ?SceneController sc;
? ?int status;// 游戏状态
?
? ?public void bindCharacter(Character ch){
? ? ? ?bindingCharacter = ch;
? ? ? ?status = (Director.getInstance ().currentSceneController as FirstController).status;
? }
?
? ?void Start(){
? ? ? ?action = Director.getInstance().currentSceneController as UserAction;
? ? ? ?sc = Director.getInstance().currentSceneController;
? }
?
? ?void OnMouseDown(){
? ? ? ?// 同步游戏状态
? ? ? ?status = (Director.getInstance ().currentSceneController as FirstController).status;
? ? ? ?// 只有在游戏中点击才有效
? ? ? ?if(status == 0){
? ? ? ? ? ?action.characterIsClicked(bindingCharacter);
? ? ? }
? }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
?
public class Moveable : MonoBehaviour{
? ?readonly float speed = 10;
?
? ?int moving_status; // 0->not moving, 1->moving to middle, 2->moving to dest
? ?Vector3 dest;
? ?Vector3 middle;
?
? ?void Update() {
? ? ? ?if (moving_status == 1) {
? ? ? ? ? ?transform.position = Vector3.MoveTowards (transform.position, middle, speed * Time.deltaTime);
? ? ? ? ? ?if (transform.position == middle) {
? ? ? ? ? ? ? ?moving_status = 2;
? ? ? ? ? }
? ? ? }
? ? ? ?else if (moving_status == 2) {
? ? ? ? ? ?transform.position = Vector3.MoveTowards (transform.position, dest, speed * Time.deltaTime);
? ? ? ? ? ?if (transform.position == dest) {
? ? ? ? ? ? ? ?moving_status = 0;
? ? ? ? ? }
? ? ? }
? }
?
? ?public void setDestination(Vector3 _dest) {
? ? ? ?dest = _dest;
? ? ? ?middle = _dest;
? ? ? ?if (_dest.y == transform.position.y) { // boat moving
? ? ? ? ? ?moving_status = 2;
? ? ? }
? ? ? ?else if (_dest.y < transform.position.y) { // character from coast to boat
? ? ? ? ? ?middle.y = transform.position.y;
? ? ? } else { // character from boat to coast
? ? ? ? ? ?middle.x = transform.position.x;
? ? ? }
? ? ? ?moving_status = 1;
? }
?
? ?public void reset() {
? ? ? ?moving_status = 0;
? }
}
五、效果展示
[]: Unity3D作业-牧师与魔鬼过河演示视频_哔哩哔哩_bilibili
六、项目地址
huanghj78/Unity-Homework - 码云 - 开源中国 (gitee.com)
|