Combate de unidad - Sacerdote y diablo

Combate de unidad - Sacerdote y diablo

código fuente del proyecto

efecto final

Efecto de juego El cura y el diablo.



descripción de fondo

The Priest and the Devil es un juego de rompecabezas en el que ayudas al sacerdote y al diablo a cruzar el río en un tiempo determinado. Hay tres sacerdotes y tres demonios junto al río. Todos quieren ir al otro lado del río, pero solo hay un bote, y este bote solo puede llevar a dos personas a la vez. Y tiene que haber alguien para dirigir el barco de un lado a otro. En el juego flash, puedes hacer clic en ellos para moverlos y hacer clic en el botón Ir para mover el barco en otra dirección. Si los sacerdotes superan en número a los demonios a ambos lados del río, mueren y se acaba el juego. Puedes probarlo de muchas maneras. ¡Mantén vivos a todos los sacerdotes! ¡Buena suerte!

Objetos

Banco (×2), Río, Barco, Sacerdote, Diablo

tabla de reglas

acción condición evento
haz clic en el personaje El juego no ha terminado y el bote no está lleno y el bote no ha llegado al otro lado suban a bordo
haga clic en el barco El juego no ha terminado y hay al menos una misión a bordo. el barco se mueve a la orilla opuesta

patrón de diseño MVC

inserte la descripción de la imagen aquí

En pocas palabras, es dividir el proyecto en tres niveles: Modelo, Controlador y Vista.

  • Modelo Objeto de datos de almacenamiento
  • Controlador Reciba eventos de usuario, aquí principalmente clics del mouse
  • Ver. Mostrar el modelo y reenviar eventos de interacción humano-computadora

¡comenzar!

establecer el objeto del juego

De acuerdo con el análisis anterior, haz algunos objetos del juego.

El diablo y el sacerdote:
inserte la descripción de la imagen aquí

Xiaohe:

inserte la descripción de la imagen aquí

tierra:

inserte la descripción de la imagen aquí

Bote:

inserte la descripción de la imagen aquí

Arrástrelos a Activos para convertirlos en prefabricados

Modelo

Cree una carpeta de Modelos en Activo para almacenar el script del modelo

Boat.cs: modelo de barco

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>();
        
    }
}

Role.cs: Modelos de personajes, incluidos sacerdotes y demonios.

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

public class Role 
{
    public GameObject role;
    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.7f,0.7f,0.7f);
        role.transform.position = position;
        role.name = "role" + id;
        role.AddComponent<Click>();
        role.AddComponent<BoxCollider>();
    }
}

River.cs:río

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.name = "river";
        river.transform.position = position;
    }
}

Land.cs:tierra

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

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

Position.cs: Para moverse más convenientemente, establezca la ubicación de varios objetos en una clase

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

public class Position
{
    public static Vector3 left_land = new Vector3(-8,-3,0);
    public static Vector3 right_land = new Vector3(8,-3,0);
    public static Vector3 river = new Vector3(0,-4,0);

    // 船在左岸的位置
    public static Vector3 left_boat = new Vector3(-2.3f,-2.3f,-0.4f);

    // 船在右岸的位置
    public static Vector3 right_boat = new Vector3(2.4f, -2.3f, -0.4f);

    // 岸上的角色应该站的位置
    public static Vector3[] role_shore = new Vector3[] {new Vector3(0.4f,0.77f,0), new Vector3(0.2f,0.77f,0), new Vector3(0,0.77f,0), new Vector3(-0.2f,0.77f,0), new Vector3(-0.4f,0.77f,0), new Vector3(-0.6f,0.77f,0)};
    
    // 船上的两个位置
    public static Vector3[] role_boat = new Vector3[] {new Vector3(0.2f,3,0), new Vector3(-0.2f,3,0)};
    
}

Click.cs,ClickAction.cs

Clickhereda ClickActionla interfaz

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.ClickOnObject();
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface ClickAction
{
    void ClickOnObject();
}

Controlador

BoatControl.cs: Controlar el movimiento de la nave

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

// 控制Boat的运动
public class BoatControl : ClickAction
{
    Boat boatModel;
    IUserAction userAction;
    
    // 实现ClickAction接口
    public void ClickOnObject() {
        // 点击船,船移动
        // 通过userAction中的方法实现移动
        // 前置条件:船上有role
        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){
            // boat已经存在
            Object.DestroyImmediate(boatModel.boat);
        }

        boatModel = new Boat(position);
        boatModel.boat.GetComponent<Click>().setClickAction(this);
    }

    public Boat GetBoat(){
        return boatModel;
    }

    // 角色从岸上移动到船上
    public Vector3 AddRole(Role r){
        // 前置条件:船没有满员
        // 如果能上船,角色应到的位置就是船所在的位置
        // 如果不能上船,角色应到的位置就是原来的位置
        int emptySeat = -1;
        if(boatModel.roles[0] == null)  emptySeat = 0;
        else if (boatModel.roles[1] == null)  emptySeat = 1;

        // 船上无空位
        if(emptySeat == -1){
            return r.role.transform.localPosition;
        }
        else{
            boatModel.roles[emptySeat] = r;     // 装到boat上
            r.inBoat = true;
            r.role.transform.parent = boatModel.boat.transform;   // 将role挂在boat下
            if(r.isPriest){
                boatModel.priestCount++;
            }
            else{
                boatModel.devilCount++;
            }
            return Position.role_boat[emptySeat];

        }

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

RoleControl.cs: Controla el movimiento del personaje

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

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

    // 实现ClickAction接口
    public void ClickOnObject() {
        // 点击role,role移动
        userAction.MoveRole(role);
    }

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

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

    }

    public Role GetRole(){
        return role;
    }
}

LandControl.cs

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

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

    public Land GetShore() {
        return land;
    }

    // 将角色加到岸上
    public Vector3 AddRole(Role r){
        r.role.transform.parent = land.land.transform;
        r.inBoat = false;
        if(r.isPriest)  land.priestCount++;
        else  land.devilCount++;

        return Position.role_shore[r.id];
    }

    // 将角色从岸上移除
    public void RemoveRole(Role r){
        if (r.isPriest) land.priestCount--;
        else land.devilCount--;
    }
}

Move.cs, MoveControl.cspara controlar el movimiento

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

public class Move : MonoBehaviour
{
    public bool canMove = false;
    public float speed = 5;
    public Vector3 destination;
    public Vector3 mid_destination;

    void update(){
        if (transform.localPosition == destination) {
            canMove = false;
            return;
        }
        canMove = 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);
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MoveControl
{
    GameObject moveObj;
    // Start is called before the first frame update

    public bool GetIsMoving() {
        return (moveObj != null && moveObj.GetComponent<Move>().canMove == true);
    }

    // Update is called once per frame
    public void SetMove(Vector3 destination, GameObject moveObj)
    {
        Move test;
        this.moveObj = moveObj;
        if (!moveObj.TryGetComponent<Move>(out test)) {
            moveObj.AddComponent<Move>();
        }

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

SSDirector.cs:director

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;
    }
}

ISceneController.cs: Controlar los cambios de escena

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

public interface ISceneController
{
    void LoadResources();
}

IUserAction.cs: controlar eventos de usuario

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

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

FirstController.cs: Un controlador que coordina todo el juego

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 + (boatController.GetBoatModel().isRight ? 0 : boatController.GetBoatModel().priestCount);
            rightPriestCount = rightLandController.GetLand().priestCount + (boatController.GetBoatModel().isRight ? boatController.GetBoatModel().priestCount : 0);
            leftDevilCount = leftLandController.GetLand().devilCount + (boatController.GetBoatModel().isRight ? 0 : boatController.GetBoatModel().devilCount);
            rightDevilCount = rightLandController.GetLand().devilCount + (boatController.GetBoatModel().isRight ? boatController.GetBoatModel().devilCount : 0);
            if (leftPriestCount != 0 && leftPriestCount < leftDevilCount || 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() {
    }
}

Vista

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);
    }
}

Supongo que te gusta

Origin blog.csdn.net/weixin_51930942/article/details/127478770
Recomendado
Clasificación