#videolinkpriestanddemon
#github link https://github.com/someoneLikeC/PriADev
Game introduction
Game Name: Priests and Demons
Game rules introduction: There are three priests escorting three demons. Now they have arrived in front of a river. There is a boat on the river, which can only carry two people. We have to control the priest to escort the demon across the river. It is worth noting that when the number of priests on one side of the river is less than that of demons, the demons will kill the priests, the escort mission will fail, and there must be at least one person on the boat to move. You need to be smart and think of ways to help the priest successfully complete this escort mission.
Rule table
Current status | Player operation | Result |
---|---|---|
The priest or demon is on the shore, and there are vacancies on the boat | The player clicks the corresponding demon button or priest on the shore near the side of the boat | The corresponding demon or priest gets on the boat |
The priest or demon is on the boat | The player clicks the button for the demon or priest on the boat | The demon or priest is on the shore near the boat |
The number of demons on one side is greater than the number of priests | — | Indicates that the player loses |
The devil and the priest all went to the other side of the river | — |
Show player wins |
There are people on the boat and the boat is not moving | The player clicks the ship button | The ship sails to the other side |
Before starting to implement the game, first create a Resources folder, and then create three folders in it, Prefabs, Scripts, and Materials
GameObject
River
Shape: Cube
Name: River
Scaling parameters: X:10; Y:1; Z:6
River Bank
Shape: Cube
Name: Bank
Scaling parameters: X:10; Y:1; Z:2
Pastor (different pastors just have different colors)
Shape: Cube
Name:Priest
Scaling parameters: X:0.5; Y:1; Z:0.5
Devil (different demons just have different colors)
Shape: Capsule
Name: Devil
Scaling parameters: X:0.5; Y:0.5; Z:0.5
Boat
Shape: Cube
Name: Boat
Scaling parameters: X:0.5; Y:0.25; Z:1.5
Make all objects into prefabs. The creation steps are as follows (taking creating a river as an example):
1. Create the object:
Right-click on the red box area and select Cube
Once created, adjust its position and size in the inspector.
Rename the block to River
2. Add color to objects
Right click on the red box
Select the material in creation and name it riverColor
Click where the arrow points in the inspector and select your favorite color in the color picker box
Just click the left mouse button and drag the material to the River.
3. Create object prefabs (things that are made in advance and can be used directly when needed)
Drag the River to the location pointed by the arrow
After completion, delete River from the scene
Design process
UML diagram
Detailed implementation
controller
SSDirector.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class SSDirector : System.Object { // singleton instance private static SSDirector _instance; public ISceneController currentSceneController { get; set; } // https://blog.csdn.net/qiaoquan3/article/details/51339242 public bool Paused { get { return Time.timeScale == 0; } set { Time.timeScale = value ? 0 : 1; } } // 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 } }
ISceneController.cs
using System; /// <summary> /// Abstact Scene Controller. Interface between scene controllers and the director /// </summary> public interface ISceneController { void LoadResources(); Role[] getRole(); void Reset(); }
FirstController.cs
using UnityEngine; public class FirstController : MonoBehaviour,ISceneController { public river river; public Boat boat; public Bank[] banks = new Bank[2]; public Role[] devilsAndpriests = new Role[6]; voidAwake() { SSDirector director = SSDirector.getInstance(); director.setFPS(60); director.currentSceneController = this; director.currentSceneController.LoadResources(); } // loading resources for the first scene public void LoadResources() { river = new River(); boat = new Boat(); for (int i = 0; i < 2; i + + ) { banks[i] = new Bank(i); banks[i].SetName("bank" + i); } for(int i = 0; i < 3; i + + ) { devilsAndpriests[i] = new Role("Priest", new Vector3(2 + i, 0.5f, -3.5f)); devilsAndpriests[i].SetName("priest" + i); devilsAndpriests[i].SetPosition(devilsAndpriests[i].posRight); } for (int i = 0; i < 3; i + + ) { devilsAndpriests[i + 3] = new Role("Devil", new Vector3(-4 + i, 0.5f, -3.5f)); devilsAndpriests[i + 3].SetName("devil" + i); devilsAndpriests[i + 3].SetPosition(devilsAndpriests[i + 3].posRight); } } public Role[] getRole() { return devilsAndpriests; } public void Reset() { foreach(Role role in devilsAndpriests) { Destroy(role.character); } foreach(Bank bank in banks) { Destroy(bank.bank); } Destroy(boat.thisboat); Destroy(river.river); LoadResources(); } }
model
Role.cs
using Unity.VisualScripting; using UnityEngine; public class Role { public bool isOnBoat; public bool isLeft; public GameObject character; public Vector3 posRight; public Vector3 posLeft; public Role(string name, Vector3 v) { character = Object.Instantiate(Resources.Load("Prefabs/" + name, typeof(GameObject)), Vector3.zero, Quaternion.identity, null) as GameObject; isOnBoat = false; isLeft = false; posRight = v; posLeft = new Vector3(v.x, v.y, -v.z); } public void SetName(string name) { character.name = name; } public void SetPosition(Vector3 pos) { character.transform.position = pos; } public void MoveTo(Boat boat, Bank[] banks) { if (isOnBoat) { if (!isLeft) { if(character.transform.position == boat.pos1) { boat.pos1Full = false; }else if(character.transform.position == boat.pos2) { boat.pos2Full = false; } character.transform.position = posRight; character.transform.SetParent(null); isOnBoat = false; boat.peopleOnboat--; if (character.name == "priest0" || character.name == "priest1" || character.name == "priest2") { boat.P--; banks[0].Pnum + + ; } else { boat.D--; banks[0].Dnum + + ; } } else { if (character.transform.position == boat.pos1) { boat.pos1Full = false; } else if (character.transform.position == boat.pos2) { boat.pos2Full = false; } character.transform.position = posLeft; character.transform.SetParent(null); isOnBoat = false; boat.peopleOnboat--; if (character.name == "priest0" || character.name == "priest1" || character.name == "priest2") { boat.P--; banks[1].Pnum + + ; } else { boat.D--; banks[1].Dnum + + ; } } } else { if(boat.isLeft == isLeft) { if (!boat.pos1Full) { character.transform.position = boat.pos1; boat.pos1Full = true; character.transform.SetParent(boat.thisboat.transform); isOnBoat = true; boat.peopleOnboat + + ; if (character.name == "priest0" || character.name == "priest1" || character.name == "priest2") { boat.P + + ; if (!isLeft) { banks[0].Pnum--; } else { banks[1].Pnum--; } } else { boat.D + + ; if (!isLeft) { banks[0].Dnum--; } else { banks[1].Dnum--; } } } else if (!boat.pos2Full) { character.transform.position = boat.pos2; boat.pos2Full = true; character.transform.SetParent(boat.thisboat.transform); isOnBoat = true; boat.peopleOnboat + + ; if (character.name == "priest0" || character.name == "priest1" || character.name == "priest2") { boat.P + + ; if (!isLeft) { banks[0].Pnum--; } else { banks[1].Pnum--; } } else { boat.D + + ; if (!isLeft) { banks[0].Dnum--; } else { banks[1].Dnum--; } } } } } } }
River.cs
using UnityEngine; public class River { public GameObject river; public River() { river = Object.Instantiate(Resources.Load("Prefabs/River", typeof(GameObject)), Vector3.zero, Quaternion.identity, null) as GameObject; river.name = "river"; } }
Boat.cs
using UnityEngine; public class Boat { public int peopleOnboat; public int P; public int D; public Vector3 pos1; public Vector3 pos2; public bool pos1Full; public bool pos2Full; public GameObject thisboat; public bool isLeft; public Vector3 posLeft; public Vector3 posRight; public Boat() { peopleOnboat = 0; thisboat = Object.Instantiate(Resources.Load("Prefabs/Boat", typeof(GameObject)), new Vector3(0, 0.5f, -2.25f), Quaternion.identity, null) as GameObject; thisboat.name = "boat"; pos1 = thisboat.transform.position + new Vector3(0, 0, 0.3f); pos2 = thisboat.transform.position + new Vector3(0, 0, -0.3f); pos1Full = false; pos2Full = false; isLeft = false; posLeft = new Vector3(0, 0.5f, 2.25f); posRight = new Vector3(0, 0.5f, -2.25f); } public void Move(Bank[] banks, UserGUI userGUI) { if(isLeft) { thisboat.transform.position = posRight; pos1 = thisboat.transform.position + new Vector3(0, 0, 0.3f); pos2 = thisboat.transform.position + new Vector3(0, 0, -0.3f); isLeft = !isLeft; foreach(Transform child in thisboat.transform) { Role[] roles = SSDirector.getInstance().currentSceneController.getRole(); for (int i = 0; i < roles.Length; i + + ) { if (roles[i].character.transform == child) { roles[i].isLeft = !roles[i].isLeft; } } } if (banks[1].Pnum + P == 3 & amp; & amp; banks[1].Dnum + D == 3) { userGUI.Win(); } else if ((banks[0].Dnum + D > banks[0].Pnum + P & amp; & amp; banks[0].Pnum != 0) || (banks[1].Dnum + D > banks [1].Pnum + P & amp; & amp; banks[1].Pnum != 0)) { userGUI.Lose(); } } else { thisboat.transform.position = posLeft; pos1 = thisboat.transform.position + new Vector3(0, 0, 0.3f); pos2 = thisboat.transform.position + new Vector3(0, 0, -0.3f); isLeft = !isLeft; foreach (Transform child in thisboat.transform) { Role[] roles = SSDirector.getInstance().currentSceneController.getRole(); for (int i = 0; i < roles.Length; i + + ) { if (roles[i].character.transform == child) { roles[i].isLeft = !roles[i].isLeft; } } } if (banks[1].Pnum + P == 3 & amp; & amp; banks[1].Dnum + D == 3) { userGUI.Win(); } else if ((banks[0].Dnum > banks[0].Pnum & amp; & amp; banks[0].Pnum != 0) || (banks[1].Dnum > banks[1].Pnum & amp; & amp; banks[1].Pnum != 0)) { userGUI.Lose(); } } } }
Bank.cs
using UnityEngine; public class Bank { public int Pnum; public int Dnum; public bool isLeft; public GameObject bank; publicBank(int id) { bank = Object.Instantiate(Resources.Load("Prefabs/Bank", typeof(GameObject)), new Vector3(0, 0, 4.0f * (id - 0.5f) * 2), Quaternion.identity, null) as GameObject ; if (id == 0) { Pnum = 3; Dnum = 3; isLeft = false; } else { Pnum = 0; Dnum = 0; isLeft = true; } } public void SetName(string name) { bank.name = name; } }
view
IUserAction
public interface IUserAction { void MoveRole(Role role, Boat boat, Bank[] banks); void CrossRiver(Boat boat, Bank[] banks); void Lose(); void Win(); void Reset(); }
UserGUI
using UnityEngine; public class UserGUI : MonoBehaviour,IUserAction { private int state; public UserGUI() { state = -1; } public void Win() { state = 0; } public void Lose() { state = 1; } public void Reset() { state = -1; } public void MoveRole(Role role,Boat boat, Bank[] banks) { role.MoveTo(boat,banks); } public void CrossRiver(Boat boat, Bank[] banks) { boat.Move(banks,this); } private void OnGUI() { if (GUI.Button(new Rect(35, 25, 70, 30), "Start again")) { SSDirector.getInstance().currentSceneController.Reset(); Reset(); } if(state == -1) { for (int i = 0; i < GetComponent<FirstController>().devilsAndpriests.Length; i + + ) { if (i < 3) { if (GUI.Button(new Rect(20, 60 + i * 35, 100, 30), "Priest" + i + "Get on/off the boat")) { MoveRole(GetComponent<FirstController>().devilsAndpriests[i], GetComponent<FirstController>().boat, GetComponent<FirstController>().banks); } } else { if (GUI.Button(new Rect(20, 60 + i * 35, 100, 30), "Devil" + (i - 3) + "Get on/off the boat")) { MoveRole(GetComponent<FirstController>().devilsAndpriests[i], GetComponent<FirstController>().boat, GetComponent<FirstController>().banks); } } } if(GetComponent<FirstController>().boat.peopleOnboat > 0) { if (GUI.Button(new Rect(35, 270, 70, 30), "Sail the boat")) CrossRiver(GetComponent<FirstController>().boat, GetComponent<FirstController>().banks); } }else if(state == 0) { GUI.Box(new Rect(375, 150, 100, 100), "You win"); }else if(state == 1) { GUI.Box(new Rect(375, 150, 100, 100), "You lost"); } } }