Sistema Solar Simple y Sacerdotes y Demonios

Juego 3D tarea 3

1. Usa Unity para crear un sistema solar completo

Requisitos : Las velocidades de rotación de los planetas alrededor del sol deben ser diferentes y no en el mismo plano normal.

Proceso : primero encuentre las texturas de los planetas en el sistema solar y cárguelas en los recursos del proyecto. [URL de las texturas del planeta] ( texturas solares | alcance del sistema solar )

  1. Crea varias Esferas y nómbralas con los nombres de cada planeta del sistema solar, y luego arrastra cada textura al planeta correspondiente, formando así el prefabricado de cada planeta.

inserte la descripción de la imagen aquí

  1. Arrastra cada planeta a su posición correspondiente en el sistema solar con el sol como centro y establece el tamaño.

inserte la descripción de la imagen aquí

  1. Agregue un efecto de fuente de luz al sol, es decir, agregue un punto de luz en la posición del sol para lograr el efecto de fuente de luz y ajuste el color de la luz a naranja-amarillo.

inserte la descripción de la imagen aquí

  1. El sol se ve un poco oscuro en este punto, por lo que debemos hacer que la superficie del sol brille.

Compruebe el componente de textura Emisión del sol y establezca el color en rojo anaranjado.

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

  1. Usa el código para hacer que los planetas giren alrededor del sol y la luna gire alrededor de la tierra.

Cabe señalar que si la rotación alrededor de un planeta giratorio se verá afectada por la rotación del planeta , es necesario clonar un sol y la tierra y hacer que estos dos planetas clonados no giren, y configurar los objetos de otros planetas para que giren. alrededor de estos dos planetas que no giran.

  1. Para poder mostrar la trayectoria del planeta, es necesario agregar un Render de prueba de componente a cada planeta, la ubicación específica es Componente->Efectos->Render de prueba.

El diagrama de efecto de ejecución después de agregar es el siguiente

inserte la descripción de la imagen aquí

Se puede ver que los planetas orbitan en diferentes planos normales.

el código se muestra a continuación.

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

public class Rotate : MonoBehaviour {
	public Transform mercury;
	public Transform venus;
	public Transform earth;
	public Transform mars;
	public Transform jupiter;
	public Transform saturn;
	public Transform uranus;
	public Transform neptune;
	public Transform moon;
	public Transform earthclone;
	public Transform sun;
	// Use this for initialization
	void Start () {
        mercury = this.transform.Find("Mercury");
		venus = this.transform.Find("Venus");
		earth = this.transform.Find("Earth");
		mars = this.transform.Find("Mars");
		jupiter = this.transform.Find("Jupiter");
		saturn = this.transform.Find("Saturn");
		uranus = this.transform.Find("Uranus");
		neptune = this.transform.Find("Neptune");
		earthclone = this.transform.Find("EarthClone");
		moon = earthclone.Find("Moon");
		sun = this.transform.Find("Sun");
	}
	
	// Update is called once per frame
	void Update () {
		sun.Rotate(Vector3.up * Time.deltaTime * 30);
		mercury.RotateAround(this.transform.position, new Vector3(1, 5, 0), 24 * Time.deltaTime);
		mercury.Rotate(Vector3.up * Time.deltaTime * 300);
		venus.RotateAround(this.transform.position, new Vector3(2, 12, 0), 33 * Time.deltaTime);
		venus.Rotate(Vector3.up * Time.deltaTime * 280);
		earth.RotateAround(this.transform.position, new Vector3(1, 10, 0), 19 * Time.deltaTime);
		earth.Rotate(Vector3.up * Time.deltaTime * 250);
		mars.RotateAround(this.transform.position, new Vector3(2, 11, 0), 24 * Time.deltaTime);
		mars.Rotate(Vector3.up * Time.deltaTime * 220);
		jupiter.RotateAround(this.transform.position, new Vector3(1, 10, 0), 13 * Time.deltaTime);
		jupiter.Rotate(Vector3.up * Time.deltaTime * 180);
		saturn.RotateAround(this.transform.position, new Vector3(1, 11, 0), 10 * Time.deltaTime);
		saturn.Rotate(Vector3.up * Time.deltaTime * 160);
		uranus.RotateAround(this.transform.position, new Vector3(2, 7, 0), 18 * Time.deltaTime);
		uranus.Rotate(Vector3.up * Time.deltaTime * 150);
		neptune.RotateAround(this.transform.position, new Vector3(3, 10, 0), 22 * Time.deltaTime);
		neptune.Rotate(Vector3.up * Time.deltaTime * 140);
		earthclone.RotateAround(this.transform.position, new Vector3(1, 10, 0), 30 * Time.deltaTime);
		moon.transform.RotateAround (earthclone.transform.position, new Vector3(1, 12, 0), 50 * Time.deltaTime);
	}
}

Mini juego El cura y el diablo

instrucciones del juego

Priests and Devils
Priests and Devils es un juego de rompecabezas en el que ayudarás a los sacerdotes y demonios a "cruzar el río dentro del límite de tiempo". Hay 3 sacerdotes y 3 demonios en un lado del río. Todos quieren llegar al río. otro lado de este río, pero solo hay un bote y este bote solo puede transportar a dos personas cada vez. Y debe haber una persona dirigiendo el bote de un lado al otro. En el juego flash, puedes hacer clic en ellos para Muévelos y haz clic en el botón "Ir" para mover el bote a la otra dirección. Si los sacerdotes son superados en número por los demonios a ambos lados del río, los matarán y el juego terminará. Puedes intentarlo de muchas maneras. ¡Todos los sacerdotes vivos! ¡Buena suerte!

  1. cosas mencionadas en el juego

El cura, el diablo, la barca, el río, las orillas a ambos lados.

  1. Enumerar las acciones del jugador en una tabla
acción Efecto condición
El jugador hace clic en el personaje de la orilla. personaje a bordo 1. El barco tiene una posición 2. Los personajes están en la misma orilla 3. Ningún otro personaje se mueve
El jugador hace clic en el personaje en el barco. desembarco del personaje 1. El barco ha llegado a la orilla 2. No se mueven otros personajes
el jugador hace clic en el barco el barco se mueve a la orilla opuesta 1. Cualquier personaje a bordo 2. Ningún otro personaje se mueve
El jugador hace clic para reiniciar Todos los personajes se reinician
  1. Convierte cada objeto de personaje en un prefabricado.

Usa una bola con textura de sacerdote para representar a un sacerdote y un cuadrado con textura de demonio para representar a un demonio.

inserte la descripción de la imagen aquí

  1. Cargue los objetos en el juego en el método LoadResources del controlador de escena

controlador de escena

inserte la descripción de la imagen aquí

El código LoadResources correspondiente es el siguiente

public void LoadResources(){
        //由于有重新开始按钮,所以如果不是第一次加载得把之前的物体摧毁
        if(flag){
            for(int i = 0; i < 6; i++){
                if(roleCtrl_list[i] != null){
                    Destroy(roleCtrl_list[i].GetModelGameObject());
                }
            }
            for(int i = 0; i < 2; i++){
                if(landCtrl_list[i] != null){
                    Destroy(landCtrl_list[i].GetModelGameObject());
                }
            }
            if(BoatCtrl != null){
                Destroy(BoatCtrl.GetModelGameObject());
            }
        }
        // 加载控制器和模型
        BoatCtrl = new BoatController();
        BoatCtrl.CreateModel();
        water1=new Water(new Vector3(0,-3.5f,12));
        for(int i = 0; i < 6; i++){
            int roleType = (i < 3) ? PRIEST : DEVIL;
            RoleController tmp=new RoleController(roleType, rolesID[i]);
            roleCtrl_list.Add(tmp);
            roleCtrl_list[i].CreateModel();
        }
        LandController tmp1 = new LandController(LEFTLAND, rolesID);
        landCtrl_list.Add(tmp1);
        LandController tmp2 = new LandController(RIGHTLAND, rolesID);
        landCtrl_list.Add(tmp2);
        landCtrl_list[0].CreateModel();
        landCtrl_list[1].CreateModel();
        MoveCtrl = new MoveController();
        flag=true;
        flag1=false;
        //开始游戏
        gameState = PLAYING;
    }

    //将角色的ID转换成数组的下标
    int IDToNumber(int ID){
        for(int i = 0; i < 6; i++){
            if(rolesID[i] == ID){
                return i;
            }
        }
        return -1;
    }

    //点击船时执行
    public void MoveBoat(){
        if(BoatCtrl.getEmptySeat()==0)
        {
            flag1=true;
        }
        else{
            if(gameState != PLAYING || MoveCtrl.IsMoving()) return;
            CheckAndSetGameState();
            if(BoatCtrl.onLeftside){
                MoveCtrl.SetMove(BoatCtrl.GetModelGameObject(), Position.boatRightPos);
                for(int i = 0; i < 2; i++){
                    if(BoatCtrl.seat[i] != -1){
                        RoleController r = roleCtrl_list[IDToNumber(BoatCtrl.seat[i])];
                        MoveCtrl.SetMove(r.GetModelGameObject(), Position.seatRightPos[i]);
                    }
                }
            }
            else{
                MoveCtrl.SetMove(BoatCtrl.GetModelGameObject(), Position.boatLeftPos);
                for(int i = 0; i < 2; i++){
                    if(BoatCtrl.seat[i] != -1){
                        RoleController r = roleCtrl_list[IDToNumber(BoatCtrl.seat[i])];
                        MoveCtrl.SetMove(r.GetModelGameObject(), Position.seatLeftPos[i]);
                    }
                } 
            }
            BoatCtrl.onLeftside = !BoatCtrl.onLeftside;
        }
    }
  1. Organizar objetos usando el tipo de colección List

    Por ejemplo, use la lista a continuación para organizar la clase de control de personajes y la clase de control de tierra.

inserte la descripción de la imagen aquí

  1. Objeto generado por código

    antes del juego

    inserte la descripción de la imagen aquí

    después de que comience el juego

inserte la descripción de la imagen aquí

  1. Presentar el marco MVC utilizado en este juego

    7.1 Modelos modelo

    ​ 7.1.1 Script de clic

    ​ La clase Click proporciona principalmente un componente funcional para otras clases de objetos en los que es necesario hacer clic.

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

    7.1.2 Clase de puesto

    ​ Las variables miembro de la clase Position se utilizan para almacenar las posiciones de otros objetos, para modificar las posiciones de otros objetos solo es necesario modificar las variables miembro en Position.

    ​ 7.1.3 Otras clases de objetos como tierra y rol.

    ​ Estas clases son principalmente para cargar objetos prefabricados, si se necesita hacer clic en el objeto, agregue el componente Click mencionado anteriormente, y los eventos que ocurren después del clic se definirán en detalle en el control posterior. Aquí tomamos la clase Boat como ejemplo.

    public class Boat
    {
        public GameObject boat;//船对象
        public Boat(Vector3 initPos){
            boat = GameObject.Instantiate(Resources.Load("Prefabs/boat", typeof(GameObject))) as GameObject;
            boat.transform.position = initPos;
            boat.AddComponent<Click>();
        }
    }
    

    7.2 Controlador controlador

    7.2.1 Objeto director

    Aquí se adopta el modo de instancia única y la clase Director se usa principalmente para obtener la escena actual del juego, administrar el estado global del juego, etc. Se creará un nuevo objeto Director en la primera llamada y no se creará ningún objeto nuevo en las llamadas posteriores, pero se devolverá el objeto creado en la primera llamada, por lo que solo habrá un Director globalmente, lo cual es conveniente para la administración global. .

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

​ 7.2.2 IUserAcción

​ IUserAction es una interfaz de objeto de usuario para recibir acciones del jugador, que separa las operaciones del jugador de la lógica interna del juego para facilitar la gestión.

public interface IUserAction {
    void MoveBoat();
    void MoveRole(int id);
    int GetGameState();
    void Restart();
}

​ 7.2.3 ISceneController

ISceneController es una interfaz de control de escena. Esta interfaz separa el control del director y la escena. El director no necesita saber cómo implementar el control de escena, solo necesita dejar que la clase de control de escena realice una determinada tarea.

public interface ISceneController
{
    void Initialize();
    void LoadResources();
}

7.2.4 Varias clases de control de objetos como BoatController y LandController

​ Estas clases de control de objetos necesitan definir las propiedades de cada objeto y usar funciones para implementar las acciones que cada objeto necesita completar. A continuación se toma BoatController como ejemplo, y se pueden consultar otras clases de control de objetos en el código.

​ Las propiedades requeridas de la clase BoatController:

​ 1. La variable onLeftside de tipo bool se utiliza para determinar si el barco está en la margen izquierda.

​ 2. El asiento de matriz del tipo Lista con una longitud de 2 se utiliza para registrar los números de los caracteres en dos posiciones en el barco.

3. El modelo de barco del objeto de clase de barco, cargado con objetos prefabricados.

​ Acciones que deben ser completadas por la clase BoatController:

1.Reset() Restablece los asientos del barco.

2.embark(int rolID) Embarca el rol numerado roleID.

​ 3.getEmptySeat() Obtiene el subíndice del asiento vacío, si no, devuelve -1.

​ 4. desembarcar(int rolID) Desembarca el rol numerado roleID.

5.DealClick() maneja el evento de clic.

6. GetModelGameObject() devuelve el objeto barco.

7.CreateModel() Crea un modelo.

​ 7.2.5 Primer controlador

​ FirstController es el controlador principal, su tarea principal es administrar todos los objetos del juego, responder a eventos externos, diseñar la lógica interna del juego, etc., y definir varios eventos al mismo tiempo.

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

public class FirstController : MonoBehaviour, ISceneController, IUserAction
{

    public static int LEFTLAND = 0;
    public static int RIGHTLAND = 1;
    public static int BOAT = 2;
    public static bool flag = false;
    public static bool flag1=false;
    public static int PRIEST = 0;
    public static int DEVIL = 1;
    public static int PLAYING = 0;
    public static int WIN = 1;
    public static int FAILED = 2;
    Water water1;
    BoatController BoatCtrl;
    public List<RoleController> roleCtrl_list=new List<RoleController>();
    public List<LandController> landCtrl_list=new List<LandController>();
    MoveController MoveCtrl;

    int[] rolesID = new int[6]{0,1,2,3,4,5};
    int gameState;

    void Awake(){
        SSDirector director = SSDirector.GetInstance();
        director.CurrentSceneController = this;
        director.CurrentSceneController.LoadResources();
    }
    public void Initialize()
    {
        LoadResources();
    }
    public void LoadResources(){
        //由于有重新开始按钮,所以如果不是第一次加载得把之前的物体摧毁
        if(flag){
            for(int i = 0; i < 6; i++){
                if(roleCtrl_list[i] != null){
                    Destroy(roleCtrl_list[i].GetModelGameObject());
                }
            }
            for(int i = 0; i < 2; i++){
                if(landCtrl_list[i] != null){
                    Destroy(landCtrl_list[i].GetModelGameObject());
                }
            }
            if(BoatCtrl != null){
                Destroy(BoatCtrl.GetModelGameObject());
            }
        }
        // 加载控制器和模型
        BoatCtrl = new BoatController();
        BoatCtrl.CreateModel();
        water1=new Water(new Vector3(0,-3.5f,12));
        for(int i = 0; i < 6; i++){
            int roleType = (i < 3) ? PRIEST : DEVIL;
            RoleController tmp=new RoleController(roleType, rolesID[i]);
            roleCtrl_list.Add(tmp);
            roleCtrl_list[i].CreateModel();
        }
        LandController tmp1 = new LandController(LEFTLAND, rolesID);
        landCtrl_list.Add(tmp1);
        LandController tmp2 = new LandController(RIGHTLAND, rolesID);
        landCtrl_list.Add(tmp2);
        landCtrl_list[0].CreateModel();
        landCtrl_list[1].CreateModel();
        MoveCtrl = new MoveController();
        flag=true;
        flag1=false;
        //开始游戏
        gameState = PLAYING;
    }

    //将角色的ID转换成数组的下标
    int IDToNumber(int ID){
        for(int i = 0; i < 6; i++){
            if(rolesID[i] == ID){
                return i;
            }
        }
        return -1;
    }

    //点击船时执行
    public void MoveBoat(){
        if(BoatCtrl.getEmptySeat()==0)
        {
            flag1=true;
        }
        else{
            if(gameState != PLAYING || MoveCtrl.IsMoving()) return;
            CheckAndSetGameState();
            if(BoatCtrl.onLeftside){
                MoveCtrl.SetMove(BoatCtrl.GetModelGameObject(), Position.boatRightPos);
                for(int i = 0; i < 2; i++){
                    if(BoatCtrl.seat[i] != -1){
                        RoleController r = roleCtrl_list[IDToNumber(BoatCtrl.seat[i])];
                        MoveCtrl.SetMove(r.GetModelGameObject(), Position.seatRightPos[i]);
                    }
                }
            }
            else{
                MoveCtrl.SetMove(BoatCtrl.GetModelGameObject(), Position.boatLeftPos);
                for(int i = 0; i < 2; i++){
                    if(BoatCtrl.seat[i] != -1){
                        RoleController r = roleCtrl_list[IDToNumber(BoatCtrl.seat[i])];
                        MoveCtrl.SetMove(r.GetModelGameObject(), Position.seatLeftPos[i]);
                    }
                } 
            }
            BoatCtrl.onLeftside = !BoatCtrl.onLeftside;
        }
    }

    //角色被点击
    public void MoveRole(int id){
        flag1=false;
        int num = IDToNumber(id);
        if(gameState != PLAYING || MoveCtrl.IsMoving()) return;
        int seat;
        switch(roleCtrl_list[num].roleState){
            //角色在左岸的情况
            case 0: 
                if(!BoatCtrl.onLeftside) return;
                landCtrl_list[0].LeaveLand(id);
                seat = BoatCtrl.embark(id);
                roleCtrl_list[num].GoTo(BOAT);
                if(seat == -1) return;
                MoveCtrl.SetMove(roleCtrl_list[num].GetModelGameObject(), Position.seatLeftPos[seat]);
                break;
            //角色在右岸的情况
            case 1: 
                if(BoatCtrl.onLeftside) return;
                landCtrl_list[1].LeaveLand(id);
                seat = BoatCtrl.embark(id);
                roleCtrl_list[num].GoTo(BOAT);
                if(seat == -1) return;
                MoveCtrl.SetMove(roleCtrl_list[num].GetModelGameObject(), Position.seatRightPos[seat]);
                break;
            //角色在船上的情况
            case 2:
                if(BoatCtrl.onLeftside){
                    seat = landCtrl_list[0].getEmptySeat();
                    BoatCtrl.disembark(id);
                    landCtrl_list[0].GoOnLand(id);
                    roleCtrl_list[num].GoTo(LEFTLAND);
                    MoveCtrl.SetMove(roleCtrl_list[num].GetModelGameObject(), Position.roleLeftPos[seat]);
                }
                else{
                    seat = landCtrl_list[1].getEmptySeat();
                    BoatCtrl.disembark(id);
                    landCtrl_list[1].GoOnLand(id);
                    roleCtrl_list[num].GoTo(RIGHTLAND);
                    MoveCtrl.SetMove(roleCtrl_list[num].GetModelGameObject(), Position.roleRightPos[seat]);
                }
                break;
            default: break;
        }
    }

    //判断游戏状态
    public void CheckAndSetGameState(){
        if(gameState != PLAYING) return;
        //失败的情况
        int[,] rolePos = new int[2, 3]{
   
   {0, 0, 0}, {0, 0, 0}};
        foreach(RoleController r in roleCtrl_list){
            rolePos[r.roleType, r.roleState]++;
        }
        if((rolePos[0,0]>0 && rolePos[0,0]<rolePos[1,0]) ||  (rolePos[0,1]>0 && rolePos[0,1]<rolePos[1,1]) ||(rolePos[0,2]>0 && rolePos[0,2] < rolePos[1,2])){
            gameState = FAILED;
            return;
        }  
        //成功的情况
        foreach(RoleController r in roleCtrl_list){
            if(r.roleType == 0 && r.roleState != RIGHTLAND){
                return;
            }
        }
        gameState = WIN;
        return;
    }

    //重置
    public void Restart(){
        LoadResources();
        gameState = PLAYING;
    }

    //获取游戏当前状态
    public int GetGameState(){
        return gameState;
    }
}

7.3 Ver vista

UserGUI es la interfaz del programa de usuario, que se utiliza para presentar la pantalla del juego y varios botones al usuario.

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

public class UserGUI : MonoBehaviour
{
    IUserAction userAction;
    GUIStyle msgStyle, titleStyle;
    void Start()
    {
        userAction = SSDirector.GetInstance().CurrentSceneController as IUserAction;

        msgStyle = new GUIStyle();
        msgStyle.normal.textColor = Color.red;
        msgStyle.alignment = TextAnchor.MiddleCenter;
        msgStyle.fontSize = 30;

        titleStyle = new GUIStyle();
        titleStyle.normal.textColor = Color.black;
        titleStyle.alignment = TextAnchor.MiddleCenter;
        titleStyle.fontSize = 40;
    }

    // Update is called once per frame
    void OnGUI() {
        // 重新开始的按钮
        if(GUI.Button(new Rect(Screen.width*0.4f, Screen.height*0.85f, Screen.width*0.2f, Screen.height*0.1f), "重新开始")){
            userAction.Restart();
        }
        // 检查是否正确
        GUI.Label(new Rect(0, 0, Screen.width, Screen.height*0.2f), "牧师与恶魔", titleStyle);
        if(userAction.GetGameState() == FirstController.WIN){
            GUI.Label(new Rect(0, Screen.height*0.2f, Screen.width, Screen.height*0.2f), "成功", msgStyle);
        }     
        else if(userAction.GetGameState() == FirstController.FAILED){
            GUI.Label(new Rect(0, Screen.height*0.2f, Screen.width, Screen.height*0.2f), "失败", msgStyle);
        }
        if(FirstController.flag1==true)
        {
            GUI.Label(new Rect(0, Screen.height*0.2f, Screen.width, Screen.height*0.2f), "船为空,不能行动", msgStyle);
        }
    }
}

pantalla de juego

inserte la descripción de la imagen aquí
codigo direccion mi almacen

Supongo que te gusta

Origin blog.csdn.net/weixin_52801288/article/details/127373917
Recomendado
Clasificación