本文主要是介绍[3D游戏编程]Priests And Devils——动作分离版,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前情提要
上次已经实现了Priests And Devils小游戏,链接如下(游戏效果和上一次一样,就不再制作视频了):
[3D游戏编程]Priests And Devils-CSDN博客
本次任务
在上一次的代码中,可以看到FirstController里完成了几乎所有操作,包括人物状态的记录,人物的上下船,游戏结束的判断等等,使得FirstController非常繁杂和臃肿。
本次任务就是要在上次代码的基础上,将动作分离给更多的角色实现。
实现效果
将之前写在FirstController中的PriestsStatus,DevilsStatus,BoatBehaviour独立出来,并提供必要的Get和Set函数作为接口获取和修改类里面的值。
增加了一个IGameJudge类,负责实现各种判断,比如哪个人物可以上下船,游戏结束等等。
游戏框架设计
具体代码
主要是FirstController和IGameJudge有比较大的变化,所以只展示这两个类的代码。由于FirstController和IGameJudge紧密关联,所以在解释其中的函数时会一起讲。
FirstController.priestsGetOn与FirstController.devilsGetOn
两个函数实现逻辑相似,只展示priestsGetOn
public void priestsGetOn(){// 如果船正在动,那么不能响应用户事件if (judge.BoatIsMoving())return;List<int> temp = judge.PriestGotoBoat();// 如果temp为空,说明没找到该上船的priestif(temp.Count == 0) return;}
其中调用了IGameJudge中的BoatIsMoving函数,用于判断船是否在动
// 判断船是否在动public bool BoatIsMoving(){return boatBehaviour.GetisMoving();}
还调用了 IGameJudge中的PriestGotoBoat函数,该函数实现了找岸上是否有priest可以上船,同样的,这里只展示船在左岸,左岸上有priest并且船左边有空位的判断逻辑。
// 返回哪个priest应该上船public List<int> PriestGotoBoat(){List<int> temp = new List<int>(); //第一个参数是哪个priest,第二个是船位置,第三个是岸位置// 船在左边if (boatBehaviour.GetatLeftSide()){for (int i = 0; i < 3; i++){// 左侧岸上有牧师if (p_status[i].GetonBankLeft()){// 上船位置if (boatBehaviour.GetleftPosEmpty()){temp.Add(i);temp.Add(0);temp.Add(1);return temp;}if (boatBehaviour.GetrightPosEmpty()){}}}}else{}return temp;}
可以看到,如果没有找到priest,返回的temp将为空,这也就正好和if(temp.Count == 0)相对应。
接下来继续看priestsGetOn(只展示船在左岸,priest上船左边):
public void priestsGetOn(){ // 接上文int i = temp[0];p_status[i].SetonBankLeft(false);p_status[i].SetonBankRight(false);judge.ModifyPersonCountOnBank(false, true, temp[2]);judge.ModifyPersonCountOnBoat(true, true);// 上船的左边if (temp[1] == 0){p_status[i].SetonBoatLeft(true);myBoatBehaviour.SetleftPosEmpty(false);// 船在左岸if (myBoatBehaviour.GetatLeftSide())Priests[i].transform.position = new Vector3(-3.3f, 1.5f, 0);elsePriests[i].transform.position = new Vector3(1, 1.5f, 0);}else{}}
可以看到,这里调用了judge的两个函数ModifyPersonCountOnBank和ModifyPersonCountOnBoat
ModifyPersonCountOnBank用于修改当前岸上人数还有多少个(只展示左岸priest加人):
// 修改岸上priest和devil的值// 第一个参数表示加减,第二个参数表示身份,第三个参数表示哪个岸public void ModifyPersonCountOnBank(bool plus, bool identify, int bank){// 区分加减if (plus){// 区分priest和devilif (identify){ // 区分左右岸if (bank == 1)leftBankPriests++;elserightBankPriests++;}else{}}else{}}
ModifyPersonCountOnBoat用于修改当前船上还有多少人(只展示priest加人):
// 修改船上priest和devil的值// 第一个参数表示加减,第二个参数表示身份public void ModifyPersonCountOnBoat(bool plus, bool identify){// 区分加减if(plus) {// 区分priest和devilif(identify)boatPriest++;elseboatDevil++;}else {}}
FirstController.priestsGetOff与FirstController.devilsGetOff
两个函数实现逻辑相似,只展示priestsGetOff(且只展示船在左岸的判断逻辑)
priestsGetOff和priestsGetOn判断逻辑其实几乎一样,主要不同点只是在于调用函数时输入的参数要变。
public void priestsGetOff(){if (judge.BoatIsMoving())return;List<int> temp = judge.PriestGoOffBoat();// 如果temp为空,说明没找到该上船的priestif (temp.Count == 0)return;int i = temp[0];judge.ModifyPersonCountOnBank(true, true, temp[2]);judge.ModifyPersonCountOnBoat(false, true);p_status[i].SetonBoatLeft(false);p_status[i].SetonBoatRight(false);// 船在左岸if (temp[2] == 1){p_status[i].SetonBankLeft(true);Priests[i].transform.position = new Vector3((-8.6f + i * 1.3f), 3, 0);if (temp[1] == 0)myBoatBehaviour.SetleftPosEmpty(true);elsemyBoatBehaviour.SetrightPosEmpty(true);}else{}}
FirstController.boatMove和FirstController.onBoatMoving
这两个函数和上一次任务实现逻辑基本相同,只是将确定船上有什么人物的逻辑移到IGameJudge中实现,在IGameJudge中,PersonOnBoat函数实现了找人逻辑,并返回船上人物的下标。
// 0-2代表priest,3-5代表devil// 找出船上有谁public List<int> PersonOnBoat(){List<int> ans = new();int i1 = -1;int i2 = -1;for (int i = 0; i < 3; i++){if (p_status[i].GetonBoatLeft() || p_status[i].GetonBoatRight()){i1 = i;break;}if (d_status[i].GetonBoatLeft() || d_status[i].GetonBoatRight()){i1 = i + 3;break;}}for (int i = 0; i < 3; i++){//第一个选了priestif (i == i1){if (d_status[i].GetonBoatLeft() || d_status[i].GetonBoatRight()){i2 = i + 3;break;}}//第一个选了devilelse if (i == i1 - 3){if (p_status[i].GetonBoatLeft() || p_status[i].GetonBoatRight()){i2 = i;break;}}else{if (p_status[i].GetonBoatLeft() || p_status[i].GetonBoatRight()){i2 = i;break;}if (d_status[i].GetonBoatLeft() || d_status[i].GetonBoatRight()){i2 = i + 3;break;}}}ans.Add(i1);ans.Add(i2);return ans;}
IGameJudge.GameOver
此外,原来在FirstController中实现的GameOver函数,现在移到IGameJudge中实现
// 判断游戏结束public int GameOver(){// 船靠岸分情况讨论if (boatBehaviour.GetatLeftSide()){if ((leftBankPriests + boatPriest > 0&& leftBankDevils + boatDevil > leftBankPriests + boatPriest)|| (rightBankDevils > rightBankPriests && rightBankPriests > 0)){return 1;}}else{if ((rightBankPriests + boatPriest > 0&& rightBankDevils + boatDevil > rightBankPriests + boatPriest)|| (leftBankDevils > leftBankPriests && leftBankPriests > 0)){return 1;}if (rightBankDevils + boatDevil == 3 && rightBankPriests + boatPriest == 3){return 2;}}return 0;}
总结
这次的代码在实现逻辑上,是和上次的代码一样的,不同点在于,通过添加更多的“角色”,分担了FirstController的任务。首先,原本在FirstController中定义的有关状态的类,都独立出来,并通过提供接口实现获取和修改值的操作;其次,原本在FirstController中有关判断的逻辑,都在IGameJudge中实现。这种做法使得FirstController变得简洁,符合面向对象基于职责的原则。
代码大放送
使用方法:将FirstController和UserInterface挂载到MainCamera就可以使用了
SSDirector
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SSDirector : System.Object
{// singlton instanceprivate static SSDirector _instance;public ISceneController currentSceneController { get; set; }// get instance anytime anywhare!public static SSDirector getInstance(){if (_instance == null){_instance = new SSDirector();}return _instance;}public int getFPS(){return Application.targetFrameRate;}public void setFPS(int fps){Application.targetFrameRate = fps;}public void NextScene(){Debug.Log("Waiting next Scene now...");
#if UNITY_EDITORUnityEditor.EditorApplication.isPlaying = false;//UnityEditor.EditorApplication.Exit(0);
#elseApplication.Quit();
#endif}
}
IUserAction
using System;public interface IUserAction
{void boatMove();void priestsGetOn();void priestsGetOff();void devilsGetOn();void devilsGetOff();
}
ISceneController
using System;/// <summary>
/// Abstact Scene Controller. Interface between scene controllers and the director
/// </summary>
public interface ISceneController
{void LoadResources();int GameOver();void restart();
}
UserInterface
using UnityEngine;
using System.Collections;public class UserInterface : MonoBehaviour
{private IUserAction myActions;private ISceneController mySceneController;float btnWidth = (float)Screen.width / 6.0f;float btnHeight = (float)Screen.height / 6.0f;void Start(){mySceneController = SSDirector.getInstance().currentSceneController;myActions = mySceneController as IUserAction;}void Update(){}void OnGUI(){//游戏正常进行if (mySceneController.GameOver() == 0){if (GUI.Button(new Rect(btnWidth / 2, 250, btnWidth, btnHeight), "Priests GetOn")){myActions.priestsGetOn();}if (GUI.Button(new Rect(btnWidth / 2 + btnWidth, 250, btnWidth, btnHeight), "Priests GetOff")){myActions.priestsGetOff();}if (GUI.Button(new Rect(btnWidth / 2 + 2 * btnWidth, 250, btnWidth, btnHeight), "Go!")){myActions.boatMove();}if (GUI.Button(new Rect(btnWidth / 2 + 3 * btnWidth, 250, btnWidth, btnHeight), "Devils GetOn")){myActions.devilsGetOn();}if (GUI.Button(new Rect(btnWidth / 2 + 4 * btnWidth, 250, btnWidth, btnHeight), "Devils GetOff")){myActions.devilsGetOff();}}//loseelse if (mySceneController.GameOver() == 1){GUI.Box(new Rect(2 * btnWidth, btnHeight, 2 * btnWidth, btnHeight), "\nYOU LOSE");if (GUI.Button(new Rect(2.5f * btnWidth, 2 * btnHeight, btnWidth, btnHeight), "Restart")){mySceneController.restart();}}//winelse{GUI.Box(new Rect(2 * btnWidth, btnHeight, 2 * btnWidth, btnHeight), "\nYOU WIN");if (GUI.Button(new Rect(2.5f * btnWidth, 2 * btnHeight, btnWidth, btnHeight), "Restart")){mySceneController.restart();}}}
}
PriestsStatus
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PriestsStatus
{private bool onBoatLeft, onBoatRight;private bool onBankLeft, onBankRight;public PriestsStatus(){this.onBoatLeft = false;this.onBoatRight = false;this.onBankLeft = true;this.onBankRight = false;}// 一些必要的get函数public bool GetonBoatLeft() { return onBoatLeft; }public bool GetonBoatRight() { return onBoatRight; }public bool GetonBankLeft() { return onBankLeft; }public bool GetonBankRight() { return onBankRight; }// 一些必要的set函数public void SetonBoatLeft(bool value) { onBoatLeft= value; }public void SetonBoatRight(bool value) { onBoatRight= value; }public void SetonBankLeft(bool value) { onBankLeft= value; }public void SetonBankRight(bool value) { onBankRight= value;}// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){}
}
DevilsStatus
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class DevilsStatus
{private bool onBoatLeft, onBoatRight;private bool onBankLeft, onBankRight;public DevilsStatus() {this.onBoatLeft = false;this.onBoatRight = false;this.onBankLeft = true;this.onBankRight = false;}// 一些必要的get函数public bool GetonBoatLeft() { return onBoatLeft; }public bool GetonBoatRight() { return onBoatRight; }public bool GetonBankLeft() { return onBankLeft; }public bool GetonBankRight() { return onBankRight; }// 一些必要的set函数public void SetonBoatLeft(bool value) { onBoatLeft = value; }public void SetonBoatRight(bool value) { onBoatRight = value; }public void SetonBankLeft(bool value) { onBankLeft = value; }public void SetonBankRight(bool value) { onBankRight = value; }// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){}
}
BoatBehaviour
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class BoatBehaviour
{private bool isMoving;private bool atLeftSide;private bool leftPosEmpty, rightPosEmpty;public BoatBehaviour(){this.isMoving = false;this.atLeftSide = true;this.leftPosEmpty = true;this.rightPosEmpty = true;}// 一些必要的get函数public bool GetisMoving() { return isMoving; }public bool GetatLeftSide() { return atLeftSide; }public bool GetleftPosEmpty() { return leftPosEmpty; }public bool GetrightPosEmpty() { return rightPosEmpty; }// 一些必要的set函数public void SetisMoving(bool value) { isMoving = value; }public void SetatLeftSide(bool value) { atLeftSide = value;}public void SetleftPosEmpty(bool value) { leftPosEmpty = value;}public void SetrightPosEmpty(bool value) { rightPosEmpty = value;}// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){}
}
IGameJudge
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class IGameJudge
{public List<PriestsStatus> p_status;public List<DevilsStatus> d_status;public BoatBehaviour boatBehaviour;// 记录船上有多少个priest(devil)private int boatPriest, boatDevil;// 记录某个位置有多少个priest(devil)private int leftBankPriests, rightBankPriests;private int leftBankDevils, rightBankDevils;public IGameJudge(){boatPriest = 0;boatDevil = 0;leftBankPriests = 3;rightBankPriests = 0;leftBankDevils = 3;rightBankDevils = 0;p_status = new List<PriestsStatus>();d_status = new List<DevilsStatus>();boatBehaviour = new BoatBehaviour();}// 实时修改状态值public void reflash(){// priests devilsp_status = new List<PriestsStatus>();d_status = new List<DevilsStatus>();for (int i = 0; i < 3; i++){p_status.Add(new PriestsStatus());d_status.Add(new DevilsStatus());}//boatboatBehaviour = new BoatBehaviour();// 初始化leftBankDevils = 3;leftBankPriests = 3;rightBankDevils = 0;rightBankPriests = 0;boatPriest = 0;boatDevil = 0;}// 修改船上priest和devil的值// 第一个参数表示加减,第二个参数表示身份public void ModifyPersonCountOnBoat(bool plus, bool identify){// 区分加减if (plus) {// 区分priest和devilif (identify)boatPriest++;elseboatDevil++;}else {if(identify)boatPriest--;elseboatDevil--;}}// 修改岸上priest和devil的值// 第一个参数表示加减,第二个参数表示身份,第三个参数表示哪个岸public void ModifyPersonCountOnBank(bool plus, bool identify, int bank){// 区分加减if (plus){// 区分priest和devilif (identify){ // 区分左右岸if (bank == 1)leftBankPriests++;elserightBankPriests++;}else{if (bank == 1)leftBankDevils++;elserightBankDevils++;}}else{if (identify){if (bank == 1)leftBankPriests--;elserightBankPriests--;}else{if (bank == 1)leftBankDevils--;elserightBankDevils--;}}}// 找出船上有谁// 0-2代表priest,3-5代表devilpublic List<int> PersonOnBoat(){List<int> ans = new();int i1 = -1;int i2 = -1;for (int i = 0; i < 3; i++){if (p_status[i].GetonBoatLeft() || p_status[i].GetonBoatRight()){i1 = i;break;}if (d_status[i].GetonBoatLeft() || d_status[i].GetonBoatRight()){i1 = i + 3;break;}}for (int i = 0; i < 3; i++){//第一个选了priestif (i == i1){if (d_status[i].GetonBoatLeft() || d_status[i].GetonBoatRight()){i2 = i + 3;break;}}//第一个选了devilelse if (i == i1 - 3){if (p_status[i].GetonBoatLeft() || p_status[i].GetonBoatRight()){i2 = i;break;}}else{if (p_status[i].GetonBoatLeft() || p_status[i].GetonBoatRight()){i2 = i;break;}if (d_status[i].GetonBoatLeft() || d_status[i].GetonBoatRight()){i2 = i + 3;break;}}}ans.Add(i1);ans.Add(i2);return ans;}// 判断船能不能动public bool CanMove(){// 船在动或者船上没人时不能开船if (!boatBehaviour.GetisMoving() && (boatPriest + boatDevil > 0)){return true;}return false;}// 判断船是否在动public bool BoatIsMoving(){return boatBehaviour.GetisMoving();}// 返回哪个priest应该上船public List<int> PriestGotoBoat(){List<int> temp = new List<int>(); //第一个参数是哪个priest,第二个是船位置,第三个是岸位置// 船在左边if (boatBehaviour.GetatLeftSide()){for (int i = 0; i < 3; i++){// 左侧岸上有牧师if (p_status[i].GetonBankLeft()){// 上船位置if (boatBehaviour.GetleftPosEmpty()){temp.Add(i);temp.Add(0);temp.Add(1);return temp;}if (boatBehaviour.GetrightPosEmpty()){temp.Add(i);temp.Add(1);temp.Add(1);return temp;}}}}else{for (int i = 0; i < 3; i++){//右侧岸上有牧师if (p_status[i].GetonBankRight()){// 上船位置if (boatBehaviour.GetleftPosEmpty()){temp.Add(i);temp.Add(0);temp.Add(0);return temp;}if (boatBehaviour.GetrightPosEmpty()){temp.Add(i);temp.Add(1);temp.Add(0);return temp;}}}}return temp;}// 返回哪个priest应该下船public List<int> PriestGoOffBoat(){List<int> temp = new List<int>(); //第一个参数是哪个priest,第二个是船位置,第三个是岸位置// 船在左边if (boatBehaviour.GetatLeftSide()){for (int i = 0; i < 3; i++){//船左侧有priestif (p_status[i].GetonBoatLeft()){temp.Add(i);temp.Add(0);temp.Add(1);return temp;}//船右侧有priestif (p_status[i].GetonBoatRight()){temp.Add(i);temp.Add(1);temp.Add(1);return temp;}}}else{for (int i = 0; i < 3; i++){//船左侧有priestif (p_status[i].GetonBoatLeft()){temp.Add(i);temp.Add(0);temp.Add(0);return temp;}//船右侧有priestif (p_status[i].GetonBoatRight()){temp.Add(i);temp.Add(1);temp.Add(0);return temp;}}}return temp;}// 返回哪个devil应该上船public List<int> DevilGotoBoat(){List<int> temp = new List<int>(); //第一个参数是哪个devil,第二个是船位置,第三个是岸位置// 船在左边if (boatBehaviour.GetatLeftSide()){for (int i = 0; i < 3; i++){// 左侧岸上有恶魔if (d_status[i].GetonBankLeft()){// 上船位置if (boatBehaviour.GetleftPosEmpty()){temp.Add(i);temp.Add(0);temp.Add(1);return temp;}if (boatBehaviour.GetrightPosEmpty()){temp.Add(i);temp.Add(1);temp.Add(1);return temp;}}}}else{for (int i = 0; i < 3; i++){//右侧岸上有恶魔if (d_status[i].GetonBankRight()){// 上船位置if (boatBehaviour.GetleftPosEmpty()){temp.Add(i);temp.Add(0);temp.Add(0);return temp;}if (boatBehaviour.GetrightPosEmpty()){temp.Add(i);temp.Add(1);temp.Add(0);return temp;}}}}return temp;}// 返回哪个priest应该下船public List<int> DevilGoOffBoat(){List<int> temp = new List<int>(); //第一个参数是哪个devil,第二个是船位置,第三个是岸位置// 船在左边if (boatBehaviour.GetatLeftSide()){for (int i = 0; i < 3; i++){//船左侧有devilif (d_status[i].GetonBoatLeft()){temp.Add(i);temp.Add(0);temp.Add(1);return temp;}//船右侧有devilif (d_status[i].GetonBoatRight()){temp.Add(i);temp.Add(1);temp.Add(1);return temp;}}}else{for (int i = 0; i < 3; i++){//船左侧有devilif (d_status[i].GetonBoatLeft()){temp.Add(i);temp.Add(0);temp.Add(0);return temp;}//船右侧有devilif (d_status[i].GetonBoatRight()){temp.Add(i);temp.Add(1);temp.Add(0);return temp;}}}return temp;}// 判断游戏结束public int GameOver(){// 船靠岸分情况讨论if (boatBehaviour.GetatLeftSide()){if ((leftBankPriests + boatPriest > 0&& leftBankDevils + boatDevil > leftBankPriests + boatPriest)|| (rightBankDevils > rightBankPriests && rightBankPriests > 0)){return 1;}}else{if ((rightBankPriests + boatPriest > 0&& rightBankDevils + boatDevil > rightBankPriests + boatPriest)|| (leftBankDevils > leftBankPriests && leftBankPriests > 0)){return 1;}if (rightBankDevils + boatDevil == 3 && rightBankPriests + boatPriest == 3){return 2;}}return 0;}// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){}
}
FirstController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// Scene Controller
/// Usage: host on a gameobject in the scene
/// responsiablities:
/// acted as a scene manager for scheduling actors.log something ...
/// interact with the director and players
/// </summary>
public class FirstController : MonoBehaviour, ISceneController, IUserAction
{// 对每种物体新建类记录当前状态// 记录物体样式、位置等等public List<GameObject> Priests, Devils;public GameObject boat, bankLeft, bankRight;// 物体状态public List<PriestsStatus> p_status;public List<DevilsStatus> d_status;public BoatBehaviour myBoatBehaviour;// GameJudgepublic IGameJudge judge;// the first scriptsvoid Awake(){SSDirector director = SSDirector.getInstance();director.setFPS(60);director.currentSceneController = this;director.currentSceneController.LoadResources();}// loading resources for the first scencepublic void LoadResources(){// GameJudgejudge = new IGameJudge();// priestsPriests = new List<GameObject>();p_status = judge.p_status;for (int i = 0; i < 3; i++){GameObject priests = Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/Priests"),Vector3.zero, Quaternion.identity);priests.name = "Priest " + (i + 1);//priests.tag = "Priest";Priests.Add(priests);}//devilsDevils = new List<GameObject>();d_status = judge.d_status;for (int i = 0; i < 3; i++){GameObject devils = Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/Devils"),Vector3.zero, Quaternion.identity);devils.name = "Devil " + (i + 1);//devils.tag = "Devil";Devils.Add(devils);}//boatboat = Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/Boat"),Vector3.zero, Quaternion.identity);boat.name = "Boat";//bankbankLeft = Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/Shore"),Vector3.zero, Quaternion.identity);bankLeft.name = "BankLeft";bankRight = Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/Shore"),Vector3.zero, Quaternion.identity);bankRight.name = "BankRight";// 初始化restart();}public void boatMove(){// 船在动或者船上没人时不能开船if (judge.CanMove()){myBoatBehaviour.SetisMoving(true);}}public void onBoatMoving(){if (myBoatBehaviour.GetisMoving()){Vector3 moveDir;// 判断向左向右走List<int> place = judge.PersonOnBoat();if (place.Count == 0)return;// 向左int i1 = place[0];int i2 = place[1]; if (!myBoatBehaviour.GetatLeftSide()){moveDir = new Vector3(-0.1f, 0, 0);boat.transform.Translate(moveDir);// 判断第一个位置if (i1 != -1){if (i1 < 3)Priests[i1].transform.Translate(moveDir);elseDevils[i1 - 3].transform.Translate(moveDir);}// 判断第二个位置if (i2 != -1){if (i2 < 3)Priests[i2].transform.Translate(moveDir);elseDevils[i2 - 3].transform.Translate(moveDir);}//到达对岸if (boat.transform.position.x == -2.4f){myBoatBehaviour.SetisMoving(false);myBoatBehaviour.SetatLeftSide(true);}}// 向右else{moveDir = new Vector3(0.1f, 0, 0);boat.transform.Translate(moveDir);// 判断第一个位置if (i1 != -1){if (i1 < 3)Priests[i1].transform.Translate(moveDir);elseDevils[i1 - 3].transform.Translate(moveDir);}// 判断第二个位置if (i2 != -1){if (i2 < 3)Priests[i2].transform.Translate(moveDir);elseDevils[i2 - 3].transform.Translate(moveDir);}//到达对岸if (boat.transform.position.x == 1.7f){myBoatBehaviour.SetisMoving(false);myBoatBehaviour.SetatLeftSide(false);}}}}public void priestsGetOn(){// 如果船正在动,那么不能响应用户事件if (judge.BoatIsMoving())return;List<int> temp = judge.PriestGotoBoat();// 如果temp为空,说明没找到该上船的priestif(temp.Count == 0) return;int i = temp[0];p_status[i].SetonBankLeft(false);p_status[i].SetonBankRight(false);judge.ModifyPersonCountOnBank(false, true, temp[2]);judge.ModifyPersonCountOnBoat(true, true);// 上船的左边if (temp[1] == 0){p_status[i].SetonBoatLeft(true);myBoatBehaviour.SetleftPosEmpty(false);// 船在左岸if (myBoatBehaviour.GetatLeftSide())Priests[i].transform.position = new Vector3(-3.3f, 1.5f, 0);elsePriests[i].transform.position = new Vector3(1, 1.5f, 0);}else{p_status[i].SetonBoatRight(true);myBoatBehaviour.SetrightPosEmpty(false);// 船在右岸if (myBoatBehaviour.GetatLeftSide())Priests[i].transform.position = new Vector3(-1.8f, 1.5f, 0);elsePriests[i].transform.position = new Vector3(2.5f, 1.5f, 0);}}public void priestsGetOff(){if (judge.BoatIsMoving())return;List<int> temp = judge.PriestGoOffBoat();// 如果temp为空,说明没找到该上船的priestif (temp.Count == 0)return;int i = temp[0];judge.ModifyPersonCountOnBank(true, true, temp[2]);judge.ModifyPersonCountOnBoat(false, true);p_status[i].SetonBoatLeft(false);p_status[i].SetonBoatRight(false);// 船在左岸if (temp[2] == 1){p_status[i].SetonBankLeft(true);Priests[i].transform.position = new Vector3((-8.6f + i * 1.3f), 3, 0);if (temp[1] == 0)myBoatBehaviour.SetleftPosEmpty(true);elsemyBoatBehaviour.SetrightPosEmpty(true);}else{p_status[i].SetonBankRight(true);Priests[i].transform.position = new Vector3((6 + i * 1.3f), 3, 0);if (temp[1] == 0)myBoatBehaviour.SetleftPosEmpty(true);elsemyBoatBehaviour.SetrightPosEmpty(true);}}public void devilsGetOn(){// 如果船正在动,那么不能响应用户事件if (judge.BoatIsMoving())return;List<int> temp = judge.DevilGotoBoat();// 如果temp为空,说明没找到该上船的devilif (temp.Count == 0)return;int i = temp[0];d_status[i].SetonBankLeft(false);d_status[i].SetonBankRight(false);judge.ModifyPersonCountOnBank(false, false, temp[2]);judge.ModifyPersonCountOnBoat(true, false);// 上船的左边if (temp[1] == 0){d_status[i].SetonBoatLeft(true);myBoatBehaviour.SetleftPosEmpty(false);// 船在左岸if (myBoatBehaviour.GetatLeftSide())Devils[i].transform.position = new Vector3(-3.3f, 1.5f, 0);elseDevils[i].transform.position = new Vector3(1, 1.5f, 0);}else{d_status[i].SetonBoatRight(true);myBoatBehaviour.SetrightPosEmpty(false);// 船在右岸if (myBoatBehaviour.GetatLeftSide())Devils[i].transform.position = new Vector3(-1.8f, 1.5f, 0);elseDevils[i].transform.position = new Vector3(2.5f, 1.5f, 0);}}public void devilsGetOff(){if (judge.BoatIsMoving())return;List<int> temp = judge.DevilGoOffBoat();// 如果temp为空,说明没找到该上船的devilif (temp.Count == 0)return;int i = temp[0];judge.ModifyPersonCountOnBank(true, false, temp[2]);judge.ModifyPersonCountOnBoat(false, false);d_status[i].SetonBoatLeft(false);d_status[i].SetonBoatRight(false);// 船在左岸if (temp[2] == 1){d_status[i].SetonBankLeft(true);Devils[i].transform.position = new Vector3((-12.9f + i * 1.3f), 3, 0);if (temp[1] == 0)myBoatBehaviour.SetleftPosEmpty(true);elsemyBoatBehaviour.SetrightPosEmpty(true);}else{d_status[i].SetonBankRight(true);Devils[i].transform.position = new Vector3((10.3f + i * 1.3f), 3, 0);if (temp[1] == 0)myBoatBehaviour.SetleftPosEmpty(true);elsemyBoatBehaviour.SetrightPosEmpty(true);}}public int GameOver(){return judge.GameOver();}public void restart(){// priestsPriests[0].transform.position = new Vector3(-8.6f, 3, 0);Priests[1].transform.position = new Vector3(-7.3f, 3, 0);Priests[2].transform.position = new Vector3(-6, 3, 0);//devilsDevils[0].transform.position = new Vector3(-12.9f, 3, 0);Devils[1].transform.position = new Vector3(-11.6f, 3, 0);Devils[2].transform.position = new Vector3(-10.3f, 3, 0);//boatboat.transform.position = new Vector3(-2.4f, 0.5f, 0);//bankbankLeft.transform.position = new Vector3(-8.5f, 1.5f, 0);bankRight.transform.position = new Vector3(8.5f, 1.5f, 0);judge.reflash();}// Use this for initializationvoid Start(){//give advice first}// Update is called once per framevoid Update(){//give advice first// 将状态实时修改传回FirstControllerp_status = judge.p_status;d_status = judge.d_status;myBoatBehaviour = judge.boatBehaviour;//用于船和人的移动onBoatMoving();}}
这篇关于[3D游戏编程]Priests And Devils——动作分离版的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!