IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 用Unity3D实现简单的牧师与魔鬼游戏(动作分离版) -> 正文阅读

[游戏开发]用Unity3D实现简单的牧师与魔鬼游戏(动作分离版)

用Unity3D实现简单的牧师与魔鬼游戏(动作分离版)

项目地址

牧师与魔鬼游戏(动作分离版)

完成效果图

在这里插入图片描述

上次博客链接

牧师与魔鬼游戏

实现心得

这次作业是在上次作业的基础上完成的,具体做出的改变是添加了一个裁判类和一个行为类,将其它控制类中涉及到判断游戏状态的代码都封装到了裁判类中,并在主控制类添加了一个裁判类的成员变量,在主控制器中使用裁判类的相关方法对游戏状态和游戏对象状态进行判断:

/* 裁判控制类 */
public class JudgeController {
	private int gameState = (int)GameState.Playing; // 游戏状态,0表示游戏正在进行,1表示游戏失败,2表示游戏成功

	public void InitJudgeController() {
		gameState = (int)GameState.Playing;
	}
	
	/* 获取游戏对象是否在船上 */
	public bool IsOnBoat(RoleController role) {
		return role.GetRoleModel().GetIsOnBoat();
	}

	/* 判断船上是否没有角色 */
	public bool IsNoRoleOnBoat(BoatController boat) {
		string [] roleOnBoat = boat.GetBoatModel().GetRoleOnBoat();
		if (roleOnBoat[0] != "" || roleOnBoat[1] != "") {
			return false;
		} else {
			return true;
		}
	}

	/* 检查游戏状态 */
	public int CheckGameState(ShoreController leftShore, ShoreController rightShore, BoatController boat) {
		// 初始化左边和右边的牧师和魔鬼数量都为0
		int leftPriest = 0, rightPriest = 0;
		int leftDevil = 0, rightDevil = 0;

		// 获取左岸和右岸以及船上的牧师和魔鬼的数量数组
		int [] leftShoreCount = leftShore.GetRoleCountOnShore();
		int [] rightShoreCount = rightShore.GetRoleCountOnShore();
		int [] boatCount = boat.GetRoleCountOnBoat();

		// 如果船在左边,那么左边的牧师和魔鬼的数量为左岸数量加上船里的数量
		if (boat.GetBoatSide() == (int)ShoreSide.Left) {
			leftPriest = leftShoreCount[0] + boatCount[0];
			leftDevil = leftShoreCount[1] + boatCount[1];
			rightPriest = rightShoreCount[0];
			rightDevil = rightShoreCount[1]; 
		} else {
			// 如果船在右边,那么右边的牧师和魔鬼的数量为右岸数量加上船里的数量
			leftPriest = leftShoreCount[0];
			leftDevil = leftShoreCount[1];
			rightPriest = rightShoreCount[0] + boatCount[0];
			rightDevil = rightShoreCount[1] + boatCount[1]; 
		}

		// 如果左边牧师加魔鬼的数量等于6且魔鬼全部上岸,那么游戏成功
		if (leftPriest + leftDevil == 6 && leftShoreCount[1] == 3) {
			gameState = (int)GameState.Win;
		} else if (leftPriest < leftDevil && leftPriest > 0) {
			// 如果任意一边牧师的数量小于魔鬼的数量且有牧师,那么游戏失败
			gameState = (int)GameState.Lose;
		} else if (rightPriest < rightDevil && rightPriest > 0) {
			gameState = (int)GameState.Lose;
		} else {
			// 否则游戏正在进行中
			gameState = (int)GameState.Playing;
		}
		return gameState;
	}

	/* 返回是否正在进行游戏 */
	public bool isPlayingGame() {
		return gameState == (int)GameState.Playing;	
	}
}

而行为类则是将原先代码中的移动控制器MoveController和点击控制器ClickController合并到了一起,其它控制类中出现这两个类的地方也换成了行为类:

/* 行为控制器,一般会挂载到某个具体的游戏对象上 */
public class ActionController : MonoBehaviour {
	private ActionModel actionModel;
	private ActionView actionView;
	private RoleController clickRole; // 如果点击的是角色,那么记录点击的对象的控制器

	void Start() {
		actionModel = new ActionModel();
		actionView = gameObject.AddComponent<ActionView>() as ActionView;
	}

	void Update() {
		int state = actionModel.GetState();
		Vector3 middlePos = actionModel.GetMiddlePos();
		Vector3 endPos = actionModel.GetEndPos();
		int speed = actionModel.GetSpeed();
		// 根据速度、中间位置、终点位置、移动状态来移动物体
		Move(state, middlePos, endPos, speed);
	}

	/* 初始化控制器,设置物体不移动 */
	public void InitActionController() {
		// 如果对象是船,获取船在哪边
		int side = actionModel.GetSide();
		// 在左边的话,船会回到右边去
		if (side == (int)ShoreSide.Left) {
			MoveToOtherSide();
		}
	}

	/* 如果对象是船,设置船的岸边边侧 */
	public void SetBoatSide(int side) {
		actionModel.SetSide(side);
	}

	/* 获取船的岸边边侧 */
	public int GetBoatSide() {
		return actionModel.GetSide();
	}

	/* 根据速度、中间位置、终点位置、移动状态来移动物体 */
	public void Move(int state, Vector3 middlePos, Vector3 endPos, int speed) {
		switch (state) {
			case (int)MoveState.Not_Moving:
				break;
			case (int)MoveState.Moving_To_Middle:
				// 移动物体到中间位置,移动到后,设置物体的下一个状态为移动到终点
				actionView.MoveTo(middlePos, speed);
				if (transform.position == middlePos) {
					actionModel.SetState((int)MoveState.Moving_To_End);
				}
				break;
			case (int)MoveState.Moving_To_End:
				// 移动物体到终点位置,移动到后,设置物体的下一个状态为不移动
				actionView.MoveTo(endPos, speed);
				if (transform.position == endPos) {
					actionModel.SetState((int)MoveState.Not_Moving);
				}
				break;
		}
	}

	/* 设置物体要移动到的位置 */
	public void SetMovePos(Vector3 pos) {
		// 设置物体开始往中间位置移动
		actionModel.SetState((int)MoveState.Moving_To_Middle);
		// 设置最终移动位置为pos
		actionModel.SetEndPos(pos);
		// 如果要移动到的位置的y坐标等于物体所在位置的y坐标,说明是船在移动
		if (pos.y == transform.position.y) {
			// 船沿直线运动,所以中间位置也可设为最终位置
			actionModel.SetMiddlePos(pos);
			// 移动状态可以直接设为往终点移动
			actionModel.SetState((int)MoveState.Moving_To_End);
		}
		// 如果要移动到的位置的y坐标小于物体所在位置的y坐标,说明是物体从岸上移动到船上
		else if (pos.y < transform.position.y) {
			actionModel.SetMiddlePos(new Vector3(pos.x, transform.position.y, pos.z));
		}
		// 如果要移动到的位置的y坐标小于物体所在位置的y坐标,说明是物体从船上移动到岸上
		else {
			actionModel.SetMiddlePos(new Vector3(transform.position.x, pos.y, pos.z));
		}
	}

	/* 将船移动到岸的另一侧 */
	public void MoveToOtherSide() {
		// 先获取船在哪边
		int lastSide = actionModel.GetSide();
		// 移动船到另一边
		if (lastSide == (int)ShoreSide.Left) {
			SetMovePos(new Vector3(2.5F, -1, 0));
			actionModel.SetSide((int)ShoreSide.Right);
		} else {
			SetMovePos(new Vector3(-2.5F, -1, 0));
			actionModel.SetSide((int)ShoreSide.Left);
		}
	}

	/* 如果对象是角色,设置被点击的对象为该角色 */
	public void SetClickRole(RoleController role) {
		clickRole = role;
	}

	void OnMouseDown() {
		// 如果鼠标点击的对象是船,那么移动船只
		if (gameObject.name == "Boat") {
			SingleObject.getInstance().GetMainController().MoveBoat();
		} else {
			// 如果鼠标点击的对象是角色,那么移动对象
			SingleObject.getInstance().GetMainController().MoveRole(clickRole);
		}
	}
}

这样一来,在实现模块分离和降低耦合性的同时,也保证了游戏功能的一致性。游戏功能和效果和之前没有任何区别。

游戏截图:

正在进行游戏:

请添加图片描述

游戏失败:

请添加图片描述

游戏成功:

请添加图片描述

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-10-18 17:42:37  更:2021-10-18 17:43:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 0:55:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码