牧师与恶魔——动作分离版

Priests and Devils ——动作分离版

完整工程文件在github(https://github.com/JennySRH/3DGame/tree/master/PriestsAndDevils2

游戏视频https://www.bilibili.com/video/av68091576

在这里插入图片描述

在之前的牧师与恶魔的游戏制作中,我们使用FirstController来控制游戏中人物的动作,这样写出了的代码低内聚高耦合。在这里,我们对上一版的牧师与恶魔进行更新迭代,将动作从FirstController中分离出来,减少程序的耦合提高内聚性。

我们首先创建一个类Action用来管理所有游戏事物的动作,然后在FirstController中创建这个类的实例,用来管理游戏事物的运动。

    public Action actionManager;   //动作管理

在这个版本中,游戏事物的所有动作都由Action来管理,而游戏事物的信息、状态等都由RoleBoat来管理。比如游戏角色(牧师和恶魔)上下船的动作,由FristcontrollerAction进行通信,让Action来管理动作的改变,同时告知Role进行状态的改变。

FirstController的代码如下所示:

if(obj.position == 0 && obj.position == boat.position && boat.num < 2)
{
    boat.num++;
    if(boat.BoatState[0] == 0)
    {
        // 更改model
        obj.getBoat(1);
        // 更改动作
        actionManager.getBoat(obj, 1);
        boat.BoatState[0] = MapName(name);
    }
    else
    {
        obj.getBoat(2);
        actionManager.getBoat(obj, 2);
        boat.BoatState[1] = MapName(name);
    }
}

Action中的相关代码如下所示:

    public void getBoat(Role role, int i)
    {
        if (i == 1)
        {
            role.character.transform.position = new Vector3(0, -3, 4);
        }
        else if (i == 2)
        {
            role.character.transform.position = new Vector3(0, -3, 6);
        }
        else if (i == 3)
        {
            role.character.transform.position = new Vector3(0, -3, -4);
        }
        else
        {
            role.character.transform.position = new Vector3(0, -3, -6);
        }
    }

Role中的相关代码如下所示:

    public void getBoat(int i)
    {
        position = 2;
        if (i == 1)
        {
            boatPos = 0;
        }
        else if(i == 2)
        {
            boatPos = 1;
        }
        else if(i == 3)
        {
            boatPos = 1;
        }
        else
        {
            boatPos = 0;
        }
    }

其余的更改基本跟上下船相同,Action类代码如下所示。

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

public class Action 
{

    public void GetBoat(Role role, int i)
    {
        if (i == 1)
        {
            role.character.transform.position = new Vector3(0, -3, 4);
        }
        else if (i == 2)
        {
            role.character.transform.position = new Vector3(0, -3, 6);
        }
        else if (i == 3)
        {
            role.character.transform.position = new Vector3(0, -3, -4);
        }
        else
        {
            role.character.transform.position = new Vector3(0, -3, -6);
        }
    }


    public void MoveToOrigin(Role role)
    {
        role.character.transform.position = role.origin;
    }

    public void MoveToDest(Role role)
    {
        role.character.transform.position = role.dest;
    }


    Role MapNumToRole(int num, Role []Priests, Role []Devils)
    {
        Role tmp = null;
        if (num < 4 && num > 0)
        {
            tmp = Priests[num - 1];
        }
        else if (num >= 4 && num <= 6)
        {
            tmp = Devils[num - 4];
        }
        return tmp;
    }

    public void MoveBoat(Boat boat, Role[] Priests, Role[] Devils)
    {
        // 船移动
        Vector3 Current = boat.thisboat.transform.position;
        Vector3[] Target = { new Vector3(0, -3, -5), new Vector3(0, -3, 4) };
        Vector3 tar = Target[boat.movestate - 1];
        int a = boat.movestate - 1;
        if (Current == tar)
        {
            boat.movestate = 0;
        }
        boat.thisboat.transform.position = Vector3.MoveTowards(Current, tar, 8f * Time.deltaTime);
        Vector3[,] targets = {
                { new Vector3(0, -3, -5), new Vector3(0, -3, -6) },
                { new Vector3(0, -3, 5), new Vector3(0, -3, 6) }
            };

        for (int i = 0; i < 2; i++)
        {
            int b = i;
            Role r = MapNumToRole(boat.BoatState[i], Priests, Devils);
            if (r != null)
            {
                Vector3 cur = r.character.transform.position;
                r.character.transform.position = Vector3.MoveTowards(cur, targets[a, b], 8f * Time.deltaTime);
            }
        }
    }
}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值