HW2_空间与运动 MVC架构

一 简答并用程序验证

(1)游戏对象运动的本质

使用矩阵变换(平移,旋转,缩放)改变游戏对象的空间属性,

(2)三种方法实现物体的抛物线运动

Method1:直接修改transform中的position
public class Motion1 : MonoBehaviour {

    // Use this for initialization
    void Start () {
        this.transform.position = new Vector3(0, -5, 0);
    }

    // Update is called once per frame
    void Update () {
        this.transform.position += Vector3.right * Time.deltaTime;
        this.transform.position += Vector3.up * (5 - this.transform.position.x * this.transform.position.x)*Time.deltaTime;
    }
}
Method2:使用Vector3.MoveTowards
void Update () {
    Debug.Log (nowVy + Vy);
    if (nowVy+Vy > 0.00001) {
        Vector3 target = this.transform.position + Vector3.up * Time.deltaTime * nowVy + Vector3.left * Time.deltaTime * Vx;
        this.transform.position = Vector3.MoveTowards (this.transform.position, target, Time.deltaTime);
        nowVy -= 10 * Time.deltaTime;       
    } else {

    }
}
Method3:使用transform.Translate
public float Vx;
public float Vy;

private float nowVy;
private Vector3 speed;
private Vector3 Gravity;

// Use this for initialization
void Start () {
    Gravity = Vector3.zero;
    speed = new Vector3 (Vx, Vy, 0);
}

// Update is called once per frame
void Update () {
    if (2*Vy+Gravity.y > 0.00001) {
        Gravity.y -= 10 * Time.fixedDeltaTime;
        this.transform.Translate (speed*Time.fixedDeltaTime);
        this.transform.Translate (Gravity*Time.fixedDeltaTime);
    } else {

    }
}

(3)写一个程序,实现一个完整的太阳系,其他星球围绕太阳的转速必须不一样,且不在一个法平面上。

直接上代码:

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

public class plantMove : MonoBehaviour
{
    public Transform Sun;
    public Transform Mercury;
    public Transform Venus;
    public Transform Earth;
    public Transform Moon;
    public Transform Mars;
    public Transform Jupiter;
    public Transform Saturn;
    public Transform Uranus;
    public Transform Neptune;
    // Start is called before the first frame update
    void Start () {
        Sun.position = Vector3.zero;
        Mercury.position = new Vector3 (4, 0, 0);
        Venus.position = new Vector3 (6, 0, 0);
        Earth.position = new Vector3 (8, 0, 0);
        Moon.position = new Vector3 (10, 0, 0);
        Mars.position = new Vector3 (12, 0, 0);
        Jupiter.position = new Vector3 (16, 0, 0);
        Saturn.position = new Vector3 (20, 0, 0);
        Uranus.position = new Vector3 (24, 0, 0);
        Neptune.position = new Vector3 (28, 0, 0);
    }

    // Update is called once per frame
    void Update () {
        Vector3 a1 = new Vector3 (0, 9, 2);
        Vector3 a2 = new Vector3 (0, 257, 135);
        Vector3 a3 = new Vector3 (0, 45, 339);
        Vector3 a4 = new Vector3 (0, 4, 9);
        Vector3 a5 = new Vector3 (0, 8, 19);
        Vector3 a6 = new Vector3 (0, 11, 9);
        Vector3 a7 = new Vector3 (0, 6, 137);
        Vector3 a8 = new Vector3 (0, 3, 13);
        Vector3 a9 = new Vector3 (0, 13, 122);
        
        Mercury.RotateAround (Sun.position, a1, 20*Time.deltaTime);
        Mercury.Rotate (Vector3.up*50*Time.deltaTime);

        Venus.RotateAround (Sun.position, a2, 10*Time.deltaTime);
        Venus.Rotate (Vector3.up*30*Time.deltaTime);

        Earth.RotateAround (Sun.position, a3, 10*Time.deltaTime);
        Earth.Rotate (Vector3.up*30*Time.deltaTime);
        Moon.transform.RotateAround (Earth.position, Vector3.up, 359 * Time.deltaTime);

        Mars.RotateAround (Sun.position, a4, 8*Time.deltaTime);
        Mars.Rotate (Vector3.up*30*Time.deltaTime);

        Jupiter.RotateAround (Sun.position, a5, 7*Time.deltaTime);
        Jupiter.Rotate (Vector3.up*30*Time.deltaTime);

        Saturn.RotateAround (Sun.position, a6, 6*Time.deltaTime);
        Saturn.Rotate (Vector3.up*30*Time.deltaTime);

        Uranus.RotateAround (Sun.position, a7, 5*Time.deltaTime);
        Uranus.Rotate (Vector3.up*30*Time.deltaTime);

        Neptune.RotateAround (Sun.position, a8, 4*Time.deltaTime);
        Neptune.Rotate (Vector3.up*30*Time.deltaTime);


    }
}

具体项目跟牧师与魔鬼项目放在一起,下面是太阳系项目的MVC框架:
在这里插入图片描述

二 编程实践—牧师与魔鬼

游戏简介:牧师和魔鬼是一款益智游戏,你将帮助牧师和魔鬼在限定时间内过河。河的一边有三个牧师和三个魔鬼。他们都想去这条河的对岸,但是只有一艘船,这艘船每次只能载两个人。必须有一个人把船从一边开到另一边。在flash游戏中,你可以点击它们移动它们,然后点击go按钮将船移动到另一个方向。如果在河的两边,牧师的人数少于魔鬼,他们就会被杀,游戏就结束了。你可以用许多的方法来尝试。让所有牧师活着!

  1. 游戏中提及的事物(objects):
  • 牧师
  • 魔鬼
  1. 用表格列出玩家动作表(规则表),注意,动作越少越好
    |玩家动作 | 执行条件 |
    |–|--|
    | 牧师/魔鬼上船 | 船上有空位且船在岸边 |
    开船 | 船上有人
    牧师/魔鬼下船 | 船到达岸边

  2. 浅谈MVC架构
    MVC架构(Model View Controller),用一种逻辑,数据,界面显示分离的方法组织代码,将业务聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。它把软件系统分为三个基本部分:

  • M(Model): Unity中,Model就是游戏场景中GameObject、和它们的关系以及后台的数据模型(比如用户信息等),它们都受到相应的Controller的控制
  • V(View): View这部分在游戏中起到的是与用户进行交互的功能,它们负责向用户战术游戏结果,处理GUI事件并通过IUserAction接口来与Controller进行交互。
  • C(Controller): Controller控制着游戏场景中所有的对象,其负责接收来自View的用户的指令并根据用户输入的指令,更新Models以及更新View的状态,其可以被认为是连接Model与View的桥梁。

视图和控制器共同构成了用户接口。且每个视图都有一个相关的控制器组件。控制器接受输入,通常作为将鼠标移动、鼠标按钮的活动或键盘输入编码的时间。时间被翻译成模型或试图的服务器请求。用户仅仅通过控制器与系统交互。
在这里插入图片描述
实现一种动态的程序设计,是后序对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。

  1. 游戏UML框架如下:
    在这里插入图片描述

  2. 接下来基于游戏框架开始编程

Director

导演的职责包括:

  • 获取当前游戏的场景
  • 控制场景运行、切换、入栈与出栈,暂停、恢复、退出
  • 管理游戏全局状态
  • 设定游戏的配置
  • 设定游戏全局视图

在这个游戏中导演主要负责的是获取当前游戏场景,具体代码如下:

public class GameDirector : System.Object {
    private static GameDirector _instance;
    public ISceneController currentSceneController { get; set; }
    public bool running { set; get; }
    
    public static GameDirector getInstance()
    {
        if (_instance == null)
        {
            _instance = new GameDirector();
            return _instance;
        } 
        return _instance;
    }

    public int getFPS()
    {
        return Application.targetFrameRate;
    }

    public void setFPS(int fps)
    {
        Application.targetFrameRate = fps;        
    }
}

Director在运行的时候只有一个实例在运行,在上面的代码中,我们可以看到其应用了单例模式保证只有一个实例生成,方便了类之间的事件通信,方便了MVC的实现。
Director作为游戏最为高层的Controller,其不具体的控制游戏中的任一对象,其通过对currentSceneController的维护,把控制游戏对象的任务交给不同的SceneController。

ISceneController

ISCeneController是游戏中的场景管理器,俗称场记,其主要职责如下:

  • 管理游戏在该游戏场景中的所有的游戏对象
  • 协调游戏对象、游戏对象管理器(GameObjectControllers)之间的通信响应外部输入事件
  • 管理该游戏场景的所有的规则
  • 管理一些其他的东西
    该统一的接口的实现正是GameDirector对各个游戏场景管理的关键,他是导演控制场景的渠道,GameDirector通过对于currentSceneController的维护,可以简单实现游戏场景的各种管理
//interface of Scene

public interface ISceneController
{
    void genGameObjects();
}
IUserAction

IUserAction中体现了游戏编程的门面模式,游戏外部与一个子系统的通信必须通过一个统一的门面对象进行,而我们现在实现的IUserAction就是这样的一个对象,GUI类通过IUserAction来与Controller进行通信,我们通过实现IUserAction接口来定义Controller与GUI的交互,这样我们在实现Controller类时只需要实现IUserAction对应的接口,他就可以与任意使用IUserAction接口的View即GUI类调用,GUI类也是只需调用接口中的方法即可实现与Controller的通信, 方便了我们MVC架构的实现。

public interface IUserAction {
    void restart();
    void ToggleBoat();
    void ClickCharacter(ICharacterController chracter);
}
UserGUI
public class UserGUI : MonoBehaviour {
    public int status = 0;
    private IUserAction action;
    GUIStyle headerStyle;
    GUIStyle buttonStyle;

	// Use this for initialization
	void Start () {
        action = GameDirector.getInstance().currentSceneController as IUserAction;
        headerStyle = new GUIStyle();
        headerStyle.fontSize = 40;
        headerStyle.alignment = TextAnchor.MiddleCenter;
        buttonStyle = new GUIStyle("button");
        buttonStyle.fontSize = 30;
    }
	
	// Update is called once per frame
	void OnGUI () {
        GUI.Label(new Rect(Screen.width / 2 - 100, 10, 200, 50), "Priests & Demons", headerStyle);
        if (status == 1)
        {
            GUI.Label(new Rect(Screen.width / 2 - 45, Screen.height / 2 - 90, 100, 50), "Gameover!", headerStyle);
            if (GUI.Button(new Rect(Screen.width / 2 - 65, Screen.height / 2, 140, 70), "Restart", buttonStyle))
            {
                status = 0;
                action.restart();
            }
        }
        else if (status == 2)
        {
            GUI.Label(new Rect(Screen.width / 2 - 50, Screen.height / 2 - 90, 100, 50), "Win!", headerStyle);
            if (GUI.Button(new Rect(Screen.width / 2 - 70, Screen.height / 2, 140, 70), "Restart", buttonStyle))
            {
                status = 0;
                action.restart();
            }
        }
    }
}

由上我们可以看到,UserGUI只是简单地根据游戏状态,对游戏信息等进行展示,然后通过IUserAction与Controller进行交互,这也是我们在上面所提到的,我们只需要在GUI中调用IUserAction中的方法就可以迅速实现对游戏场景的控制,下面的ClickGUI也是一样

ClickGUI
public class ClickGUI : MonoBehaviour {
    IUserAction action;
    ICharacterController character;

    public void setController(ICharacterController characterController)
    {
        character = characterController;
    }

    void Start()
    {
        action = GameDirector.getInstance().currentSceneController as IUserAction;
    }

    void OnMouseDown()
    {
        if (gameObject.name == "boat")
        {
            action.ToggleBoat();
        }
        else
        {
            action.ClickCharacter(character);
        }
    }
}

在ClickGUI中,我们同样用到了IUserAction, ClickGUI监听事件的发生,然后通过IUserAction提供的类似移动船,游戏角色上下船的函数,把用户指令传给Controller进行执行。从而实现View和Controller之间的交互。

FirstController
public class FirstController : MonoBehaviour, ISceneController, IUserAction {
    readonly Vector3 riverPosition = new Vector3(0, -0.25f, 0);
    UserGUI userGUI;

    public LandController rightLand;
    public LandController leftLand;
    public BoatController boat;
    public ICharacterController[] characters;

    void Awake()
    {
        GameDirector director = GameDirector.getInstance();
        director.currentSceneController = this;
        userGUI = gameObject.AddComponent<UserGUI>() as UserGUI;
        genGameObjects();
    }

    public void genGameObjects()
    {
        characters = new ICharacterController[6];
        GameObject river = Instantiate(Resources.Load("Prefabs/River", typeof(GameObject)), riverPosition, Quaternion.identity, null) as GameObject;
        river.name = "river";

        boat = new BoatController();
        leftLand = new LandController(-1);
        rightLand = new LandController(1);

        for (int i = 0; i < 3; i++)
        {
            ICharacterController priest = new ICharacterController(0, "priest" + i);
            priest.setPosition(rightLand.getEmptyPosition());
            priest.getOnLand(rightLand);
            rightLand.getOnLand(priest);
            characters[i] = priest;
        }

        for (int i = 0; i < 3; i++)
        {
            ICharacterController demon = new ICharacterController(1, "demon" + i);
            demon.setPosition(rightLand.getEmptyPosition());
            demon.getOnLand(rightLand);
            rightLand.getOnLand(demon);
            characters[i+3] = demon;
        }
    }


    public void ClickCharacter(ICharacterController character)
    {
        if (userGUI.status != 0 || !boat.available())
        {
            return;
        }
        if (character.isOnBoat()) {
            LandController land;
            if (boat.getBoatPos() == 0)
            {
                land = leftLand;
            }
            else
            {
                land = rightLand;
            }
            boat.getOffBoat(character.getName());
            character.MoveTo(land.getEmptyPosition());
            character.getOnLand(land);
            land.getOnLand(character);
        }
        else
        {
            LandController land = character.getLandController();
            if (boat.getEmptyIndex() == -1)
                return;
            int landPos = land.getType(), boatPos = (boat.getBoatPos() == 0) ? -1 : 1;
            if (landPos != boatPos)
                return;
            land.getOffLand(character.getName());
            character.MoveTo(boat.getEmptyPosition());
            character.getOnBoat(boat, boat.getEmptyIndex());
            boat.getOnBoat(character);
        }
        userGUI.status = checkResult();
    }

    public void ToggleBoat()
    {
        if (userGUI.status != 0 || boat.isEmptty())
            return;
        boat.Move();
        userGUI.status = checkResult();
    }

    int checkResult()
    {
        int leftPriests = 0;
        int rightPriests = 0;
        int leftDemons = 0;
        int rightDemons = 0;

        int[] leftStatus = leftLand.getStatus();
        leftPriests += leftStatus[0];
        leftDemons += leftStatus[1];

        if (leftPriests + leftDemons == 6)
            return 2;

        int[] rightStatus = rightLand.getStatus();
        rightPriests += rightStatus[0];
        rightDemons += rightStatus[1];

        int[] boatStatus = boat.getBoatStatus();
        if (boat.getBoatPos() == 0)
        {
            leftPriests += boatStatus[0];
            leftDemons += boatStatus[1];
        }
        else
        {
            rightPriests += boatStatus[0];
            rightDemons += boatStatus[1];
        }

        if (leftPriests > 0 && leftPriests < leftDemons)
            return 1;
        if (rightPriests > 0 && rightPriests < rightDemons)
            return 1;

        return 0;
    }

    public void restart()
    {
        boat.reset();
        leftLand.reset();
        rightLand.reset();
        for (int i = 0; i < characters.Length; i++)
            characters[i].reset();
    }
}
Gameobject的move
public class Move : MonoBehaviour {
    readonly float speed = 20;

    int status;//0: 静止, 1: 处于前段移动, 2: 处于后段移动
    Vector3 middle;
    Vector3 destination;

    void Update()
    {
        if (status == 1)
        {
            this.transform.position = Vector3.MoveTowards(this.transform.position, middle, Time.deltaTime * speed);
            if (transform.position == middle)
            {
                status = 2;
            }
        }
        else if (status == 2)
        {
            this.transform.position = Vector3.MoveTowards(this.transform.position, destination, Time.deltaTime * speed);
            if (this.transform.position == destination)
            {
                status = 0;
            }
        }
    }

    public int getStatus()
    {
        return status;
    }

    public  void moveTo(Vector3 _destination)
    {
        destination = _destination;
        middle = _destination;
        if (_destination.y == this.transform.position.y)
        {
            status = 2;
            return;
        }
        else if (_destination.y < this.transform.position.y)
        {
            middle.y = transform.position.y;
        }
        else
        {
            middle.x = transform.position.x;
        }
        status = 1;
    }

    public void reset()
    {
        status = 0;
    }
}

为了让物体不要直接穿过land的墙体,当character上船时,先把物体移动到destination的对应的x坐标,然后再把物体移动到对应的位置,当charcter下船时,先把物体移动到destination的对应的y坐标,然后再把物体移动到对应的位置,这样保证了物体不会穿越墙体进行移动,且实现方式较为简单。

ICharacterController

因为牧师与恶魔的动作等都是一样的,就只是外形、类型不一样,所以我把其抽象为一个Controller,通过type区分它们

public class ICharacterController
{
    readonly GameObject character;
    readonly Move moveAction;
    readonly int type;//0: Priest, 1: Demon
    readonly ClickGUI clickGUI;

    bool onBoat;
    LandController landController;

    public ICharacterController(int chracterType, string name)
    {
        if (chracterType == 0)
        {
            this.character = Object.Instantiate(Resources.Load("Prefabs/Priest", typeof(GameObject)), Vector3.zero, Quaternion.identity, null) as GameObject;
            this.type = 0;
        }
        else
        {
            this.character = Object.Instantiate(Resources.Load("Prefabs/Demon", typeof(GameObject)), Vector3.zero, Quaternion.identity, null) as GameObject;
            this.type = 1;
        }
        character.name = name;
        moveAction = character.AddComponent(typeof(Move)) as Move;
        clickGUI = character.AddComponent(typeof(ClickGUI)) as ClickGUI;
        clickGUI.setController(this);
    }

    public string getName()
    {
        return character.name;
    }

    public void setPosition(Vector3 pos)
    {
        character.transform.position = pos;
    }

    public void MoveTo(Vector3 destination)
    {
        moveAction.moveTo(destination);
    }

    public int getType()
    {
        return type;
    }

    public void getOnBoat(BoatController boatController, int pos)
    {
        landController = null;
        if (pos == 0)
        {
            character.transform.rotation = Quaternion.AngleAxis(90, Vector3.up);
        }
        else
        {
            character.transform.rotation = Quaternion.AngleAxis(270, Vector3.up);
        }
        character.transform.parent = boatController.getBoat().transform;
        onBoat = true;
    }

    public void getOnLand(LandController land)
    {
        landController = land;
        if (land.getType() == -1)
        {
            character.transform.rotation = Quaternion.AngleAxis(90, Vector3.up);
        }
        else
        {
            character.transform.rotation = Quaternion.AngleAxis(270, Vector3.up);
        }
        character.transform.parent = null;
        onBoat = false;
    }

    public bool isOnBoat()
    {
        return onBoat;
    }

    public LandController getLandController()
    {
        return landController;
    }

    public void reset()
    {
        moveAction.reset();
        landController = (GameDirector.getInstance().currentSceneController as FirstController).rightLand;
        getOnLand(landController);
        setPosition(landController.getEmptyPosition());
        landController.getOnLand(this);
    }
}

CharcterController类的实现十分简单,就是根据type导入预制,然后再实现上船,上岸,重置以及一些其他的get, set函数就完成了,具体可以看以上代码的实现。

BoatController
public class BoatController {
    readonly GameObject boat;
    readonly Move moveAction;
    readonly Vector3 right = new Vector3(3.5f, 0, 0);
    readonly Vector3 left = new Vector3(-3.5f, 0, 0);
    readonly Vector3[] right_positions;
    readonly Vector3[] left_positions;

    int status;// 0: left, 1: right
    ICharacterController[] characterOnBoat = new ICharacterController[2];

    public BoatController()
    {
        status = 1;
        right_positions = new Vector3[] { new Vector3(2.5F, 0.2F, 0), new Vector3(4.5F, 0.2F, 0) };
        left_positions = new Vector3[] { new Vector3(-4.5F, 0.2F, 0), new Vector3(-2.5F, 0.2F, 0) };
        boat = Object.Instantiate(Resources.Load("Prefabs/Boat", typeof(GameObject)), right, Quaternion.identity, null) as GameObject;
        boat.name = "boat";
        moveAction = boat.AddComponent(typeof(Move)) as Move;
        boat.AddComponent(typeof(ClickGUI));
    }

    public void Move()
    {
        if (status == 1)
        {
            moveAction.moveTo(left);
        }
        else
        {
            moveAction.moveTo(right);
        }
        status = 1 - status;
    }

    public int getEmptyIndex()
    {
        for (int i = 0; i < characterOnBoat.Length; i++)
        {
            if (characterOnBoat[i] == null)
            {
                return i;
            }
        }
        return -1;
    }

    public Vector3 getEmptyPosition()
    {
        int index = getEmptyIndex();
        if (status == 0)
        {
            return left_positions[index];
        }
        else
        {
            return right_positions[index];
        }
    }

    public bool isEmptty()
    {
        for (int i = 0; i < characterOnBoat.Length; i++)
        {
            if (characterOnBoat[i] != null)
            {
                return false;
            }
        }
        return true;
    }

    public void getOnBoat(ICharacterController character)
    {
        characterOnBoat[getEmptyIndex()] = character;
    }

    public ICharacterController getOffBoat(string name)
    {
        for (int i = 0; i < characterOnBoat.Length; i++)
        {
            if (characterOnBoat[i] != null && characterOnBoat[i].getName() == name)
            {
                ICharacterController character = characterOnBoat[i];
                characterOnBoat[i] = null;
                return character;
            }
        }
        return null;
    }

    public GameObject getBoat()
    {
        return boat;
    }

    public int getBoatPos()
    {
        return status;
    }

    public int[] getBoatStatus()
    {
        int[] boatStatus = { 0, 0 };
        for (int i = 0; i < characterOnBoat.Length; i++)
        {
            if (characterOnBoat[i] == null)
                continue;
            boatStatus[characterOnBoat[i].getType()]++;
        }
        return boatStatus;
    }// 0: Priests, 1: Demon

    public bool available()
    {
        return (moveAction.getStatus() == 0);
    }

    public void reset()
    {
        moveAction.reset();
        if (status == 0)
        {
            Move();
        }
        characterOnBoat = new ICharacterController[2];
    }
}

Boat的实现也差不多,只需要实现初始化、移动(ToggleBoat),character上船、下船相关的函数就可以实现了。

LandController
public class LandController {
    readonly GameObject land;
    readonly Vector3 leftPos = new Vector3(-8.5f, 0f, 0f);
    readonly Vector3 rightPos = new Vector3(8.5f, 0f, 0f);
    readonly Vector3[] landPositions;
    readonly int type;// 1:right, -1: left

    ICharacterController[] characterOnLand;

    public LandController(int _type)
    {
        landPositions = new Vector3[] { new Vector3(6F,0.5F,0), new Vector3(7F,0.5F,0), new Vector3(8F,0.5F,0),
                new Vector3(9F,0.5F,0), new Vector3(10F,0.5F,0), new Vector3(11F,0.5F,0) };

        characterOnLand = new ICharacterController[6];

        type = _type;
        if (type == 1)
        {
            land = Object.Instantiate(Resources.Load("Prefabs/Land", typeof(GameObject)), rightPos, Quaternion.identity, null) as GameObject;
            land.name = "rightLand";
        }
        else
        {
            land = Object.Instantiate(Resources.Load("Prefabs/Land", typeof(GameObject)), leftPos, Quaternion.identity, null) as GameObject;
            land.name = "leftLand";
        }
    }

    public Vector3 getEmptyPosition()
    {
        Vector3 pos = landPositions[getEmptyIndex()];
        pos.x *= type;
        return pos;
    }

    public int getEmptyIndex()
    {
        for (int i = 0; i < characterOnLand.Length; i++)
        {
            if (characterOnLand[i] == null)
                return i;
        }
        return -1;
    }

    public void getOnLand(ICharacterController chracter)
    {
        characterOnLand[getEmptyIndex()] = chracter;
    }

    public ICharacterController getOffLand(string name)
    {
        for (int i = 0; i < characterOnLand.Length; i++)
        {
            if (characterOnLand[i] != null && characterOnLand[i].getName() == name)
            {
                ICharacterController tmp = characterOnLand[i];
                characterOnLand[i] = null;
                return tmp;
            }
        }
        return null;
    }

    public int getType()
    {
        return type;
    }

    public int[] getStatus()
    {
        int[] status = { 0, 0 };
        for (int i = 0; i < characterOnLand.Length; i++)
        {
            if (characterOnLand[i] == null)
                continue;
            status[characterOnLand[i].getType()]++;
        }
        return status;
    }// 0: priests, 1: Demon

    public void reset()
    {
        characterOnLand = new ICharacterController[6];
    }
}

landController的实现和上面的Controller也类似,也是实现初始化,上岸,下岸的相关函数就完成了

这次游戏的实现将接口和Director放在同一个脚本的同一命名空间下,所以总共只有三个脚本,等之后对项目进行扩展时再进行扩充

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值