空间与运动_编程题


1、编程实践

  • 阅读以下游戏脚本
  • Priests and Devils
    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!

程序需要满足的要求:

  • play the game ( http://www.flash-game.net/game/2535/priests-and-devils.html )
  • 列出游戏中提及的事物(Objects)
  • 用表格列出玩家动作表(规则表),注意,动作越少越好
  • 请将游戏中对象做成预制
  • 在 GenGameObjects 中创建 长方形、正方形、球 及其色彩代表游戏中的对象。
  • 使用 C# 集合类型 有效组织对象
  • 整个游戏仅 主摄像机 和 一个 Empty 对象, 其他对象必须代码动态生成!!! 。 整个游戏不许出现 Find 游戏对象, SendMessage 这类突破程序结构的 通讯耦合 语句。 违背本条准则,不给分
  • 请使用课件架构图编程,不接受非 MVC 结构程序
  • 注意细节,例如:船未靠岸,牧师与魔鬼上下船运动中,均不能接受用户事件!

牧师和魔鬼游戏是一款益智类游戏,游戏的目标是将3个牧师和3个魔鬼从河的一端安全地送到河的另一端。在运送过程中,船可以搭载两个人,而且必须有一人掌船。无论何时,只要河一边的魔鬼数量多于牧师的数量,游戏就会以失败结束。

  • 在这个游戏中提及的事物有:

    • 3个牧师
    • 3个恶魔
    • 2个河岸
    • 1个船
    • 1条河
  • 游戏中玩家动作表为:

    • 每次开船时,船上至少有一个牧师或者一个恶魔;
    • 当玩家点击岸上的牧师或者恶魔时,这个牧师或恶魔应该跳上船;
    • 当某一个岸边的魔鬼数大于了牧师数量时,游戏失败;
    • 当3个牧师与3个魔鬼均到达河的另一岸时,游戏成功;
    • 当玩家点击重置按钮时,全部游戏对象回到最初的位置。
玩家动作 条件
船从起始处向终点处开船 船在起始处,船上至少有一个牧师或一个恶魔
船从终点处向起始处开船 船在终点处,船上至少有一个牧师或一个恶魔
恶魔在起始处上船 起始处有恶魔,船上有一个空位
牧师在起始处上船 起始处有牧师,船上有一个空位
船的左侧空位下船 船的左侧位上有牧师或恶魔
船的右侧空位下船 船的右侧位上有牧师或恶魔

先放出游戏成品图:

在制作的过程中,我的第一步首先是完成游戏界面的设计。我是先把GameObject先通过实例确定位置、大小。此处的河岸是用Cube加上贴图生成的;船是由Cylinder加上贴图生成的。此处的水,是用Unity自带的资源包生成的。找到水预设的方法如下:

  • 1、点击Assets,找到import package,点击Environment
  • 2、在Standard Assets中找到Environment,再找到Water,勾选后点击右下方的import即可。

    由于恶魔与牧师的3d版图形没有,于是我这里使用了Cube代替牧师,Sphere代替恶魔。
    在大体设置好了游戏界面的时候,即可通过拖动,生成游戏中各个对象的预设。这一步后,效果如下:

之后开始编程。MVC模式的要求,此游戏的架构可以是如下模式的:

模块 功能
GenGameObject 生成游戏中各个对象;判定游戏输赢
Director 控制游戏中各个对象的基类以及各种相应的事件
ClickGUI 检测用户操作,调用各个对象的方法
UserGUI 向用户提供提示信息

对于Director,我们需要实现的首先是个Director的对象,以及实现SceneController与UserAction两个接口:

public class Director : System.Object {private static Director _instance;public SceneController currentSceneController { get; set; }public static Director getInstance() {if (_instance == null) {_instance = new Director ();}return _instance;}
}public interface SceneController {void loadResources ();}public interface UserAction {void moveBoat();void characterIsClicked(MyCharacterController characterCtrl);void restart();}

在Director我们还需要实现各个游戏对象方法的接口类:
如对于船的移动,我们需要注意的是:判定船上是否有至少一个牧师或恶魔,船是从哪一边的河岸出发,向哪一边的河岸开动。此处定义了一个int型变量moving_status,有一下这个类:

public class Moveable: MonoBehaviour {readonly float move_speed = 20;int moving_status;  // 0->not moving, 1->moving to middle, 2->moving to destVector3 dest;Vector3 middle;void Update() {if (moving_status == 1) {transform.position = Vector3.MoveTowards (transform.position, middle, move_speed * Time.deltaTime);if (transform.position == middle) {moving_status = 2;}} else if (moving_status == 2) {transform.position = Vector3.MoveTowards (transform.position, dest, move_speed * Time.deltaTime);if (transform.position == dest) {moving_status = 0;}}}public void setDestination(Vector3 _dest) {dest = _dest;middle = _dest;if (_dest.y == transform.position.y) {  // boat movingmoving_status = 2;}else if (_dest.y < transform.position.y) {  // character from coast to boatmiddle.y = transform.position.y;} else {                                // character from boat to coastmiddle.x = transform.position.x;}moving_status = 1;}public void reset() {moving_status = 0;}
}

仿照这个类,我们还需要完成在事件列表中其他的几个类对象:

类对象 功能
CharacterController 对牧师与恶魔控制的一个类,完成牧师与恶魔上船、下船、随船一起过等事件时单独游戏对象位置的变化
BoatController 对船的状态进行控制,判断船上有多少个牧师或者恶魔
CoastController 对河岸的状态进行控制,判断岸上有多少牧师与恶魔

在ClickGUI中,我们需要的是检测用户鼠标点击的事件,并通过接口,完成对事件的响应。所以在ClickGUI中,我们的代码实现比较简单,主要如下:

public class ClickGUI : MonoBehaviour {UserAction action;MyCharacterController characterController;public void setController(MyCharacterController characterCtrl) {characterController = characterCtrl;}void Start() {action = Director.getInstance ().currentSceneController as UserAction;}void OnMouseDown() {if (gameObject.name == "boat") {action.moveBoat ();} else {action.characterIsClicked (characterController);}}
}

在UserGUI 中我们需要完成预设的实例化:

readonly Vector3 water_pos = new Vector3(0,0.5F,0);
UserGUI userGUI;public CoastController fromCoast;
public CoastController toCoast;
public BoatController boat;
private MyCharacterController[] characters;void Awake() {Director director = Director.getInstance ();director.currentSceneController = this;userGUI = gameObject.AddComponent <UserGUI>() as UserGUI;characters = new MyCharacterController[6];loadResources ();
}public void loadResources() {GameObject water = Instantiate (Resources.Load ("Perfabs/Water", typeof(GameObject)), water_pos, Quaternion.identity, null) as GameObject;water.name = "water";fromCoast = new CoastController ("from");toCoast = new CoastController ("to");boat = new BoatController ();loadCharacter ();
}
//加载资源
private void loadCharacter() {for (int i = 0; i < 3; i++) {MyCharacterController cha = new MyCharacterController ("priest");cha.setName("priest" + i);cha.setPosition (fromCoast.getEmptyPosition ());cha.getOnCoast (fromCoast);fromCoast.getOnCoast (cha);characters [i] = cha;}for (int i = 0; i < 3; i++) {MyCharacterController cha = new MyCharacterController ("devil");cha.setName("devil" + i);cha.setPosition (fromCoast.getEmptyPosition ());cha.getOnCoast (fromCoast);fromCoast.getOnCoast (cha);characters [i+3] = cha;}
}
//实例化牧师与恶魔对象
int check_game_over() { // 0->not finish, 1->lose, 2->winint from_priest = 0;int from_devil = 0;int to_priest = 0;int to_devil = 0;int[] fromCount = fromCoast.getCharacterNum ();from_priest += fromCount[0];from_devil += fromCount[1];int[] toCount = toCoast.getCharacterNum ();to_priest += toCount[0];to_devil += toCount[1];if (to_priest + to_devil == 6)      // winreturn 2;int[] boatCount = boat.getCharacterNum ();if (boat.get_to_or_from () == -1) { // boat at toCoastto_priest += boatCount[0];to_devil += boatCount[1];} else {    // boat at fromCoastfrom_priest += boatCount[0];from_devil += boatCount[1];}if (from_priest < from_devil && from_priest > 0) {      // losereturn 1;}if (to_priest < to_devil && to_priest > 0) {return 1;}return 0;           // not finish}
//判断游戏输赢public void restart() {boat.reset ();fromCoast.reset ();toCoast.reset ();for (int i = 0; i < characters.Length; i++) {characters [i].reset ();}
}
//游戏重新开始

此外我们在游戏的过程中,还需要加载一些对用户的提示信息:

public class UserGUI : MonoBehaviour {private UserAction action;public int status = 0;GUIStyle style;GUIStyle buttonStyle;void Start() {action = Director.getInstance ().currentSceneController as UserAction;style = new GUIStyle();style.fontSize = 40;style.alignment = TextAnchor.MiddleCenter;buttonStyle = new GUIStyle("button");buttonStyle.fontSize = 30;}void OnGUI() {if (status == 1) {GUI.Label(new Rect(Screen.width/2-50, Screen.height/2-85, 100, 50), "Gameover!", style);if (GUI.Button(new Rect(Screen.width/2-70, Screen.height/2, 140, 70), "Restart", buttonStyle)) {status = 0;action.restart ();}} else if(status == 2) {GUI.Label(new Rect(Screen.width/2-50, Screen.height/2-85, 100, 50), "You win!", style);if (GUI.Button(new Rect(Screen.width/2-70, Screen.height/2, 140, 70), "Restart", buttonStyle)) {status = 0;action.restart ();}}}
}

大体的代码就是这样完成的了,放上一张游戏成功的截图吧~

完整代码,请点击此处。

Unity3d-learning 牧师与恶魔相关推荐

  1. Unity3D游戏编程-牧师与恶魔

    Unity3D游戏编程-牧师与恶魔 文章目录 Unity3D游戏编程-牧师与恶魔 前置说明 牧师与恶魔 MVC架构 作业要求 项目配置 Object 玩家动作(规则表) 项目演示 视频演示 项目下载 ...

  2. unity3d 牧师与恶魔

    先挂一个github地址 https://github.com/ddghost/unity3d/tree/master/unity%20hw2 本次游戏的设计采用MVC模式,游戏中的所有GameObj ...

  3. Unity3D游戏编程-牧师与恶魔 动作分离版

    Unity3D游戏编程-牧师与恶魔 动作分离版 文章目录 Unity3D游戏编程-牧师与恶魔 动作分离版 作业要求 项目配置 项目演示 视频演示 项目下载 文字说明 项目截图 实现过程和方法(算法) ...

  4. [Unity3D课堂作业] Priests and Devils 牧师与恶魔

    #感觉这门课作业不提前写真搞不定啊_(:зゝ∠)_ #文末有全部代码以及操作方法 先把游戏效果po一下吧(白色胶囊体代表牧师.红色胶囊体代表魔鬼.蓝色代表船.两条白色圆柱体代表两岸): 这次作业与TA ...

  5. AR小游戏 牧师与恶魔

    AR小游戏 牧师与恶魔 前言 这是中山大学数据科学与计算机学院2019年3D游戏编程与设计的第十一次作业 所有项目与代码已上传至github当中,欢迎大家访问. github个人主页: https:/ ...

  6. 牧师与恶魔过河游戏——智能提示

    前言 这次实现一个含提示功能的牧师与恶魔过河小游戏,主要在上一个版本的牧师与恶魔小游戏上进行更改,通过增加一个状态计算和改版了得寻路算法,实现向玩家提示如何胜利完成游戏.游戏主体实现思路见上一篇博客- ...

  7. 3D游戏编程与设计 PD(牧师与恶魔)过河游戏智能帮助实现

    3D游戏编程与设计 P&D(牧师与恶魔) 过河游戏智能帮助实现 文章目录 3D游戏编程与设计 P&D(牧师与恶魔) 过河游戏智能帮助实现 一.作业与练习 二.设计简述 1. 状态图基础 ...

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

    Priests and Devils --动作分离版 完整工程文件在github(https://github.com/JennySRH/3DGame/tree/master/PriestsAndDe ...

  9. 3D游戏编程与设计 HW 4.5 牧师与恶魔(动作分离版)

    3D游戏编程与设计 HW 4.5 牧师与恶魔(动作分离版) 文章目录 3D游戏编程与设计 HW 4.5 牧师与恶魔(动作分离版) 1.作业要求 2.游戏制作 ① 设计思路 ② 设计代码 一.Actio ...

最新文章

  1. 会话中的存储技术和一些细节
  2. SAP ABAP里数据库表的Storage Parameters从哪里来的
  3. jQuery 遍历 - slice() 方法
  4. Python 字符串 - Python零基础入门教程
  5. 【英语学习】【WOTD】sentient 释义/词源/示例
  6. java多线程基础_java线程基础
  7. [解决方案]WebAPI+SwaggerUI部署服务器后,访问一直报错的问题
  8. 网络安全等级保护通用解决方案参考模板
  9. 解决 Mac OS 下罗技鼠标滚轮无法使用问题(滚动失效)
  10. 《持续集成实践指南》第3章 Gitlab基本配置与使用
  11. 计算机专业买什么牌子的笔记本,买笔记本电脑什么牌子好(2020年6月笔记本电脑推荐)...
  12. 计算机教室消防说明,6.7 消防专用电话的设置
  13. 输出乱码疑难杂症总结及解决方案
  14. 古老CPU启示录-意义重大的8008 芯片
  15. html5简介及常用标签
  16. Python获取拥有100万+关注的CSDN公众数据, 发现最关心的竟不是技术,而是…
  17. ASUS AC1900p 梅林固件编译 asuswrt-merlin
  18. Route命令使用详解
  19. 【转载】利用ENVI直接建立掩膜去除背景Inf值或NaN值
  20. java项目分享,学海无涯,未完待续!

热门文章

  1. FFmpeg框架与媒体处理
  2. tp5 部署两套模板(pc 手机端)
  3. RFS的web自动化验收测试——第16讲 RFS+AutoItLibrary测试web对话框
  4. 8条战术教你正确分析游戏性能问题
  5. java测试示例-生成ULID
  6. 基于 phylotree.js 基因进化树可视化图谱(gene-tree)
  7. zabbix 自定义监控文本内容
  8. 怎么在编辑器上将CAD转换成PDF格式后保存桌面?
  9. 智能家居实训(华清远见)第三天
  10. 电脑右下角出现一个脱机文件的图标,看着很心烦,如何关闭!