魔鬼与牧师小游戏

简介及其他

魔鬼与牧师游戏规则相对来说简单,对象也不多,适合于做一开始的练习,想玩游戏的点这里

我做的最终效果如图,红色代表魔鬼,白色代表牧师,看起来还是蛮好懂的哈,并没有美术素材,希望懂得找资源和添加方法的同学教教我

最终效果图

做这个游戏过程中,难度和重要程度划分如下:

  1. 单实例的应用
  2. 一些细节,比如创建光源等的学习
  3. 游戏逻辑实现

其中游戏逻辑实现是最简单的,可以用list也可以用stack,根据制定的不同的游戏动作规则表有各种各样的实现方法。

而重要的在于单实例的理解和应用;

我们用三个文件来实现MVC的结构:

  • Basecode.cs V
  • GenGameObjects M
  • Actions C
如何运行

最终只要将这三个文件挂载在 main camera 上就好了,代码中有规定camera位置,以及创建光源,所以并不需要在别的地方在添加或者修改东西

在BaseCode中我们定义了命名空间来实现单实例

namespace Com.Mygame {

    public enum WinOrLose {Win,Lose,Gaming};

    public interface ImyAction { //这是定义的接口ImyAction
        void DevilGoOnBoat();
        void DevilGoOffBoat ();
        void PriestGoOnBoat();
        void PriestGoOffBoat();
        void BoatGo ();
    }

    public class GameSceneController:System.Object, ImyAction {
        // 定义了GameSceneController来管理View层,以下的类都是单实例的,只能实例化一次
        private static GameSceneController _instance;
        private BaseCode _base_code;
        private GenGameObjects _gen_game_object;

        public WinOrLose wl = WinOrLose.Gaming;

        public static GameSceneController GetInstance(){
            if (null == _instance) {
                _instance = new GameSceneController ();
            }
            return _instance;
        }

        public BaseCode getBaseCode(){
            return _base_code;
        }

        internal void setBaseCode(BaseCode bc){
            if (null == _base_code) {
                _base_code = bc;
            }
        }

        public GenGameObjects getGenGameObject(){
            return _gen_game_object;
        }

        internal void setGenGameObject(GenGameObjects g){
            if (_gen_game_object == null){
                _gen_game_object = g;
            }
        }

        //这下面是接口函数,里面调用的_gen_game_object方法必须是 public 的,否则无法使用   
        public void DevilGoOnBoat(){
            _gen_game_object.DevilGoOnBoat ();
        }

        public void DevilGoOffBoat (){
            _gen_game_object.DevilGoOffBoat ();
        }

        public void PriestGoOnBoat(){
            _gen_game_object.PriestGoOnBoat ();
        }

        public void PriestGoOffBoat(){  
            _gen_game_object.PriestGoOffBoat ();
        }

        public void BoatGo (){
            _gen_game_object.BoatGo ();
        }
    }
}

GenGameObjects用于创建各个对象并实例化他们

这里需要创建一个GameSceneController,然后将自己注入到其中,使用setGenGameobject方法,同时寒添加Com.Mygame,也就是自己定义的命名空间。

代码没有什么好说的,每个人有每个人的实现方法。这次给我经验就是不用怕设置很多的变量,但是一定要区分模块,将主体分割成一部分一部分的功能。不然越做越乱。

注意,在unity中,设定相对位置localposition,是要考虑父对象的scale的,如果父对象缩小了2倍,那么移动单位距离时,就要乘以2!

同时网上各种查不到的脚本添加光源方法,这里也记一下:

    GameObject light = new GameObject("The light");
    Light lightComp = light.AddComponent<Light> ();
    lightComp.type = LightType.Directional;//添加的光源还可以是其他的类型
    //但是平行光的话一定要成角度,一下是转化角度的方式
    Quaternion Q;
    Q = Quaternion.Euler (20.0f,0.0f,0.0f); //这个方法可以将欧拉角度转化为4元组的角度,比较实用
    light.transform.rotation = Q;

同理在Action里,写入GUI函数,并添加接口函数就可以了

void OnGUI(){

        if(GUI.Button(new Rect(firstBx,firstBy,BottonW,BottonH), "魔鬼上船")){
            actions.DevilGoOnBoat ();
        }
        if(GUI.Button(new Rect(firstBx+BottonW+blank,firstBy,BottonW,BottonH), "魔鬼下船")){
            actions.DevilGoOffBoat ();
        }
        if(GUI.Button(new Rect(firstBx,firstBy+BottonH+blank,BottonW,BottonH), "牧师上船")){
            actions.PriestGoOnBoat ();
        }
        if(GUI.Button(new Rect(firstBx+BottonW+blank,firstBy+BottonH+blank,BottonW,BottonH), "牧师下船")){
            actions.PriestGoOffBoat ();
        }
        if(GUI.Button(new Rect(firstBx,firstBy+(BottonH+blank)*2,BottonW*2+blank,BottonH*2), "开船!")){
            actions.BoatGo ();
            if (mygame.wl == WinOrLose.Gaming) str = "点击重置!";
            else if (mygame.wl == WinOrLose.Lose) str = "输了...重来!";
            else if (mygame.wl == WinOrLose.Win) str = "赢了!再来!";
        }

        if(GUI.Button(new Rect(Screen.width-BottonW/2,firstBy,BottonW/2,BottonH),str)){
            Application.LoadLevel (Application.loadedLevelName);
            mygame.wl = WinOrLose.Gaming;
        }

        //GUI.Label (new Rect (firstBx,firstBy-BottonH,BottonW*2,BottonH), str);

    }

完整代码如下,本人为编程渣渣,所以在逻辑实现部分显得很繁琐,= =,如果大家有更好的实现方法,多多交流啦~


完整代码

BaseCode.cs
using UnityEngine;
using System.Collections;
using Com.Mygame;

namespace Com.Mygame {

    public enum WinOrLose {Win,Lose,Gaming};

    public interface ImyAction {
        void DevilGoOnBoat();
        void DevilGoOffBoat ();
        void PriestGoOnBoat();
        void PriestGoOffBoat();
        void BoatGo ();
    }

    public class GameSceneController:System.Object, ImyAction {
        private static GameSceneController _instance;
        private BaseCode _base_code;
        private GenGameObjects _gen_game_object;

        public WinOrLose wl = WinOrLose.Gaming;

        public static GameSceneController GetInstance(){
            if (null == _instance) {
                _instance = new GameSceneController ();
            }
            return _instance;
        }

        public BaseCode getBaseCode(){
            return _base_code;
        }

        internal void setBaseCode(BaseCode bc){
            if (null == _base_code) {
                _base_code = bc;
            }
        }

        public GenGameObjects getGenGameObject(){
            return _gen_game_object;
        }

        internal void setGenGameObject(GenGameObjects g){
            if (_gen_game_object == null){
                _gen_game_object = g;
            }
        }

        public void DevilGoOnBoat(){
            _gen_game_object.DevilGoOnBoat ();
        }

        public void DevilGoOffBoat (){
            _gen_game_object.DevilGoOffBoat ();
        }

        public void PriestGoOnBoat(){
            _gen_game_object.PriestGoOnBoat ();
        }

        public void PriestGoOffBoat(){  
            _gen_game_object.PriestGoOffBoat ();
        }

        public void BoatGo (){
            _gen_game_object.BoatGo ();
        }
    }
}

public class BaseCode : MonoBehaviour {

    public string gameName;
    public string gameRule;


    // Use this for initialization
    void Start () {
        this.transform.position = new Vector3 (0.0f,5.0f,-12.0f);
        GameSceneController mygame = GameSceneController.GetInstance ();
        mygame.setBaseCode (this);
    }

    // Update is called once per frame
    void Update () {

    }
}
GenGameObjects.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Com.Mygame;

public class GenGameObjects : MonoBehaviour {

    GameSceneController mygame;
    //boat
    int state = 0;
    GameObject Boat;
    Vector3 boatscale = new Vector3(4.0f,0.3f,2.0f);  //boat's size;
    Vector3 boatStartpos = new Vector3(-6.0f,0.0f,0.0f);
    Vector3 boatEndpos = new Vector3(6.0f,0.0f,0.0f);
    // sits on the boat
    Vector3 boatsit1 = new Vector3 (-0.25f,3.45f,0.0f); //  localposition is care with the scale
    Vector3 boatsit2 = new Vector3 (0.25f,3.45f,0.0f);
    // others about boats
    float boatspeed = 1.0f;
    int boatnumber = 0;
    int Ifboatsit1have = 0;
    int Ifboatsit2have = 0;
    //river


    //Devils
    List<GameObject> devils = new List<GameObject>();
    Vector3[] devilStartpos = new Vector3[3]{ 
        new Vector3(-10f,1.15f,-3f),
        new Vector3(-10f,1.15f,-2f),
        new Vector3(-10f,1.15f,-1f)
    };
    Vector3[] devilEndpos = new Vector3[3]{ 
        new Vector3(10f,1.15f,-3f),
        new Vector3(10f,1.15f,-2f),
        new Vector3(10f,1.15f,-1f)
    };
    Vector3[] devilScale = new Vector3[3]{ 
        new Vector3(),
        new Vector3(),
        new Vector3()
    };
    int[] DevilsState = new int[3]{0,0,0}; // 0-startside 1-endside 2-onboat
    int[] Devilssite = new int[3]{0,0,0}; //0表示 nosite 1-1site 2-2site

    int devilStartside = 3;
    int devilEndside = 0;

    //Priest
    List<GameObject> priests = new List<GameObject>();
    Vector3[] priestStartpos = new Vector3[3]{ 
        new Vector3(-10f,1.15f,1f),
        new Vector3(-10f,1.15f,2f),
        new Vector3(-10f,1.15f,3f)
    };
    Vector3[] prisetEndpos = new Vector3[3]{ 
        new Vector3(10f,1.15f,1f),
        new Vector3(10f,1.15f,2f),
        new Vector3(10f,1.15f,3f)
    };
    Vector3[] priestScale = new Vector3[3]{ 
        new Vector3(),
        new Vector3(),
        new Vector3()
    };

    int[] PriestState = new int[3]{0,0,0}; // 0-startside 1-endside 2-onboat
    int[] Priestsite = new int[3]{0,0,0};

    int priestStartside = 3;
    int priestEndside = 0;

    // startside
    GameObject startside;
    Vector3 startsidepos = new Vector3 (-10.0f,0.0f,0.0f);
    Vector3 startsidescale =  new Vector3(4f,0.3f,8f);
    // endside
    GameObject endside;
    Vector3 endsidepos = new Vector3 (10.0f,0.0f,0.0f);
    Vector3 endsidescale = new Vector3(4f,0.3f,8f);

    // Use this for initialization
    void Start () {
        mygame = GameSceneController.GetInstance ();
        mygame.setGenGameObject (this);
        InsAll ();
    }

    // Update is called once per frame
    void Update () {

        float step = boatspeed * Time.deltaTime;
        if(state == 2){
            Boat.transform.position = Vector3.MoveTowards (Boat.transform.position,boatEndpos,boatspeed);
            if(Boat.transform.position == boatEndpos) state = 1;
        } else if (state == 3){
            Boat.transform.position = Vector3.MoveTowards (Boat.transform.position,boatStartpos,boatspeed);
            if(Boat.transform.position == boatStartpos) state = 0;
        }
    }



    // ins all gameobjects
    void InsAll(){
        //sides
        startside = GameObject.CreatePrimitive(PrimitiveType.Cube);
        startside.transform.localScale = startsidescale;
        startside.transform.position = startsidepos;
        startside.GetComponent<Renderer> ().material.color = Color.green;
        endside = GameObject.CreatePrimitive (PrimitiveType.Cube);
        endside.transform.localScale = endsidescale;
        endside.transform.position = endsidepos;
        endside.GetComponent<Renderer> ().material.color = Color.green;
        //boat
        Boat = GameObject.CreatePrimitive(PrimitiveType.Cube);
        Boat.transform.position = boatStartpos;
        Boat.transform.localScale = boatscale;
        Boat.GetComponent<Renderer> ().material.color = Color.grey;
        //devils and Priests
        for(int i = 0;i<3;i++){
            GameObject devil = GameObject.CreatePrimitive (PrimitiveType.Cylinder);
            devil.GetComponent<Renderer> ().material.color = Color.red;
            devil.transform.position = devilStartpos [i];
            devils.Add (devil);
            GameObject priest = GameObject.CreatePrimitive (PrimitiveType.Cylinder);
            priest.transform.position = priestStartpos [i];
            priests.Add (priest);

        }

        //light !!cool
        GameObject light = new GameObject("The light");
        Light lightComp = light.AddComponent<Light> ();
        lightComp.type = LightType.Directional;
        light.transform.position = new Vector3 ();
        Quaternion Q;
        Q = Quaternion.Euler (20.0f,0.0f,0.0f);
        light.transform.rotation = Q;

    }

    public void DevilGoOnBoat(){ // must write by public ,or the interface can not use it
        if (state == 0) { //startside
            if (boatnumber != 2) {
                for (int i = 0; i < 3; i++) {
                    if (DevilsState [i] == 0) {

                        DevilsState [i] = 2;//mean now this devil's state is on boat

                        devils [i].transform.parent = Boat.transform;

                        if (Ifboatsit1have == 0 && Ifboatsit2have == 0) {
                            devils [i].transform.localPosition = boatsit1;
                            Devilssite [i] = 1;
                            Ifboatsit1have = 1;
                        } else if (Ifboatsit1have == 1 && Ifboatsit2have == 0) {
                            devils [i].transform.localPosition = boatsit2;
                            Devilssite [i] = 2;
                            Ifboatsit2have = 1;
                        } else if (Ifboatsit1have == 0 && Ifboatsit2have == 1) {
                            devils [i].transform.localPosition = boatsit1;
                            Devilssite [i] = 1;
                            Ifboatsit1have = 1;
                        }

                        devilStartside--;
                        boatnumber++;
                        break;
                    }
                }
            }
        } else if (state == 1) { // endside
            if (boatnumber != 2) {
                for (int i = 0; i < 3; i++) {
                    if (DevilsState [i] == 1) {

                        DevilsState [i] = 2;//mean now this devil's state is on boat
                        devils [i].transform.parent = Boat.transform;

                        if (Ifboatsit1have == 0 && Ifboatsit2have == 0) {
                            devils [i].transform.localPosition = boatsit1;
                            Devilssite [i] = 1;
                            Ifboatsit1have = 1;
                        } else if (Ifboatsit1have == 1 && Ifboatsit2have == 0) {
                            devils [i].transform.localPosition = boatsit2;
                            Devilssite [i] = 2;
                            Ifboatsit2have = 1;
                        } else if (Ifboatsit1have == 0 && Ifboatsit2have == 1) {
                            devils [i].transform.localPosition = boatsit1;
                            Devilssite [i] = 1;
                            Ifboatsit1have = 1;
                        }

                        devilEndside--;
                        boatnumber++;
                        break;
                    }
                }
            }
        }
    }

    public void DevilGoOffBoat(){
        if (state == 0) { // startside
            for (int i = 0; i < 3; i++) {
                if(DevilsState[i] == 2){
                    devils [i].transform.parent = null;
                    devils[i].transform.position = devilStartpos[i];
                    DevilsState[i] = 0;

                    if (Devilssite [i] == 1)
                        Ifboatsit1have = 0;
                    else if (Devilssite [i] == 2)
                        Ifboatsit2have = 0;
                    Devilssite [i] = 0;

                    devilStartside++;
                    boatnumber--;
                    break;
                }
            }
        } else if (state == 1) { // endside
            for (int i = 0; i < 3; i++) {
                if(DevilsState[i] == 2){
                    devils [i].transform.parent = null;
                    devils[i].transform.position = devilEndpos[i];
                    DevilsState[i] = 1;

                    if (Devilssite [i] == 1)
                        Ifboatsit1have = 0;
                    else if (Devilssite [i] == 2)
                        Ifboatsit2have = 0;
                    Devilssite [i] = 0;

                    devilEndside++;
                    boatnumber--;
                    break;
                }
            }
        }
    }

    public void PriestGoOnBoat(){
        if (state == 0) { //startside
            if (boatnumber != 2) {
                for (int i = 0; i < 3; i++) {
                    if (PriestState [i] == 0) {

                        PriestState [i] = 2;//mean now this devil's state is on boat
                        priests [i].transform.parent = Boat.transform;

                        if (Ifboatsit1have == 0 && Ifboatsit2have == 0) {
                            priests [i].transform.localPosition = boatsit1;
                            Priestsite [i] = 1;
                            Ifboatsit1have = 1;
                        } else if (Ifboatsit1have == 1 && Ifboatsit2have == 0) {
                            priests [i].transform.localPosition = boatsit2;
                            Priestsite [i] = 2;
                            Ifboatsit2have = 1;
                        } else if (Ifboatsit1have == 0 && Ifboatsit2have == 1) {
                            priests [i].transform.localPosition = boatsit1;
                            Priestsite [i] = 1;
                            Ifboatsit1have = 1;
                        }

                        priestStartside--;
                        boatnumber++;
                        break;
                    }
                }
            }
        } else if (state == 1) { // endside
            if (boatnumber != 2) {
                for (int i = 0; i < 3; i++) {
                    if (PriestState [i] == 1) {

                        PriestState [i] = 2;//mean now this devil's state is on boat
                        priests [i].transform.parent = Boat.transform;

                        if (Ifboatsit1have == 0 && Ifboatsit2have == 0) {
                            priests [i].transform.localPosition = boatsit1;
                            Priestsite [i] = 1;
                            Ifboatsit1have = 1;
                        } else if (Ifboatsit1have == 1 && Ifboatsit2have == 0) {
                            priests [i].transform.localPosition = boatsit2;
                            Priestsite [i] = 2;
                            Ifboatsit2have = 1;
                        } else if (Ifboatsit1have == 0 && Ifboatsit2have == 1) {
                            priests [i].transform.localPosition = boatsit1;
                            Priestsite [i] = 1;
                            Ifboatsit1have = 1;
                        }

                        priestEndside--;
                        boatnumber++;
                        break;
                    }
                }
            }
        }
    }

    public void PriestGoOffBoat(){
        if (state == 0) { // startside
            for (int i = 0; i < 3; i++) {
                if(PriestState[i] == 2){
                    priests [i].transform.parent = null;
                    priests[i].transform.position = priestStartpos[i];
                    PriestState[i] = 0;
                    if (Priestsite [i] == 1)
                        Ifboatsit1have = 0;
                    else if (Priestsite [i] == 2)
                        Ifboatsit2have = 0;
                    Priestsite [i] = 0;
                    priestStartside++;
                    boatnumber--;
                    break;
                }
            }
        } else if (state == 1) { // endside
            for (int i = 0; i < 3; i++) {
                if(PriestState[i] == 2){
                    priests [i].transform.parent = null;
                    priests[i].transform.position = prisetEndpos[i];
                    PriestState[i] = 1;

                    if (Priestsite [i] == 1)
                        Ifboatsit1have = 0;
                    else if (Priestsite [i] == 2)
                        Ifboatsit2have = 0;
                    Priestsite [i] = 0;
                    priestEndside++;
                    boatnumber--;
                    break;
                }
            }
        }
    }

    public void BoatGo(){
        if(boatnumber != 0){
            check ();
            if (state == 0) {
                // from startpos to endpos,move
                state = 2;
            } else if (state == 1){
                state = 3;
                // form endpos to startpos,move
            }
        }
    }

    public void check(){
        //lose check
        print(devilStartside);
        print (devilEndside);
        print (priestStartside);
        print (priestEndside);
        if (state == 0) {
            if ((devilStartside > priestStartside && priestStartside!=0) || ((3 - devilStartside) > (3 - priestStartside) && (3-priestStartside)!=0)) {
                mygame.wl = WinOrLose.Lose;
                return;
            }
        } else if (state == 1) {
            if ((devilEndside > priestEndside && priestEndside!=0 ) || ((3 - devilEndside) > (3 - priestEndside) && (3-priestEndside)!=0)) {
                mygame.wl = WinOrLose.Lose;
                return;
            }
        }
        //win check
        if(devilStartside == 0 && priestStartside == 0) mygame.wl = WinOrLose.Win;

    }
}

Actions.cs
using UnityEngine;
using System.Collections;
using Com.Mygame;

public class Actions : MonoBehaviour {
    GameSceneController mygame;
    ImyAction actions;
    float BottonW = Screen.width/4;
    float BottonH = Screen.height/16;
    float firstBx = Screen.width/4;
    float firstBy = Screen.height/8;
    float blank = 5;
    private string str = "点击重置!";
    // Use this for initialization
    void Start () {

        mygame = GameSceneController.GetInstance();
        actions = GameSceneController.GetInstance () as ImyAction;
    }

    void OnGUI(){

        if(GUI.Button(new Rect(firstBx,firstBy,BottonW,BottonH), "魔鬼上船")){
            actions.DevilGoOnBoat ();
        }
        if(GUI.Button(new Rect(firstBx+BottonW+blank,firstBy,BottonW,BottonH), "魔鬼下船")){
            actions.DevilGoOffBoat ();
        }
        if(GUI.Button(new Rect(firstBx,firstBy+BottonH+blank,BottonW,BottonH), "牧师上船")){
            actions.PriestGoOnBoat ();
        }
        if(GUI.Button(new Rect(firstBx+BottonW+blank,firstBy+BottonH+blank,BottonW,BottonH), "牧师下船")){
            actions.PriestGoOffBoat ();
        }
        if(GUI.Button(new Rect(firstBx,firstBy+(BottonH+blank)*2,BottonW*2+blank,BottonH*2), "开船!")){
            actions.BoatGo ();
            if (mygame.wl == WinOrLose.Gaming) str = "点击重置!";
            else if (mygame.wl == WinOrLose.Lose) str = "输了...重来!";
            else if (mygame.wl == WinOrLose.Win) str = "赢了!再来!";
        }

        if(GUI.Button(new Rect(Screen.width-BottonW/2,firstBy,BottonW/2,BottonH),str)){
            Application.LoadLevel (Application.loadedLevelName);
            mygame.wl = WinOrLose.Gaming;
        }

        //GUI.Label (new Rect (firstBx,firstBy-BottonH,BottonW*2,BottonH), str);

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值