游戏开发之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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值