前情提要
上次已经实现了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为空,说明没找到该上船的priest
if(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);
else
Priests[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和devil
if (identify)
{
// 区分左右岸
if (bank == 1)
leftBankPriests++;
else
rightBankPriests++;
}
else
{}
}
else
{}
}
ModifyPersonCountOnBoat用于修改当前船上还有多少人(只展示priest加人):
// 修改船上priest和devil的值
// 第一个参数表示加减,第二个参数表示身份
public void ModifyPersonCountOnBoat(bool plus, bool identify)
{
// 区分加减
if(plus)
{
// 区分priest和devil
if(identify)
boatPriest++;
else
boatDevil++;
}
else
{}
}
FirstController.priestsGetOff与FirstController.devilsGetOff
两个函数实现逻辑相似,只展示priestsGetOff(且只展示船在左岸的判断逻辑)
priestsGetOff和priestsGetOn判断逻辑其实几乎一样,主要不同点只是在于调用函数时输入的参数要变。
public void priestsGetOff()
{
if (judge.BoatIsMoving())
return;
List<int> temp = judge.PriestGoOffBoat();
// 如果temp为空,说明没找到该上船的priest
if (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);
else
myBoatBehaviour.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++)
{
//第一个选了priest
if (i == i1)
{
if (d_status[i].GetonBoatLeft() || d_status[i].GetonBoatRight())
{
i2 = i + 3;
break;
}
}
//第一个选了devil
else 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 instance
private 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_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
//UnityEditor.EditorApplication.Exit(0);
#else
Application.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();
}
}
//lose
else 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();
}
}
//win
else
{
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 update
void Start()
{
}
// Update is called once per frame
void 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 update
void Start()
{
}
// Update is called once per frame
void 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 update
void Start()
{
}
// Update is called once per frame
void 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 devils
p_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());
}
//boat
boatBehaviour = 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和devil
if (identify)
boatPriest++;
else
boatDevil++;
}
else
{
if(identify)
boatPriest--;
else
boatDevil--;
}
}
// 修改岸上priest和devil的值
// 第一个参数表示加减,第二个参数表示身份,第三个参数表示哪个岸
public void ModifyPersonCountOnBank(bool plus, bool identify, int bank)
{
// 区分加减
if (plus)
{
// 区分priest和devil
if (identify)
{
// 区分左右岸
if (bank == 1)
leftBankPriests++;
else
rightBankPriests++;
}
else
{
if (bank == 1)
leftBankDevils++;
else
rightBankDevils++;
}
}
else
{
if (identify)
{
if (bank == 1)
leftBankPriests--;
else
rightBankPriests--;
}
else
{
if (bank == 1)
leftBankDevils--;
else
rightBankDevils--;
}
}
}
// 找出船上有谁
// 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++)
{
//第一个选了priest
if (i == i1)
{
if (d_status[i].GetonBoatLeft() || d_status[i].GetonBoatRight())
{
i2 = i + 3;
break;
}
}
//第一个选了devil
else 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++)
{
//船左侧有priest
if (p_status[i].GetonBoatLeft())
{
temp.Add(i);
temp.Add(0);
temp.Add(1);
return temp;
}
//船右侧有priest
if (p_status[i].GetonBoatRight())
{
temp.Add(i);
temp.Add(1);
temp.Add(1);
return temp;
}
}
}
else
{
for (int i = 0; i < 3; i++)
{
//船左侧有priest
if (p_status[i].GetonBoatLeft())
{
temp.Add(i);
temp.Add(0);
temp.Add(0);
return temp;
}
//船右侧有priest
if (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++)
{
//船左侧有devil
if (d_status[i].GetonBoatLeft())
{
temp.Add(i);
temp.Add(0);
temp.Add(1);
return temp;
}
//船右侧有devil
if (d_status[i].GetonBoatRight())
{
temp.Add(i);
temp.Add(1);
temp.Add(1);
return temp;
}
}
}
else
{
for (int i = 0; i < 3; i++)
{
//船左侧有devil
if (d_status[i].GetonBoatLeft())
{
temp.Add(i);
temp.Add(0);
temp.Add(0);
return temp;
}
//船右侧有devil
if (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 update
void Start()
{
}
// Update is called once per frame
void 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;
// GameJudge
public IGameJudge judge;
// the first scripts
void Awake()
{
SSDirector director = SSDirector.getInstance();
director.setFPS(60);
director.currentSceneController = this;
director.currentSceneController.LoadResources();
}
// loading resources for the first scence
public void LoadResources()
{
// GameJudge
judge = new IGameJudge();
// priests
Priests = 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);
}
//devils
Devils = 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);
}
//boat
boat = Instantiate<GameObject>(
Resources.Load<GameObject>("Prefabs/Boat"),
Vector3.zero, Quaternion.identity);
boat.name = "Boat";
//bank
bankLeft = 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);
else
Devils[i1 - 3].transform.Translate(moveDir);
}
// 判断第二个位置
if (i2 != -1)
{
if (i2 < 3)
Priests[i2].transform.Translate(moveDir);
else
Devils[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);
else
Devils[i1 - 3].transform.Translate(moveDir);
}
// 判断第二个位置
if (i2 != -1)
{
if (i2 < 3)
Priests[i2].transform.Translate(moveDir);
else
Devils[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为空,说明没找到该上船的priest
if(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);
else
Priests[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);
else
Priests[i].transform.position = new Vector3(2.5f, 1.5f, 0);
}
}
public void priestsGetOff()
{
if (judge.BoatIsMoving())
return;
List<int> temp = judge.PriestGoOffBoat();
// 如果temp为空,说明没找到该上船的priest
if (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);
else
myBoatBehaviour.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);
else
myBoatBehaviour.SetrightPosEmpty(true);
}
}
public void devilsGetOn()
{
// 如果船正在动,那么不能响应用户事件
if (judge.BoatIsMoving())
return;
List<int> temp = judge.DevilGotoBoat();
// 如果temp为空,说明没找到该上船的devil
if (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);
else
Devils[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);
else
Devils[i].transform.position = new Vector3(2.5f, 1.5f, 0);
}
}
public void devilsGetOff()
{
if (judge.BoatIsMoving())
return;
List<int> temp = judge.DevilGoOffBoat();
// 如果temp为空,说明没找到该上船的devil
if (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);
else
myBoatBehaviour.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);
else
myBoatBehaviour.SetrightPosEmpty(true);
}
}
public int GameOver()
{
return judge.GameOver();
}
public void restart()
{
// priests
Priests[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);
//devils
Devils[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);
//boat
boat.transform.position = new Vector3(-2.4f, 0.5f, 0);
//bank
bankLeft.transform.position = new Vector3(-8.5f, 1.5f, 0);
bankRight.transform.position = new Vector3(8.5f, 1.5f, 0);
judge.reflash();
}
// Use this for initialization
void Start()
{
//give advice first
}
// Update is called once per frame
void Update()
{
//give advice first
// 将状态实时修改传回FirstController
p_status = judge.p_status;
d_status = judge.d_status;
myBoatBehaviour = judge.boatBehaviour;
//用于船和人的移动
onBoatMoving();
}
}