Unity牧师与魔鬼小游戏制作

游戏机制:

牧师与魔鬼是一款益智游戏,玩家需要帮助牧师与魔鬼在规定时间内过河。河边有三个牧师和三个魔鬼,他们都想去这条河的对岸,但只有一艘船,这艘船每次只能载两个人。而且必须有一个人把船从一边开到另一边。在游戏中,玩家可以通过单击人物来将人物移动到船只上,然后单击船只将船移动到河的另一边。如果在其中一边魔鬼的数量超过了这一边中牧师的数量,牧师就会被杀死,游戏就失败了。而当全部牧师和全部魔鬼都到达另一边时,游戏就胜利了。

UML图:

Controller制作代码: 

 BoatControl.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BoatControl : ClickAction
{
    Boat boatModel;
    IUserAction userAction;

    public void DealClick() {
        // 前置条件:船没有满员
        // 如果能上船,角色应到的位置就是船所在的位置
        // 如果不能上船,角色应到的位置就是原来的位置
        if (boatModel.roles[0] != null || boatModel.roles[1] != null) {
            userAction.MoveBoat();
        }
    }

    public BoatControl() {
        userAction = SSDirector.GetInstance().CurrentSceneController as IUserAction;
    }
    public void CreateBoat(Vector3 position) {
        if (boatModel != null) {
            Object.DestroyImmediate(boatModel.boat);
        }
        boatModel = new Boat(position);
        boatModel.boat.GetComponent<Click>().setClickAction(this);
    }

    public Boat GetBoatModel() {
        return boatModel;
    }

    public Vector3 AddRole(Role roleModel) {
        int index = -1;
        if (boatModel.roles[0] == null) index = 0;
        else if (boatModel.roles[1] == null) index = 1;

        if (index == -1) return roleModel.role.transform.localPosition;

        boatModel.roles[index] = roleModel;
        roleModel.inBoat = true;
        roleModel.role.transform.parent = boatModel.boat.transform;
        if (roleModel.isPriest) boatModel.priestCount++;
        else boatModel.devilCount++;
        return Position.role_boat[index];
    }

    //将角色从船上移到岸上
    public void RemoveRole(Role roleModel) {
        for (int i = 0; i < 2; ++i){
            if (boatModel.roles[i] == roleModel) {
                boatModel.roles[i] = null;
                if (roleModel.isPriest) boatModel.priestCount--;
                else boatModel.devilCount--;
                break;
            }
        }
    }

    
}

 FirstController.cs 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FirstController : MonoBehaviour, ISceneController, IUserAction {
    LandControl leftLandController, rightLandController;
    River river;
    BoatControl boatController;
    RoleControl[] roleControllers;
    MoveCtrl moveController;
    bool isRunning;
    float time;

    public void LoadResources() {
        //role
        roleControllers = new RoleControl[6];
        for (int i = 0; i < 6; ++i) {
            roleControllers[i] = new RoleControl();
            roleControllers[i].CreateRole(Position.role_land[i], i < 3 ? true : false, i);
        }

        //land
        leftLandController = new LandControl();
        leftLandController.CreateLand(Position.left_land);
        leftLandController.GetLand().land.name = "left_land";
        rightLandController = new LandControl();
        rightLandController.CreateLand(Position.right_land);
        rightLandController.GetLand().land.name = "right_land";

        //将人物添加并定位至左岸  
        foreach (RoleControl roleController in roleControllers)
        {
            roleController.GetRoleModel().role.transform.localPosition = leftLandController.AddRole(roleController.GetRoleModel());
        }
        //boat
        boatController = new BoatControl();
        boatController.CreateBoat(Position.left_boat);

        //river
        river = new River(Position.river);

        //move
        moveController = new MoveCtrl();

        isRunning = true;
        time = 60;


    }

    public void MoveBoat() {
        if (isRunning == false || moveController.GetIsMoving()) return;
        if (boatController.GetBoatModel().isRight) {
            moveController.SetMove(Position.left_boat, boatController.GetBoatModel().boat);
        }
        else {
            moveController.SetMove(Position.right_boat, boatController.GetBoatModel().boat);
        }
        boatController.GetBoatModel().isRight = !boatController.GetBoatModel().isRight;
    }

    public void MoveRole(Role roleModel) {
        if (isRunning == false || moveController.GetIsMoving()) return;
        if (roleModel.inBoat) {
            if (boatController.GetBoatModel().isRight) {
                moveController.SetMove(rightLandController.AddRole(roleModel), roleModel.role);
            }
            else {
                moveController.SetMove(leftLandController.AddRole(roleModel), roleModel.role);
            }
            roleModel.onRight = boatController.GetBoatModel().isRight;
            boatController.RemoveRole(roleModel);
        }
        else {
            if (boatController.GetBoatModel().isRight == roleModel.onRight) {
                if (roleModel.onRight) {
                    rightLandController.RemoveRole(roleModel);
                }
                else {
                    leftLandController.RemoveRole(roleModel);
                }
                moveController.SetMove(boatController.AddRole(roleModel), roleModel.role);
            }
        }
    }

    public void Check() {
        if (isRunning == false) return;
        this.gameObject.GetComponent<UserGUI>().gameMessage = "";
        if (rightLandController.GetLand().priestCount == 3) {
            this.gameObject.GetComponent<UserGUI>().gameMessage = "You Win!";
            isRunning = false;
        }
        else {
            int leftPriestCount, rightPriestCount, leftDevilCount, rightDevilCount;
            leftPriestCount = leftLandController.GetLand().priestCount ;
            rightPriestCount = rightLandController.GetLand().priestCount;
            leftDevilCount = leftLandController.GetLand().devilCount ;
            rightDevilCount = rightLandController.GetLand().devilCount ;
            if (leftPriestCount != 0 && leftPriestCount < leftDevilCount ){
                this.gameObject.GetComponent<UserGUI>().gameMessage = "Game Over!";
                isRunning = false;
            }
            
            else if( rightPriestCount != 0 && rightPriestCount < rightDevilCount) {
                this.gameObject.GetComponent<UserGUI>().gameMessage = "Game Over!";
                isRunning = false;
            }
        }
    }

    void Awake() {
        SSDirector.GetInstance().CurrentSceneController = this;
        LoadResources();
        this.gameObject.AddComponent<UserGUI>();
    }

    void Update() {

    }
}

 ISceneController.cs 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface ISceneController
{
    void LoadResources();
}

IUserAction.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface IUserAction {
    void MoveBoat();
    void MoveRole(Role roleModel);
    void Check();
}

LandControl.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LandControl
{
    Land landModel;
    public void CreateLand(Vector3 position) {
        if (landModel == null) {
            landModel = new Land(position);
        }
    }
    public Land GetLand() {
        return landModel;
    }

    public Vector3 AddRole(Role roleModel) {
        roleModel.role.transform.parent = landModel.land.transform;
        roleModel.inBoat = false;
        if (roleModel.isPriest) landModel.priestCount++;
        else landModel.devilCount++;
        return Position.role_land[roleModel.id];
    }

    public void RemoveRole(Role roleModel) {
        if (roleModel.isPriest) landModel.priestCount--;
        else landModel.devilCount--;
    }
}

 Move.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Move : MonoBehaviour
{
    public bool isMoving = false;
    public float speed = 5;
    public Vector3 destination;
    public Vector3 mid_destination;
    // Update is called once per frame
    void Update()
    {
        
        if (transform.localPosition == destination) {
            isMoving = false;
            return;
        }
        isMoving = true;
        if (transform.localPosition.x != destination.x && transform
        .localPosition.y != destination.y) {
            transform.localPosition = Vector3.MoveTowards(transform.localPosition, mid_destination, speed * Time.deltaTime);
        }
        else {
            transform.localPosition = Vector3.MoveTowards(transform.localPosition, destination, speed * Time.deltaTime);
        }
    }
}

MoveControl.cs 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MoveCtrl 
{
    GameObject moveObject;
    public bool GetIsMoving() {
        return (moveObject != null && moveObject.GetComponent<Move>().isMoving == true);
    }

    public void SetMove(Vector3 destination, GameObject moveObject) {
        Move test;
        this.moveObject = moveObject;
        if (!moveObject.TryGetComponent<Move>(out test)) {
            moveObject.AddComponent<Move>();
        }

        this.moveObject.GetComponent<Move>().destination = destination;
        if (this.moveObject.transform.localPosition.y > destination.y) {
            this.moveObject.GetComponent<Move>().mid_destination = new Vector3(destination.x, this.moveObject.transform.localPosition.y, destination.z);
        }
        else {
            this.moveObject.GetComponent<Move>().mid_destination = new Vector3(this.moveObject.transform.localPosition.x, destination.y, destination.z);
        }
    }
}

RoleControl.cs 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RoleControl : ClickAction
{
    Role roleModel;
    IUserAction userAction;

    public RoleControl() {
        userAction = SSDirector.GetInstance().CurrentSceneController as IUserAction;

    }

    public void CreateRole(Vector3 position, bool isPriest, int id) {
        if (roleModel != null) {
            Object.DestroyImmediate(roleModel.role);
        }
        roleModel = new Role(position, isPriest, id);
        roleModel.role.GetComponent<Click>().setClickAction(this);
    }

    public Role GetRoleModel() {
        return roleModel;
    }

    public void DealClick() {
        userAction.MoveRole(roleModel);
    }
}

 SSDirector.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SSDirector : System.Object
{
    static SSDirector _instance;
    public ISceneController CurrentSceneController {get; set;}
    public static SSDirector GetInstance() {
        if (_instance == null) {
            _instance = new SSDirector();
        }
        return _instance;
    }
}

View制作代码: 

UserGUI.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UserGUI : MonoBehaviour
{
    IUserAction userAction;
    public string gameMessage ;
    GUIStyle style, bigstyle;
    // Start is called before the first frame update
    void Start()
    {

        userAction = SSDirector.GetInstance().CurrentSceneController as IUserAction;

        style = new GUIStyle();
        style.normal.textColor = Color.white;
        style.fontSize = 30;

        bigstyle = new GUIStyle();
        bigstyle.normal.textColor = Color.white;
        bigstyle.fontSize = 50;

        
        
    }

    // Update is called once per frame
    void OnGUI() {
        userAction.Check();
        GUI.Label(new Rect(160, Screen.height * 0.1f, 50, 200), "Preists and Devils", bigstyle);
        GUI.Label(new Rect(250, 100, 50, 200), gameMessage, style);


    }
}

Model制作代码:

Boat.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Boat
{
    public GameObject boat;//船对象
    public Role[] roles;//船上的角色
    public bool isRight;
    public int priestCount, devilCount;

    public Boat(Vector3 position) {
        boat = GameObject.Instantiate(Resources.Load("Prefabs/Boat", typeof(GameObject))) as GameObject;
        boat.name = "boat";
        boat.transform.position = position;
        boat.transform.localScale = new Vector3(2.8f,0.4f,2);

        roles = new Role[2];
        isRight = false;
        priestCount = devilCount = 0;

        boat.AddComponent<BoxCollider>();
        boat.AddComponent<Click>();
        
    }
}

Click.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Click : MonoBehaviour
{
    ClickAction clickAction;
    public void setClickAction(ClickAction clickAction) {
        this.clickAction = clickAction;
    }
    void OnMouseDown() {
        clickAction.DealClick();
    }
}

 ClickAction.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface ClickAction
{
    void DealClick();
}

Land.cs 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Land 
{
    public GameObject land;
    public int priestCount, devilCount;
    public Land (Vector3 position){
        land = GameObject.Instantiate(Resources.Load("Prefabs/Land", typeof(GameObject))) as GameObject;
        land.transform.position = position;
        priestCount = devilCount = 0;
    }
}

Position.cs 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Position 
{
    public static Vector3 left_land = new Vector3(-8,-3.52f,0);
    public static Vector3 right_land = new Vector3(8,-3.52f,0);
    public static Vector3 river = new Vector3(0,-4,0);
    public static Vector3 left_boat = new Vector3(-2.3f,-3.05f,-0.4f);
    public static Vector3 right_boat = new Vector3(2.3f, -3.05f, -0.4f);

    public static Vector3[] role_land = new Vector3[] {new Vector3(0.4f,0.77f,0), new Vector3(0.228f,0.77f,0), new Vector3(0.058f,0.77f,0), new Vector3(-0.126f,0.77f,0), new Vector3(-0.29f,0.77f,0), new Vector3(-0.44f,0.77f,0)};
    
    // 在船上的位置
    public static Vector3[] role_boat = new Vector3[] {new Vector3(0.2f,2.41f,0), new Vector3(-0.2f,2.41f,0)};


}

River.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class River
{
    public GameObject river;
    public River(Vector3 position) {
        river = GameObject.Instantiate(Resources.Load("Prefabs/river", typeof(GameObject))) as GameObject;
        river.transform.position = position;
        river.name = "river";
    }
}

Role.cs 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Role 
{
    public GameObject role;//model对应的游戏对象
    public bool isPriest;
    public bool inBoat;
    public bool onRight;
    public int id;
    
    public Role (Vector3 position, bool isPriest, int id) {
        this.isPriest = isPriest;
        this.id = id;
        onRight = false;
        inBoat = false;
        role = GameObject.Instantiate(Resources.Load("Prefabs/" + (isPriest ? "Priest" : "Devil"), typeof(GameObject))) as GameObject;
        role.transform.localScale = new Vector3(0.6f,0.6f, 0.6f);
        role.transform.position = position;
        role.name = "role" + id;
        role.AddComponent<Click>();
        role.AddComponent<BoxCollider>();
    }
}

游戏游玩视频:

Unity牧师与魔鬼小游戏游玩_哔哩哔哩_bilibili

猜你喜欢

转载自blog.csdn.net/qq3098320650/article/details/133965010