简答并用程序验证
游戏对象运动的本质是什么?
游戏运动的本质是游戏对象随着时间帧的变化而做出相应的动作,包括坐标位置的改变,旋转和对相应的用户时间做出反应等。
请用三种方法以上方法,实现物体的抛物线运动。(如,修改Transform属性,使用向量Vector3的方法…)
修改Transform属性
根据平抛运动公式来分别实现x和y方向的运动方式:
public float speedX = 0.8f;public float sppedY = 0;public int gravity = 10;void Start () {Debug.Log("start!");}// Update is called once per framevoid Update () {ansform.position += Vector3.down * Time.deltaTime * ansform.position += Vector3.right * Time.deltaTime * speedX;speedY += gravity * Time.deltaTime;}
使用Vector3
void Update () {Vector3 vec = new Vector3(Time.deltaTime * speedX, -Time.deltaTime * speedY, 0);ansform.position += vec;speedY += gravity * Time.deltaTime;}
使用translate()函数
void Update(){Vector3 vec = new Vector3(Time.deltaTime * speedX, -Time.deltaTime * speedY, 0);ansform.Translate(vec);speedY += gravity * Time.deltaTime;}
写一个程序,实现一个完整的太阳系, 其他星球围绕太阳的转速必须不一样,且不在一个法平面上。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SolarSystem : MonoBehaviour
{public GameObject venus;public GameObject earth;public GameObject sun;public GameObject saturn;public GameObject uranus;public GameObject mercury;public GameObject mars;public GameObject jupiter;public GameObject neptune;void Start(){sun = GameObject.Find("sun");mercury = GameObject.Find("mercury");venus = GameObject.Find("venus");earth = GameObject.Find("earth");mars = GameObject.Find("mars");jupiter = GameObject.Find("jupiter");saturn = GameObject.Find("saturn");uranus = GameObject.Find("uranus");neptune = GameObject.Find("neptune");}// Update is called once per framevoid Update(){ansform.Rotate(Vector3.up * 3 * Time.deltaTime);ansform.ansform.position, new Vector3(0, 3.5f, 1), 200* Time.deltaTime);ansform.Rotate(new Vector3(0, 5, 1) * 5 * Time.deltaTime);ansform.ansform.position, new Vector3(0, 2.5f, 1), 100 * Time.deltaTime);ansform.Rotate(new Vector3(0, 2, 1) * Time.deltaTime);ansform.ansform.position, new Vector3(0, 9, 3), 30 * Time.deltaTime);ansform.Rotate(new Vector3(0, 10, 3) * 30 * Time.deltaTime);ansform.ansform.position, new Vector3(0, 2, 1), 20 * Time.deltaTime);ansform.Rotate(new Vector3(0, 3, 1) * 20 * Time.deltaTime);ansform.ansform.position, new Vector3(0, 10, 1), 10 * Time.deltaTime);ansform.Rotate(new Vector3(0, 10, 1) * 20 * Time.deltaTime);ansform.ansform.position, new Vector3(0, 7.5f, 1), 5 * Time.deltaTime);ansform.Rotate(new Vector3(0, 8, 1) * 30 * Time.deltaTime);ansform.ansform.position, Vector3.up, 50 * Time.deltaTime);ansform.Rotate(Vector3.up * 30 * Time.deltaTime);ansform.ansform.position, new Vector3(0, 12, 5), 40 * Time.deltaTime);ansform.Rotate(new Vector3(0, 12, 5) * 40 * Time.deltaTime);}
}
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 (
.html )
列出游戏中提及的事物(Objects)
用表格列出玩家动作表(规则表),注意,动作越少越好
请将游戏中对象做成预制
在 GenGameObjects 中创建 长方形、正方形、球 及其色彩代表游戏中的对象。
使用 C# 集合类型 有效组织对象
整个游戏仅 主摄像机 和 一个 Empty 对象, 其他对象必须代码动态生成!!! 。 整个游戏不许出现 Find 游戏对象, SendMessage 这类突破程序结构的 通讯耦合 语句。 违背本条准则,不给分
请使用课件架构图编程,不接受非 MVC 结构程序
注意细节,例如:船未靠岸,牧师与魔鬼上下船运动中,均不能接受用户事件!
动作 | 结果 | 约束 |
---|---|---|
点击牧师 | 牧师移动(陆地–船 or 船–陆地) | 牧师与船在同侧;船或牧师没有在移动过程中;游戏未结束 |
点击魔鬼 | 魔鬼移动(陆地–船 or 船–陆地) | 魔鬼与船在同侧;船或魔鬼没有在移动过程中;游戏未结束 |
点击船 | 船移动 | 船未在移动过程中;船上有乘客;游戏未结束 |
MVC架构:
主要的几个类:
游戏对象搭建:
一开始我使用unity自带的3DObject搭建对象,后来觉得不太美观,于是就从asset store上下载了一些预设,这样看起来会稍微好一些:
devil:
priest:
然后因为在之后需要对象捕捉到鼠标的点击动作,所以要为它们分别添加一个capsule collider组件,不然鼠标点击了没有反应。
对于boat、land和river,就索性用了cube,然后改变下参数,加上不同的material:
刚好上节课学了天空盒的设置,在这里就顺便加上了一个:
大体看上去是这样子:
关键模块
SSDirector
SSDirector获取当前游戏的场景,掌握着游戏整体运行的节奏,管理游戏全局状态,并设定相关的配置,是游戏的整体指挥者。
public class SSDirector : System.Object{private static SSDirector _instance;public ISceneController currentSceneController { get; set; }public static SSDirector getInstance(){if (_instance == null){_instance = new SSDirector();}return _instance;}}
两个接口ISceneController和UserAction分别提供场景加载和游戏对象响应函数的接口:
public interface ISceneController{void loadResources();}public interface UserAction{void moveBoat(); //move boatvoid restart(); //restart gamevoid objectClicked(chCtrl.CharacterController ch);}
CharacterControlller
实现对游戏角色的加载和运动控制,通过构造函数进行初始化,然后实现了一些角色的运动函数,如setPosition(), movePos(), getOnBoat()等,并提供一些角色的状态信息,以便FirstController来对角色进行总体地调度。
public CharacterController(string ch_name){if (ch_name == "priest"){obj = Object.Instantiate(Resources.Load("prefabs/priest", typeof(GameObject)), , Quaternion.identity, null) as ansform.Rotate(Vector3.up, -90);objMark = 0;}if (ch_name == "devil"){obj = Object.Instantiate(Resources.Load("prefabs/devil", typeof(GameObject)), , Quaternion.identity, null) as ansform.Rotate(Vector3.up, -90);objMark = 1;}move = obj.AddComponent(typeof(Move)) as Move;clickGUI = obj.AddComponent(typeof(ClickGUI)) as ClickGUI;clickGUI.setController(this);}public void reset(){set();landController = (Instance().currentSceneController as FirstController).startLand;getOnLand(landController);EmptyPlace());landController.addObj(this);}public int getMark() { return objMark; }public string getName() { return obj.name; }public LandController getLandController() { return landController; }public bool isOnBoat() { return onBoat; }public void setName(string name) { obj.name = name; }public void setPosition(Vector3 pos) { ansform.position = pos; }public void movePos(Vector3 dest) { move.setDest(dest); }public void getOnBoat(BoatController bo){landController = ansform.parent = bo.getGameobj().transform;onBoat = true;}public void getOnLand(LandController la){landController = ansform.parent = null;onBoat = false;}
LandController/BoatController
作用和CharacterController类似,都是对相应的对象进行控制,在LandController中会提供给FirstController陆地上的状态信息,例如空余的位置,在陆地上的角色信息,还有上岸离岸的操作。BoatController控制船的移动,提供船上角色信息,以及上岸上船操作。
public LandController(string _state){passenger = new chCtrl.CharacterController[6];pos = new Vector3[] {new Vector3(6.5F,0.8f,0), new Vector3(7.5F,0.8F,0),new Vector3(8.5F,0.8F,0),new Vector3(9.5F,0.8F,0), new Vector3(10.5F,0.8F,0),new Vector3(11.5F,0.8F,0)}; //object positionif (_state == "from") //from{land = Object.Instantiate(Resources.Load("prefabs/land", typeof(GameObject)), startPos, Quaternion.identity, null) as GameObject;land.name = "from";state = 1;}else //to{land = Object.Instantiate(Resources.Load("prefabs/land", typeof(GameObject)), endPos, Quaternion.identity, null) as GameObject;land.name = "to";state = -1;}}public int getEmptyNum(){for (int i = 0; i < passenger.Length; i++){if (passenger[i] == null) return i;}return -1;}public Vector3 getEmptyPlace(){int index = getEmptyNum();Vector3 v = pos[index];v.x *= state;return v;}public int getState(){return state;}public int[] getObjNum(){int[] count = { 0, 0 };for (int i = 0; i < passenger.Length; i++){if (passenger[i] == null) continue;if (passenger[i].getMark() == 0) count[0]++; //pelse count[1]++; //d}return count;}public void addObj(chCtrl.CharacterController ch) //get on land{int index = getEmptyNum();passenger[index] = ch;}public chCtrl.CharacterController removeObj(string name) //get off land{for (int i = 0; i < passenger.Length; i++){if (passenger[i] != null && passenger[i].getName() == name){chCtrl.CharacterController ch = passenger[i];passenger[i] = null;return ch;}}return null;}
public BoatController(){state = 1;startPoss = new Vector3[] { new Vector3(4.5F, 0.8f, 0), new Vector3(5.5F, 0.8f, 0) };endPoss = new Vector3[] { new Vector3(-5.5F, 0.8f, 0), new Vector3(-4.5F, 0.8f, 0) };boat = Object.Instantiate(Resources.Load("prefabs/boat", typeof(GameObject)), startPos, Quaternion.identity, null) as GameObject;boat.name = "boat";move = boat.AddComponent(typeof(Move)) as Move;boat.AddComponent(typeof(ClickGUI));}public void reset(){set();if (state == -1) Move();passenger = new chCtrl.CharacterController[2];}public GameObject getGameobj() { return boat; }public int getState() { return state; }public int[] getObjNum() //return obj index{int[] count = { 0, 0 };for (int i = 0; i < passenger.Length; i++){if (passenger[i] == null)continue;if (passenger[i].getMark() == 0){count[0]++;}else{count[1]++;}}return count;}public void Move() //boat move{if (state == -1) //to{move.setDest(startPos);state = 1;}else //from{move.setDest(endPos);state = -1;}}public int getEmptyNum(){for (int i = 0; i < passenger.Length; i++){if (passenger[i] == null){return i;}}return -1;}public Vector3 getEmptyPlace(){Vector3 pos = new Vector3();int index = getEmptyNum();if (state == -1) //to{pos = endPoss[index];}if (state == 1) //from{pos = startPoss[index];}return pos;}public bool isEmpty(){for (int i = 0; i < passenger.Length; i++){if (passenger[i] != null){return false;}}return true;}public void getOnBoat(chCtrl.CharacterController ch){int index = getEmptyNum();passenger[index] = ch;}public chCtrl.CharacterController getOffBoat(string name){for (int i = 0; i < passenger.Length; i++){if (passenger[i] != null && passenger[i].getName() == name){chCtrl.CharacterController ch = passenger[i];passenger[i] = null;return ch;}}return null;}
FirstController
实现对所有游戏对象的控制,根据各个controller提供的信息来进行相关函数调用。同时实现了ISceneController和UserAction的函数接口。
public void loadResources(){GameObject river = Instantiate(Resources.Load("prefabs/river", typeof(GameObject)), riverPos, Quaternion.identity, null) as GameObject;river.name = "river";startLand = new LandController("from");endLand = new LandController("to");boat = new BoatController();for (int i = 0; i < 3; i ++){chCtrl.CharacterController _ch = new chCtrl.CharacterController("priest");_ch.setName("priest[" + i + "]");_ch.EmptyPlace());_ch.getOnLand(startLand);startLand.addObj(_ch);ch[i] = _ch;}for (int i = 0; i < 3; i++){chCtrl.CharacterController _ch = new chCtrl.CharacterController("devil");_ch.setName("devil[" + i + "]");_ch.EmptyPlace());_ch.getOnLand(startLand);startLand.addObj(_ch);ch[i + 3] = _ch;}}public void moveBoat(){if (boat.isEmpty()) return;boat.Move();userGUI.status = check();}public void objectClicked(chCtrl.CharacterController _ch){if (_ch.isOnBoat()) //obj is on boat{LandController land;if (State() == -1) land = endLand;else land = OffBoat(_ch.getName());_ch.EmptyPlace());_ch.getOnLand(land);land.addObj(_ch);}else //obj is on land{LandController land = _ch.getLandController();if (EmptyNum() == -1) return; //full boatif (State() != State()) return; //veObj(_ch.getName());_ch.EmptyPlace());_ch.getOnBoat(boat);OnBoat(_ch);}userGUI.status = check();}int check(){int start_p = 0, start_d = 0, end_p = 0, end_d = 0;int[] start_count = ObjNum();start_p += start_count[0];start_d += start_count[1];int[] end_count = ObjNum();end_p += end_count[0];end_d += end_count[1];if (end_p + end_d == 6) return 2;int[] boatCount = ObjNum();if (State() == -1) //to{end_p += boatCount[0];end_d += boatCount[1];}if (State() == 1) //from{start_p += boatCount[0];start_d += boatCount[1];}if (start_p < start_d && start_p > 0){ return 1;}if (end_p < end_d && end_p > 0){return 1;}return 0;}public void restart(){set();set();set();for (int i = 0; i < ch.Length; i++) ch[i].reset();}
UserGUI
加载了游戏界面信息,包括按钮和标题等。
void Start(){userAction = Instance().currentSceneController as UserAction;}void OnGUI(){GUIStyle fontstyle = new GUIStyle();al.background = al.textColor = new Color(255, 192, 203);fontstyle.fontSize = 50;style = new GUIStyle(){fontSize = 50};Color = new Color(0, 0, 0);buttonStyle = new GUIStyle("button"){fontSize = 10};GUI.Label(new Rect(250, 15, 100, 100), "Priest & Devil", fontstyle); //titleif (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 = start();}}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 = start();}}}
除此之外,还有Move和ClickGUI等辅助类,定义物体的运动和鼠标点击后的事件等,具体代码见github。
github
本文发布于:2024-02-02 17:39:33,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170686677445390.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |