hw4-遊戲對象與圖形基礎作業

基本演練操作

1.下載 Fantasy Skybox FREE, 構建自己的遊戲場景

  • 建立天空盒
    製作一個 6 面體材料 ,點擊菜單 Assets - create - Material,再點擊Inspector - shader - skybox - 6 sided ,按前後、上下、左右拖入 6 個圖片 - 製作完成,拖入項目 Material 目錄 。
    在這裏插入圖片描述
  • 構造草地樹木
    點擊菜單 - Game object - 3d object - Terrain 建立地形。然後根據地形設計工具箱來種樹種草。
    在這裏插入圖片描述
  • 效果圖
    簡單地建了一些山草樹木。
    在這裏插入圖片描述

2.寫一個簡單的總結,總結遊戲對象的使用

  • 遊戲對象的生成:遊戲對象可以通過代碼動態生成,也可以直接在Unity3D的界面中創建生成。
  • 改變遊戲對象的狀態(動作、位移等):通過在代碼中調整相應的參數改變遊戲對象的狀態。
  • 遊戲對象的部件:在Unity3D的界面中可以添加遊戲對象的部件,如聲音、效果、事件、UI、視頻等。

編程實踐

  • 【牧師與魔鬼 動作分離版】
    【新要求】:設計一個裁判類,當遊戲達到結束條件時,通知場景控制器遊戲結束

1.動作分類
根據上次作業的設計,把遊戲對象的主要動作分爲以下幾類:

動作 功能
CCActionManager 具體動作作爲類中的一個對象從而管理動作,同時繼承SSActionManager
CCBoatMoving 船移動的具體方法,繼承SSAction,將GenGameObject作爲其中一個對象
CCGetOffBoat 牧師或魔鬼對象下船的具體方法,繼承SSAction,其中的對象有int型判斷河岸,與GameObject型對象接收具體作用的遊戲對象
CCGetOnTheBoat 牧師或魔鬼對象上船的具體方法,繼承SSAction,其中的對象有GameObject型接收具體作用的遊戲對象

2.CCActionManager
CCActionManager是對具體遊戲事件的控制,其中包含三個方法:Start(),Update(),和SSActionEvent()。Start()方法中用於將SSDirector實例化,Update()方法中用於實現具體的遊戲事件,SSActionEvent()方法則是接口ISSActionCallback中的。
具體代碼如下:

public class CCActionManager : SSActionManager, ISSActionCallback
{
    public GenGameObject sceneController;
    public CCGetOnTheBoat getonA;
    public CCGetOffBoat getoffB;
    public CCBoatMoving boatmovingC;

    // Use this for initialization
    protected void Start()
    {
        sceneController = (GenGameObject)SSDirector.getInstance().currentScenceController;
        sceneController.actionManager = this;
    }

    // Update is called once per frame
    protected new void Update()
    {
        if (Input.GetMouseButtonDown(0) && sceneController.game == 0)
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                if (hit.transform.tag == "Devil" || hit.transform.tag == "Priest")
                {
                    if (hit.collider.gameObject == sceneController.boat[0] || hit.collider.gameObject == sceneController.boat[1])
                    {
                        if (hit.collider.gameObject == sceneController.boat[0])
                        {
                            getoffB = CCGetOffBoat.GetSSAction(0);
                            this.RunAction(hit.collider.gameObject, getoffB, this);
                        }
                        else
                        {
                            getoffB = CCGetOffBoat.GetSSAction(1);
                            this.RunAction(hit.collider.gameObject, getoffB, this);
                        }
                    }
                    else
                    {
                        getonA = CCGetOnTheBoat.GetSSAction();
                        this.RunAction(hit.collider.gameObject, getonA, this);
                    }
                }
                else if (hit.transform.tag == "Boat" && sceneController.boatCapacity != 2)
                {
                    print(hit.transform.tag);
                    boatmovingC = CCBoatMoving.GetSSAction();
                    this.RunAction(hit.collider.gameObject, boatmovingC, this);
                }
            }
        }
        base.Update();
    }

    public void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Competeted,
        int intParam = 0, string strParam = null, Object objectParam = null)
    {
        //
    }
}

3.船的動作
船的事件類有三個,分別是,CCBoatMoving、CCGetOffBoat和CCGetOnTheBoat。這三個具體的類全都繼承SSAction類,也同時在Start()函數中實例化了SSDirector。在Update中則是各自完成各自操作的。
【CCBoatMoving】

\\CCBoatMoving
public class CCBoatMoving : SSAction
{
   public GenGameObject sceneController;

   public static CCBoatMoving GetSSAction()
   {
       CCBoatMoving action = ScriptableObject.CreateInstance<CCBoatMoving>();
       return action;
   }
   // Use this for initialization
   public override void Start()
   {
       sceneController = (GenGameObject)SSDirector.getInstance().currentScenceController;
   }

   // Update is called once per frame
   public override void Update()
   {
       if (sceneController.boat_position == 1)
       {
           sceneController.boat_position = 0;
           while (this.transform.position != sceneController.boatStartPos)
               this.transform.position = Vector3.MoveTowards(this.transform.position, sceneController.boatStartPos, 1);
       }
       else if (sceneController.boat_position == 0)
       {
           sceneController.boat_position = 1;
           while (this.transform.position != sceneController.boatEndPos)
               this.transform.position = Vector3.MoveTowards(this.transform.position, sceneController.boatEndPos, 1);
       }
       sceneController.check();
       this.destroy = true;
       this.callback.SSActionEvent(this);
   }
}

【CCGetOffBoat】

public class CCGetOffBoat : SSAction
{
    public int side;
    public GenGameObject sceneController;
    public static CCGetOffBoat GetSSAction(int side)
    {
        CCGetOffBoat action = ScriptableObject.CreateInstance<CCGetOffBoat>();
        action.side = side;
        return action;
    }
    // Use this for initialization
    public override void Start()
    {
        sceneController = (GenGameObject)SSDirector.getInstance().currentScenceController;
    }

    // Update is called once per frame
    public override void Update()
    {
        if (sceneController.boat[side] != null)
        {
            sceneController.boat[side].transform.parent = null;
            if (sceneController.boat_position == 1)
            {

                if (sceneController.boat[side].transform.tag == "Priest")
                {
                    for (int i = 0; i < 3; i++)
                    {
                        if (sceneController.priests_end[i] == null)
                        {
                            sceneController.priests_end[i] = sceneController.boat[side];
                            sceneController.boatCapacity++;
                            break;
                        }
                    }
                }
                else if (sceneController.boat[side].transform.tag == "Devil")
                {
                    for (int i = 0; i < 3; i++)
                    {
                        if (sceneController.devils_end[i] == null)
                        {
                            sceneController.devils_end[i] = sceneController.boat[side];
                            sceneController.boatCapacity++;
                            break;
                        }
                    }
                }
            }
            else if (sceneController.boat_position == 0)
            {
                if (sceneController.boat[side].transform.tag == "Priest")
                {
                    for (int i = 0; i < 3; i++)
                    {
                        if (sceneController.priests_start[i] == null)
                        {
                            sceneController.priests_start[i] = sceneController.boat[side];
                            sceneController.boatCapacity++;
                            break;
                        }
                    }
                }
                else if (sceneController.boat[side].transform.tag == "Devil")
                {
                    for (int i = 0; i < 3; i++)
                    {
                        if (sceneController.devils_start[i] == null)
                        {
                            sceneController.devils_start[i] = sceneController.boat[side];
                            sceneController.boatCapacity++;
                            break;
                        }
                    }
                }
            }
            sceneController.boat[side] = null;
        }
        sceneController.check();
        this.destroy = true;
        this.callback.SSActionEvent(this);
    }
}

【CCGetOnTheBoat】

public class CCGetOnTheBoat : SSAction
{
    public GenGameObject sceneController;

    public static CCGetOnTheBoat GetSSAction()
    {
        CCGetOnTheBoat action = ScriptableObject.CreateInstance<CCGetOnTheBoat>();
        return action;
    }
    // Use this for initialization
    public override void Start()
    {
        sceneController = (GenGameObject)SSDirector.getInstance().currentScenceController;
    }

    // Update is called once per frame
    public override void Update()
    {
        if (sceneController.boatCapacity != 0)
        {
            if (sceneController.boat_position == 0)
            {
                for (int i = 0; i < 3; i++)
                {
                    if (sceneController.devils_start[i] == gameobject)
                    {
                        sceneController.devils_start[i] = null;
                        sceneController.find = 1;
                    }
                    if (sceneController.priests_start[i] == gameobject)
                    {
                        sceneController.priests_start[i] = null;
                        sceneController.find = 1;
                    }
                }
            }
            else if (sceneController.boat_position == 1)
            {
                for (int i = 0; i < 3; i++)
                {
                    if (sceneController.devils_end[i] == gameobject)
                    {
                        sceneController.devils_end[i] = null;
                        sceneController.find = 1;
                    }
                    if (sceneController.priests_end[i] == gameobject)
                    {
                        sceneController.priests_end[i] = null;
                        sceneController.find = 1;
                    }
                }
            }

            if (sceneController.find == 1)
                gameobject.transform.parent = sceneController.boat_obj.transform;

            if (sceneController.boat[0] == null && sceneController.find == 1)
            {
                sceneController.boat[0] = gameobject;
                sceneController.boat[0].transform.tag = gameobject.transform.tag;
                sceneController.boatCapacity--;
                this.transform.localPosition = new Vector3(0, 1.2f, 0.19f);
            }
            else if (sceneController.boat[1] == null && sceneController.find == 1)
            {
                sceneController.boat[1] = gameobject;
                sceneController.boat[1].transform.tag = gameobject.transform.tag;
                sceneController.boatCapacity--;
                this.transform.localPosition = new Vector3(0, 1.2f, -0.12f);
            }
        }
        sceneController.find = 0;
        this.destroy = true;
        this.callback.SSActionEvent(this);
    }
}

4.裁判類
此次作業的新要求是要增加一個裁判類,判斷遊戲何時結束。其實就是將判斷遊戲結束的函數單獨出來變成一個類,代碼如下:

public class Judge : MonoBehaviour
{
    CoastController fromCoast;
    CoastController toCoast;
    public BoatController boat;

    public Judge(CoastController c1,CoastController c2, BoatController b)
    {
        fromCoast = c1;
        toCoast = c2;
        boat = b;
    }

    public int Check()
    {   // 0->not finish, 1->lose, 2->win
        int from_priest = 0;
        int from_devil = 0;
        int to_priest = 0;
        int to_devil = 0;

        int[] fromCount = fromCoast.GetobjectsNumber();
        from_priest += fromCount[0];
        from_devil += fromCount[1];

        int[] toCount = toCoast.GetobjectsNumber();
        to_priest += toCount[0];
        to_devil += toCount[1];

        if (to_priest + to_devil == 6)      // win
            return 2;

        int[] boatCount = boat.GetobjectsNumber();
        if (boat.get_State() == -1)
        {   // boat at toCoast
            to_priest += boatCount[0];
            to_devil += boatCount[1];
        }
        else
        {   // boat at fromCoast
            from_priest += boatCount[0];
            from_devil += boatCount[1];
        }
        if (from_priest < from_devil && from_priest > 0)
        {       // lose
            return 1;
        }
        if (to_priest < to_devil && to_priest > 0)
        {
            return 1;
        }
        return 0;           // not finish
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章