Unity3d学习之路-牧师与魔鬼

本文介绍了Unity3d开发的一款益智游戏——牧师与魔鬼,玩家需帮助双方安全过河。游戏规则是利用一艘小船,确保任何时候牧师都不被魔鬼超过。文章详细阐述了游戏的架构设计,包括MVC模式的应用,以及各个游戏对象如角色、船只和陆地的模型设计。此外,还讨论了如何通过Resources.Load和Object.Instantiate加载和实例化预制体,以及实现角色移动、点击检测和动画播放的脚本机制。
摘要由CSDN通过智能技术生成

Unity3d学习之路-牧师与魔鬼


游戏基本介绍

  • 游戏规则:

    Priests and Devils is a puzzle game in which you will help the Priests and Devils to cross the river within the time limit. There are 3 priests and 3 devils at one side of the river. They all want to get to the other side of this river, but there is only one boat and this boat can only carry two persons each time. And there must be one person steering the boat from one side to the other side. In the flash game, you can click on them to move them and click the go button to move the boat to the other direction. If the priests are out numbered by the devils on either side of the river, they get killed and the game is over. You can try it in many > ways. Keep all priests alive! Good luck!

  • 游戏中提及的事物(Objects):
    魔鬼,牧师,船,河流,两边的陆地

  • 用表格列出玩家动作表(规则表):

玩家动作 执行条件 执行结果
点击牧师/魔鬼 游戏未结束,船没有正在移动,与船在相同的一边 牧师/魔鬼移动
点击船 游戏未结束且船上至少有一人 船移动
  • 本游戏架构参考下图:

MVC
MVC模式真的很好用,用过都说好,不过本次游戏只创建了三个脚本,所以接口和导演是和GameModels放在同一个脚本的同一命名空间下。

游戏制作流程

  • 搭建场景
    在Unity官方的Asset Store输入需要查找的资源,找到了免费的模型且模型带有动画(Asset Store中有很多免费的资源但是注意版权哦),然后布置场景,把它们放在场景中,记录他们不同状态的时候的坐标,方便接下来使用。

  • 创建各类构建基本的架构

    1.SSDirector
    利用单例模式创建导演,和Cocos2d-x一样一个游戏导演只能有一个,这里继承于System.Object,保持导演类一直存在,不被Unity内存管理而管理,导演类类似于生活中的导演,安排场景,场景切换,都是靠它来指挥。

    public class SSDirector : System.Object
    {
        private static SSDirector _instance;             //导演类的实例
        public ISceneController CurrentScenceController { get; set; }
        public static SSDirector GetInstance()           
        {
            if (_instance == null)
            {
                _instance = new SSDirector();
            }
            return _instance;
        }
    }

2.ISceneController
这是一个场景的控制器的接口,算是导演与场景控制器沟通的接口,利用这个接口,得知当前场景是由哪个控制,然后向场景控制器传达要求等。

   public interface ISceneController                      
{
    void LoadResources();                                  //加载场景
}

3.IUserAction
用户进行操作后与游戏中发生响应的接口,用户通过键盘、鼠标等对游戏发出指令,这个指令会触发游戏中的一些行为,(比如在这个游戏中,点击角色让角色移动,这个角色移动就是用户动作后触发的行为),由IUserAction来声明

    public interface IUserAction                           //用户互动会发生的事件
    {
        void MoveBoat();                                   //移动船
        void Restart();                                    //重新开始
        void MoveRole(RoleModel role);                     //移动角色
        int Check();                                       //检测游戏结束
    }

4.FirstController
这是一个控制器,对场景中的具体对象进行操作(其实也是使用GameModels给出的函数进行控制),可以看到这个控制器继承了两个接口类并实现了它们的方法,控制器是场景中各游戏对象行为改变的核心

public class Controllor : MonoBehaviour, ISceneController, IUserAction
{
    public LandModel start_land;            //开始陆地
    public LandModel end_land;              //结束陆地
    public BoatModel boat;                  //船
    private RoleModel[] roles;              //角色
    UserGUI user_gui;

    void Start ()
    {
        SSDirector director = SSDirector.GetInstance();      //得到导演实例
        director.Curre
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是C#语言实现牧师与野人问题求解的代码和注释: ```csharp using System; using System.Collections.Generic; namespace MissionariesAndCannibals { class Program { static void Main(string[] args) { // 初始化状态 State initialState = new State(3, 3, true, 0, 0); // 初始化搜索树 SearchTree searchTree = new SearchTree(initialState); // 进行搜索 searchTree.BFS(); } } // 表示状态的类 class State { public int MissionariesLeft { get; set; } // 左岸传教士数量 public int CannibalsLeft { get; set; } // 左岸野人数量 public bool BoatPosition { get; set; } // 船的位置,true表示在左岸,false表示在右岸 public int MissionariesRight { get; set; } // 右岸传教士数量 public int CannibalsRight { get; set; } // 右岸野人数量 // 构造函数 public State(int missionariesLeft, int cannibalsLeft, bool boatPosition, int missionariesRight, int cannibalsRight) { MissionariesLeft = missionariesLeft; CannibalsLeft = cannibalsLeft; BoatPosition = boatPosition; MissionariesRight = missionariesRight; CannibalsRight = cannibalsRight; } // 判断状态是否合法 public bool IsValid() { if (MissionariesLeft < 0 || CannibalsLeft < 0 || MissionariesRight < 0 || CannibalsRight < 0) { return false; } if (MissionariesLeft > 3 || CannibalsLeft > 3 || MissionariesRight > 3 || CannibalsRight > 3) { return false; } if (CannibalsLeft > MissionariesLeft && MissionariesLeft > 0) { return false; } if (CannibalsRight > MissionariesRight && MissionariesRight > 0) { return false; } return true; } // 判断状态是否为目标状态 public bool IsGoal() { return MissionariesLeft == 0 && CannibalsLeft == 0; } // 判断两个状态是否相等 public override bool Equals(object obj) { State state = obj as State; if (state == null) { return false; } return MissionariesLeft == state.MissionariesLeft && CannibalsLeft == state.CannibalsLeft && BoatPosition == state.BoatPosition && MissionariesRight == state.MissionariesRight && CannibalsRight == state.CannibalsRight; } // 获取状态的哈希值 public override int GetHashCode() { return MissionariesLeft * 10000 + CannibalsLeft * 1000 + (BoatPosition ? 100 : 0) + MissionariesRight * 10 + CannibalsRight; } // 获取状态的字符串表示 public override string ToString() { return "MissionariesLeft: " + MissionariesLeft + ", CannibalsLeft: " + CannibalsLeft + ", BoatPosition: " + (BoatPosition ? "Left" : "Right") + ", MissionariesRight: " + MissionariesRight + ", CannibalsRight: " + CannibalsRight; } } // 表示搜索树的类 class SearchTree { private State _initialState; // 初始状态 private Queue<Node> _frontier; // 存放待扩展的节点的队列 private HashSet<State> _exploredSet; // 存放已扩展过的状态的集合 // 构造函数 public SearchTree(State initialState) { _initialState = initialState; _frontier = new Queue<Node>(); _frontier.Enqueue(new Node(_initialState, null)); _exploredSet = new HashSet<State>(); } // 广度优先搜索 public void BFS() { while (_frontier.Count > 0) { Node node = _frontier.Dequeue(); State state = node.State; if (state.IsGoal()) { // 找到了目标状态,输出路径 List<State> path = new List<State>(); while (node != null) { path.Insert(0, node.State); node = node.Parent; } foreach (State s in path) { Console.WriteLine(s); } return; } _exploredSet.Add(state); List<State> successors = GetSuccessors(state); foreach (State successor in successors) { if (!_exploredSet.Contains(successor)) { _frontier.Enqueue(new Node(successor, node)); } } } Console.WriteLine("No solution found."); } // 获取一个状态的所有合法后继状态 private List<State> GetSuccessors(State state) { List<State> successors = new List<State>(); if (state.BoatPosition) { // 船在左岸 for (int i = 0; i <= 2; i++) { for (int j = 0; j <= 2; j++) { if (i + j >= 1 && i + j <= 2) { State successor = new State(state.MissionariesLeft - i, state.CannibalsLeft - j, false, state.MissionariesRight + i, state.CannibalsRight + j); if (successor.IsValid()) { successors.Add(successor); } } } } } else { // 船在右岸 for (int i = 0; i <= 2; i++) { for (int j = 0; j <= 2; j++) { if (i + j >= 1 && i + j <= 2) { State successor = new State(state.MissionariesLeft + i, state.CannibalsLeft + j, true, state.MissionariesRight - i, state.CannibalsRight - j); if (successor.IsValid()) { successors.Add(successor); } } } } } return successors; } } // 表示搜索树中的节点的类 class Node { public State State { get; set; } // 节点对应的状态 public Node Parent { get; set; } // 父节点 // 构造函数 public Node(State state, Node parent) { State = state; Parent = parent; } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值