游戏开发之Unity学习(三)——小游戏:牧师与魔鬼

一、牧师与魔鬼游戏规则

在河的一边有三个牧师和三个魔鬼。 他们都想到达这条河的另一边,但只有一条船,这条船每次只能载两人。 而且必须有一个人将船从一侧转向另一侧。 您可以点击它们来移动它们,然后点击go按钮将船移动到另一个方向。 如果在岸上(如果船停在这个岸边,则包括船上)恶魔多于牧师,牧师将被杀死,游戏结束,挑战失败。 你可以用很多方式尝试。 让所有的牧师活着! 祝你好运!

二、基于规则完善游戏对象

游戏UI。
牧师、魔鬼、岸、河、船、go按钮。
用户UI。
restart按钮。

三、基于规则完善游戏动作

玩家动作 发生条件
上船 船上有空位且点击想放上船的对象
下船 船上有对象且点击想放下船的对象
开船 点击Go按钮
重新开始 点击restart按钮

四、基于规则构建游戏场景

根据(二)设计好每一个游戏对象的图形做成预制(prefab)(预制开始还没有皮肤的)
这里写图片描述
其中使用的水来自于Unity自带的资源包(工具栏 Assets Import Package Enviironment )

下面就开始做皮肤吧!

皮肤的图片可以自己在网上找。然后保存到此项目的Asset是文件夹(或其子文件夹)然后创建Materials,如下:
这里写图片描述
蓝底白字那个就是我新建的,点击它,然后在右侧找到下面红色圈圈圈起来的那里。点选最后一个的第四个。
这里写图片描述
就会变成下面这样:
这里写图片描述
把你的图片拖到右边那个格子里。材料就做好了。
然后只要你把这个材料拖到预制(prefabs)上,预制就会拥有好看的皮肤了。

五、根据规则编写行为约束代码

根据(三)。我们需要编写一个响应用户点击事件的函数,此文件命名为UserClick.cs。下面是响应用户点击事件的代码

using UnityEngine;

public class UserClick : MonoBehaviour {
    private IUserAction action;
    // Use this for initialization
    void Start()
    {
        action = SSDirector.getInstance().currentSceneController as IUserAction;
    }
    private void OnMouseDown()
    {
        action.UserClick(this.gameObject);
    }
}

和响应restart的代码:

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

public class UserGUI : MonoBehaviour {

    private IUserAction action;
    void Start () {
        action = SSDirector.getInstance().currentSceneController as IUserAction;
    }
    private void OnGUI()
    {
        GUIStyle fontstyle1 = new GUIStyle();
        fontstyle1.fontSize = 50;
        fontstyle1.normal.textColor = new Color(255, 255, 255);
        if (GUI.Button(new Rect(0, 80, 80, 60), "RESTART"))
        {
            action.Restart();
        }
    }
}

这里点击事件使用this.gameObject作为参数的好处在于可以将当前被点击的物体传给处理函数处理。不需要写多份代码。action是一个接口类的实例。
然后我们看这个接口类:

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

public interface IUserAction {
    void UserClick(GameObject target);
    void Restart();
}

然后我们把第四步中制作好的场景生成出来,使用空对象绑定CSharp脚本。
这里我们需要场景控制器。并生成一个“导演”。

public interface ISceneController {
    void GenGameObjects();
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SSDirector : System.Object {

    private static SSDirector _instance;
    public ISceneController currentSceneController { get; set; }
    public static SSDirector getInstance()
    {
        if (_instance == null)
            _instance = new SSDirector();
        return _instance;
    }

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

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

最后整个整个场景的生成和上述代码的实现。

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

public class FirstSceneController : MonoBehaviour, IUserAction, ISceneController{
    private GameObject boat;
    private GameObject river;
    private int devils_s;
    private int priests_s;
    private int devils_e;
    private int priests_e;
    private int devils_boat;
    private int priests_boat;
    private List<GameObject> OnBoat;
    private bool isFull;
    private bool isRunning;
    private Vector3 endPos;
    private int flag;

    private void Awake()
    {
        SSDirector director = SSDirector.getInstance();
        director.setFPS(60);
        director.currentSceneController = this;
        director.currentSceneController.GenGameObjects();
    }
    private void Start()
    {
        devils_s = 3;
        priests_s = 3;
        devils_boat = 0;
        priests_boat = 0;
        devils_e = 0;
        priests_e = 0;
        flag = 0;
        OnBoat = new List<GameObject>();
        isFull = false;
        isRunning = false;
        endPos = boat.transform.position;
    }
    public void GenGameObjects ()
    {
        river = Instantiate<GameObject>(Resources.Load<GameObject>("prefabs/river"), Vector3.zero, Quaternion.identity);
        river.name = "river";
        river.transform.parent = this.transform;
        boat = Instantiate<GameObject>(Resources.Load<GameObject>("prefabs/boat"));
        boat.name = "boat";
        boat.transform.parent = this.transform;
        boat.transform.position = new Vector3(-3.5f,0);
        for (int i=1;i<=6;++i)
        {
            string str = i <= 3 ? "priest" : "Devils";
            GameObject priest = Instantiate<GameObject>(Resources.Load<GameObject>("prefabs/" + str));
            priest.name = str + i;
            priest.transform.parent = this.transform;
            priest.transform.position = new Vector3(- 4.9f - i*0.6f, 1.25f, 0);
        }
    }
    public void UserClick(GameObject target)
    {
        if (!isRunning&& flag == 0)
        {
            if (OnBoat.Contains(target))
            {
                int f = boat.transform.position.x < 0 ? 1 : -1;
                int i = target.name[target.name.Length - 1] - '0';
                target.transform.parent = this.transform;
                target.transform.position = new Vector3(f * (-4.9f - i * 0.6f), 1.25f, 0);
                isFull = false;
                if (i <= 3) priests_boat--;
                else devils_boat--;
                OnBoat.Remove(target);
            }
            else if (OnBoat.Count < 2)
            {
                int i = target.name[target.name.Length - 1] - '0';
                if (i <= 3) priests_boat++;
                else devils_boat++;
                target.transform.parent = boat.transform;
                if (OnBoat.Count == 1)
                    target.transform.position = new Vector3(-OnBoat[0].transform.position.x, OnBoat[0].transform.position.y, OnBoat[0].transform.position.z) + 2*boat.transform.position;
                else
                    target.transform.position = new Vector3(-0.6f, 0.7f) + boat.transform.position;
                OnBoat.Add(target);
            }
            else
                isFull = true;
        }
    }
    public void Restart()
    {
        SceneManager.LoadScene("1");
    }
}

如需查看更详细的代码请前往 github

猜你喜欢

转载自blog.csdn.net/JC2474223242/article/details/79787743