unity3D小游戏-牧师与魔鬼MVC版

2023-12-16 11:10

本文主要是介绍unity3D小游戏-牧师与魔鬼MVC版,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、介绍

帮助三个牧师与三个魔鬼过河。过程中,河的两岸分别要满足:牧师数量不能少于魔鬼的数量。

二、实现

1、框架

Model:

(1)包含船、陆地、角色等游戏中涉及到的模型(物体、物件),

它们的基础类型都是GameObject,区别它们的是各自使用的预制件、初始化的位置等等

这些模型仅仅定义了其本身的属性(位置等),并不提供运动等操作函数。

(2)包含click、move两个“特殊”的模型:

click的点击事件(函数)触发的是Contorller中的IObjectController定义的点击函数;

同时船、陆地、角色等模型在定义时被赋予“click”(可点击?)

move:用于实现模型的移动(判断是否在移动、Update函数更新位置)

同样,这两个模型并没有自发的功能实现,更类似于可供其他类使用的“工具”。

View:

用户(玩家)操作的按钮等界面

Controller:

(1)Controllers文件夹包含各种控制器。FirstContorller是“主脑”,由它生成并管理其他控制器的实例(如船、陆地、角色等的控制器)

(2)船、陆地、角色等控制器定义了各种数据(位置、座位数等辅助数据)以及各种功能函数(创建物体、如何入座、点击事件等)

(3)这些物件都有一些共同的动作或功能函数,于是创建一些接口来统一定义:

    IObjectController定义了物体的点击、生成、重置等函数

    IUserAction定义了物体动作、场景状态等函数(物体动作、场景状态(重新开始等)都是由玩家来操控,所以叫IUserAction)    

(4)ISceneController定义了场景初始化函数

    (3)(4)这些controller只是对函数的“声明”(类似于基类,由firstcontroller继承?),具体的函数实现由firstcontroller完成。

只有当FirstController创建了船等其他控制器、调用其他控制器的“创建物件”函数,游戏实体才被创建出来。同样,只有当FirstController调用了其他控制器的功能函数,游戏实体才能实现运动。

玩家行为:

玩家动作效果备注
点击牧师或魔鬼牧师或魔鬼:离岸上船、下船上岸需要点中对象
点击船体船从一岸移动到另一岸             1<=船上人数<=2

UML图:

2、实现:

Scripts脚本文件夹中分成三部分:Controllers、Models、Views,分别实现上述对应的代码。

在这里我参照了这位博主的博客https://www.cnblogs.com/LC32/p/15420714.html(或者说,我只是在他的代码、框架上做小修改,在此特别感谢)

3、游戏逻辑介绍

角色分为牧师与魔鬼

船上只可乘坐一个或两个角色(对应的,在boatcontroller定义座位数),无人时不可移动。

boatController(部分):

    ......public int[] seat; // 座位数组,存储船上的乘客座位号public Boat boatModel; // 船的模型对象public int seatNum=2; //船的座位   //添加这个是为了方便控制船的位置数//在下面的初始化、循环中统一用seatNumpublic BoatController(){userAction = SSDirector.GetInstance().CurrentSceneController as         IUserAction; // 获取当前场景的用户操作接口seat = new int[seatNum]; // 初始化座位数组Reset(); // 重置船的状态}......

点击岸上、船上的角色,对应角色上船、下船。点击船体,船左右移动。船体或角色移动过程中,不响应其他点击事件。

角色上岸(回到左岸或上到右岸),则回到岸上一个空位置上(对应的,landconcroller定义位置等参数)

角色在左岸、右岸、船上转移,对应的rolecontroller定义角色位置等参数

最后,在游戏的适当时机(船载着角色移动时、角色上到右岸时),执行“check”,检查游戏状态:是否成功或者失败(所有角色到达右岸则为成功;存在某一岸上的魔鬼数量>牧师数量,则游戏失败)

firstController:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class FirstController : MonoBehaviour, ISceneController, IUserAction
{public static int LEFTLAND = 0;public static int RIGHTLAND = 1;public static int BOAT = 2;public static int PRIEST = 0;public static int DEVIL = 1;public static int PLAYING = 0;public static int WIN = 1;public static int FAILED = 2;BoatController BoatCtrl;RoleController[] RoleCtrl = new RoleController[6];LandController[] LandCtrl = new LandController[2];MoveController MoveCtrl;int[] rolesID = new int[6]{0,1,2,3,4,5};int gameState;void Awake(){SSDirector director = SSDirector.GetInstance();director.CurrentSceneController = this;director.CurrentSceneController.Initialize();}public void Initialize(){//如果有,则释放原有的GameObjectfor(int i = 0; i < 6; i++){if(RoleCtrl[i] != null){Destroy(RoleCtrl[i].GetModelGameObject());}}for(int i = 0; i < 2; i++){if(LandCtrl[i] != null){Destroy(LandCtrl[i].GetModelGameObject());}}if(BoatCtrl != null){Destroy(BoatCtrl.GetModelGameObject());}// 加载控制器和模型BoatCtrl = new BoatController();BoatCtrl.CreateModel();for(int i = 0; i < 6; i++){int roleType = (i < 3) ? PRIEST : DEVIL;RoleCtrl[i] = new RoleController(roleType, rolesID[i]);RoleCtrl[i].CreateModel();}LandCtrl[0] = new LandController(LEFTLAND, rolesID);LandCtrl[1] = new LandController(RIGHTLAND, rolesID);LandCtrl[0].CreateModel();LandCtrl[1].CreateModel();MoveCtrl = new MoveController();//开始游戏gameState = PLAYING;}//将角色的ID转换成数组的下标int IDToNumber(int ID){for(int i = 0; i < 6; i++){if(rolesID[i] == ID){return i;}}return -1;}//点击船时执行public void MoveBoat(){if(gameState != PLAYING || MoveCtrl.IsMoving() || BoatCtrl.isEmpty()) return;CheckAndSetGameState();if(BoatCtrl.onLeftside){MoveCtrl.SetMove(BoatCtrl.GetModelGameObject(), Position.boatRightPos);for(int i = 0; i < BoatCtrl.seatNum; i++){if(BoatCtrl.seat[i] != -1){RoleController r = RoleCtrl[IDToNumber(BoatCtrl.seat[i])];MoveCtrl.SetMove(r.GetModelGameObject(), Position.seatRightPos[i]);}}}else{MoveCtrl.SetMove(BoatCtrl.GetModelGameObject(), Position.boatLeftPos);for(int i = 0; i < BoatCtrl.seatNum; i++){if(BoatCtrl.seat[i] != -1){RoleController r = RoleCtrl[IDToNumber(BoatCtrl.seat[i])];MoveCtrl.SetMove(r.GetModelGameObject(), Position.seatLeftPos[i]);}} }BoatCtrl.onLeftside = !BoatCtrl.onLeftside;}//点击角色时执行public void MoveRole(int id){int num = IDToNumber(id);if(gameState != PLAYING || MoveCtrl.IsMoving()) return;int seat;switch(RoleCtrl[num].roleState){case 0: // LEFTLANDif(!BoatCtrl.onLeftside || (BoatCtrl.getEmptySeat() == -1)) return;//增加判断getEmptySeat :LandCtrl[0].LeaveLand(id);                                         //如果上不了船,就直接返回,而seat = BoatCtrl.embark(id);                                        //不用改动role、land、boat的位置参数RoleCtrl[num].GoTo(BOAT);if(seat == -1) return;   //增加判断getEmptySeat后,这句应该可以略去MoveCtrl.SetMove(RoleCtrl[num].GetModelGameObject(), Position.seatLeftPos[seat]);break;case 1: // RIGHTLANDif(BoatCtrl.onLeftside || (BoatCtrl.getEmptySeat() == -1)) return;//同上LandCtrl[1].LeaveLand(id);seat = BoatCtrl.embark(id);RoleCtrl[num].GoTo(BOAT);if(seat == -1) return;MoveCtrl.SetMove(RoleCtrl[num].GetModelGameObject(), Position.seatRightPos[seat]);break;case 2: //BOATif(BoatCtrl.onLeftside){seat = LandCtrl[0].getEmptySeat();BoatCtrl.disembark(id);LandCtrl[0].GoOnLand(id);RoleCtrl[num].GoTo(LEFTLAND);MoveCtrl.SetMove(RoleCtrl[num].GetModelGameObject(), Position.roleLeftPos[seat]);}else{UnityEngine.Debug.Log("mid_d");seat = LandCtrl[1].getEmptySeat();BoatCtrl.disembark(id);LandCtrl[1].GoOnLand(id);RoleCtrl[num].GoTo(RIGHTLAND);CheckAndSetGameState();//新添加一个在这里,在最后一个角色上右岸之后判定成功MoveCtrl.SetMove(RoleCtrl[num].GetModelGameObject(), Position.roleRightPos[seat]);}break;default: break;}}//判断游戏状态public void CheckAndSetGameState(){if(gameState != PLAYING) return;//判断是否失败int[,] rolePos = new int[2, 3]{{0, 0, 0}, {0, 0, 0}};foreach(RoleController r in RoleCtrl){rolePos[r.roleType, r.roleState]++;  //roletype: 0天使、1魔鬼}                                        //rolestate:0左岸、1右岸、2船上if((rolePos[0,0]>0 && rolePos[0,0]<rolePos[1,0]) ||   //左岸存在天使 && 左岸的天使数量少于左岸魔鬼的数量(rolePos[0,1]>0 && rolePos[0,1]<rolePos[1,1]) ||   //右岸存在天使 && 右岸的天使数量少于右岸魔鬼的数量(rolePos[0,2]>0 && rolePos[0,2] < rolePos[1,2])){  //船上最多只能承载两个角色时,这行可以删去gameState = FAILED;return;}  //判断是否成功foreach(RoleController r in RoleCtrl){if(r.roleState != RIGHTLAND){//存在角色未到达右岸,则直接返回 //r.roleType == 0 && UnityEngine.Debug.Log("这里");return;}}UnityEngine.Debug.Log("其实是这里");gameState = WIN;  //上面的情况都不符合,则说明所有角色都安全到达右岸,winreturn;}//Reset按钮执行的功能public void Restart(){Initialize();gameState = PLAYING;}//获取游戏当前状态public int GetGameState(){return gameState;}
}

视频链接:unity3D小游戏-牧师与魔鬼MVC版_哔哩哔哩_bilibili

这篇关于unity3D小游戏-牧师与魔鬼MVC版的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/500247

相关文章

Spring MVC 图片上传

引入需要的包 <dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.1</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-

【iOS】MVC模式

MVC模式 MVC模式MVC模式demo MVC模式 MVC模式全称为model(模型)view(视图)controller(控制器),他分为三个不同的层分别负责不同的职责。 View:该层用于存放视图,该层中我们可以对页面及控件进行布局。Model:模型一般都拥有很好的可复用性,在该层中,我们可以统一管理一些数据。Controlller:该层充当一个CPU的功能,即该应用程序

Unity3D自带Mouse Look鼠标视角代码解析。

Unity3D自带Mouse Look鼠标视角代码解析。 代码块 代码块语法遵循标准markdown代码,例如: using UnityEngine;using System.Collections;/// MouseLook rotates the transform based on the mouse delta./// Minimum and Maximum values can

Unity3D 运动之Move函数和translate

CharacterController.Move 移动 function Move (motion : Vector3) : CollisionFlags Description描述 A more complex move function taking absolute movement deltas. 一个更加复杂的运动函数,每次都绝对运动。 Attempts to

MVC(Model-View-Controller)和MVVM(Model-View-ViewModel)

1、MVC MVC(Model-View-Controller) 是一种常用的架构模式,用于分离应用程序的逻辑、数据和展示。它通过三个核心组件(模型、视图和控制器)将应用程序的业务逻辑与用户界面隔离,促进代码的可维护性、可扩展性和模块化。在 MVC 模式中,各组件可以与多种设计模式结合使用,以增强灵活性和可维护性。以下是 MVC 各组件与常见设计模式的关系和作用: 1. Model(模型)

.Net Mvc-导出PDF-思路方案

效果图: 导语:     在我们做项目的过程中,经常会遇到一些服务性的需求,感到特别困扰,明明实用的价值不高,但是还是得实现;     因此小客在这里整理一下自己导出PDF的一些思路,供大家参考。     网上有很多导出PDF运用到的插件,大家也可以看看其他插件的使用,学习学习; 提要:     这里我使用的是-iTextSharp,供大家参考参考,借鉴方案,完善思路,补充自己,一起学习

.net MVC 导出Word--思路详解

序言:          一般在项目的开发过程中,总会接收到一个个需求,其中将数据转换成Work来下载,是一个很常见的需求;          那么,我们改如何处理这种需求,并输出实现呢?          在做的过程中,去思考 1、第一步:首先确认,Work的存在位置,并创建字符输出路:             //在的项目中创建一个存储work的文件夹             string

SSM Spring MVC集成mybatis

一、练习目标 1、需求 完成部门基本的 CRUD 和分页查询,完成员工基本的 CRUD、分页查询和过滤查询(根据姓名和邮箱模糊查询,根据部门查询)。 2、技术架构 使用 Spring MVC + Spring + MyBatis,数据库选用 MySQL,视图选用 JSP。 3、SSM 集成作用及本质 作用:在框架上基础上开发,发挥各个框架在各层的好处,提高开发效率。 本质: Sp

Unity3D在2D游戏中获取触屏物体的方法

我们的需求是: 假如屏幕中一个棋盘,每个棋子是button构成的,我们希望手指或者鼠标在哪里,就显示那个位置的button信息。 网上有很多获取触屏物体信息的信息的方法如下面代码所示: Camera cam = Camera.main; // pre-defined...if (touch.phase == TouchPhase.Bagan)){ // 如果触控点状态为按下Ray

Spring MVC 执行流程详解

Spring MVC 是一个典型的基于 MVC 设计模式的框架,它用于开发 Java Web 应用程序。在 Spring MVC 中,每个请求都要经历一系列的步骤,从客户端请求到服务器返回响应。下面的执行流程图很好地描述了 Spring MVC 的执行流程,从请求发起到最后返回数据。接下来,我将全面、深入地讲解 Spring MVC 的执行流程。 Spring MVC 执行流程图: +----