3d游戏第三次作业

阅读: 评论:0

3d游戏第三次作业

3d游戏第三次作业

3d游戏第三次作业

  • 1、简答并用程序验证【建议做】
    • 游戏对象运动的本质是什么?
    • 请用三种方法以上方法,实现物体的抛物线运动。(如,修改Transform属性,使用向量Vector3的方法…)
  • 2、编程实践
    • 主要的一些类的解释:
      • Director
      • 四个控制类
      • ClickGUI
  • 3、思考题【选做】

1、简答并用程序验证【建议做】

游戏对象运动的本质是什么?

是游戏物体随着时间的变化而引起空间的变化。具体来说就是当刷新帧的时候,游戏物体transorm参数变化,具体包括position和rotation的变化。

请用三种方法以上方法,实现物体的抛物线运动。(如,修改Transform属性,使用向量Vector3的方法…)

抛物线运动是水平匀速,竖直方向加速。第一种方法可以直接在update修改每一帧的时候直接更新transform的属性:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Move : MonoBehaviour
{private float speedx = 5;private float speedy = 0;private float g = 10;// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){      transform.position += Vector3.right * speedx * Time.deltaTime;transform.position += Vector3.down * speedy * Time.deltaTime;speedy += g * Time.deltaTime;}
}

也可以使用Vector3来间接修改(在上面代码基础上修改如下代码段):

void Update(){speedy += g * Time.deltaTime;Vector3 temp = new Vector3(speedx * Time.deltaTime, -speedy * Time.deltaTime, 0);transform.position += temp;}

还可以修改物体的重力属性来实现:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Move : MonoBehaviour
{void Start(){gameObject.AddComponent<Rigidbody>();gameObject.GetComponent<Rigidbody>().velocity = new Vector3(1, 0, 0);}void Update() { }
}

写一个程序,实现一个完整的太阳系, 其他星球围绕太阳的转速必须不一样,且不在一个法平面上。

创建太阳系:

脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class solarSystem : MonoBehaviour
{public Transform sun;public Transform mercury;public Transform venus;public Transform earth;public Transform mars;public Transform jupiter;public Transform saturn;public Transform uranus;public Transform neptune;void Start() { }void Update(){sun.Rotate(Vector3.up,  Time.deltaTime * 10);mercury.ansform.position, new Vector3(1, 10, 0), 50 * Time.deltaTime);mercury.Rotate(Vector3.up,  Time.deltaTime * 100);venus.ansform.position, new Vector3(1, 13, 0), 40 * Time.deltaTime);venus.Rotate(Vector3.up,  Time.deltaTime * 100);earth.ansform.position, new Vector3(1, 15, 0), 35 * Time.deltaTime);earth.Rotate(Vector3.up,  Time.deltaTime * 100);mars.ansform.position, new Vector3(2, 10, 0), 30 * Time.deltaTime);mars.Rotate(Vector3.up,  Time.deltaTime * 100);jupiter.ansform.position, new Vector3(2, 13, 0), 20 * Time.deltaTime);jupiter.Rotate(Vector3.up,  Time.deltaTime * 100);saturn.ansform.position, new Vector3(2, 15, 0), 15 * Time.deltaTime);saturn.Rotate(Vector3.up,  Time.deltaTime * 100);uranus.ansform.position, new Vector3(3, 10, 0), 10 * Time.deltaTime);uranus.Rotate(Vector3.up,  Time.deltaTime * 100);neptune.ansform.position, new Vector3(3, 15, 0), 9 * Time.deltaTime);neptune.Rotate(Vector3.up,  Time.deltaTime * 100);}
}

运行效果

2、编程实践

阅读以下游戏脚本

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)
  • 用表格列出玩家动作表(规则表),注意,动作越少越好
  • 请将游戏中对象做成预制
  • 在场景控制器 LoadResources 方法中加载并初始化 长方形、正方形、球 及其色彩代表游戏中的对象。
  • 使用 C# 集合类型 有效组织对象
  • 整个游戏仅 主摄像机 和 一个 Empty 对象, 其他对象必须代码动态生成!!! 。 整个游戏不许出现 Find 游戏对象, SendMessage 这类突破程序结构的 通讯耦合 语句。 违背本条准则,不给分
  • 请使用课件架构图编程,不接受非 MVC 结构程序
  • 注意细节,例如:船未靠岸,牧师与魔鬼上下船运动中,均不能接受用户事件!

游戏中的对象:牧师、魔鬼、小船、河岸、河水
玩家动作表(规则表)

动作条件结果
点击岸上的牧师或者魔鬼船未满并且在岸边点击的牧师或者魔鬼上船
点击小船船上有牧师或者魔鬼移动到另一岸
点击船上的牧师或魔鬼船在岸边牧师或者魔鬼上岸

创建预制,将牧师做成浅黄方块,恶魔做成深红方块

见上图,资源被整合成材料、预制和脚本三个文件夹。

  • 运行前的游戏对象
  • 运行后的游戏对象

    使用MVC架构:
  • 模型(Model):数据对象及关系
    所有的GameObject
  • 控制器(Controller):接受用户事件,控制模型的变化
    Director类,FirstController类,Move类,RolesController类,CoastController类,BoatController类
  • 界面(View):显示模型,将人机交互事件交给控制器处理
    UserGUI和ClickGUI脚本

主要的一些类的解释:

Director

获取当前游戏的场景
控制场景运行、切换、入栈与出栈
暂停、恢复、退出
管理游戏全局状态
设定游戏的配置
设定游戏全局视图

	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;}}

可以看到无论何时调用getInstance()都会得到同一个实例,这保证了导演类的唯一性,也能保证导演类控制场记的作用。

四个控制类

Moveable
 控制游戏物体的移动
RolesController
 控制牧师或者魔鬼
CoastController
 控制河岸
BoatController
 控制小船

	public class Moveable: MonoBehaviour {readonly float move_speed = 30;int moving_status;	// 0->not moving, 1->moving end middle, 2->moving end 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)moving_status = 2;else if (_dest.y < transform.position.y) middle.y = transform.position.y;else 						middle.x = transform.position.x;moving_status = 1;}public void reset() {moving_status = 0;}}public class RolesController {readonly GameObject character;readonly Moveable moveableScript;readonly ClickGUI clickGUI;readonly int RoleType;	// 0->priest, 1->devil// change frequentlybool _isOnBoat;CoastController coastController;public RolesController(string which_character) {if (which_character == "priest") {character = Object.Instantiate (Resources.Load ("Perfabs/Priest", typeof(GameObject)), , Quaternion.identity, null) as GameObject;RoleType = 0;} else {character = Object.Instantiate (Resources.Load ("Perfabs/Devil", typeof(GameObject)), , Quaternion.identity, null) as GameObject;RoleType = 1;}moveableScript = character.AddComponent (typeof(Moveable)) as Moveable;clickGUI = character.AddComponent (typeof(ClickGUI)) as ClickGUI;clickGUI.setController (this);}public void setName(string name) {character.name = name;}public void setPosition(Vector3 pos) {ansform.position = pos;}public void moveToPosition(Vector3 destination) {moveableScript.setDestination(destination);}public int getType() {	// 0->priest, 1->devilreturn RoleType;}public string getName() {return character.name;}public void getOnBoat(BoatController boatCtrl) {coastController = ansform.parent = Gameobj().transform;_isOnBoat = true;}public void getOnCoast(CoastController coastCtrl) {coastController = ansform.parent = null;_isOnBoat = false;}public bool isOnBoat() {return _isOnBoat;}public CoastController getCoastController() {return coastController;}public void reset() {set ();coastController = (Instance ().currentSceneController as FirstController).bankbegin;getOnCoast (coastController);setPosition (EmptyPosition ());OnCoast (this);}}public class CoastController {readonly GameObject coast;readonly Vector3 from_pos = new Vector3(9,1,0);readonly Vector3 to_pos = new Vector3(-9,1,0);readonly Vector3[] positions;readonly int postion;	// end->-1, begin->1// change frequentlyRolesController[] passengerPlaner;public CoastController(string _postion) {positions = new Vector3[] {new Vector3(6.5F,2.25F,0), new Vector3(7.5F,2.25F,0), new Vector3(8.5F,2.25F,0), new Vector3(9.5F,2.25F,0), new Vector3(10.5F,2.25F,0), new Vector3(11.5F,2.25F,0)};passengerPlaner = new RolesController[6];if (_postion == "begin") {coast = Object.Instantiate (Resources.Load ("Perfabs/Bank", typeof(GameObject)), from_pos, Quaternion.identity, null) as GameObject;coast.name = "begin";postion = 1;} else {coast = Object.Instantiate (Resources.Load ("Perfabs/Bank", typeof(GameObject)), to_pos, Quaternion.identity, null) as GameObject;coast.name = "end";postion = -1;}}public int getEmptyIndex() {for (int i = 0; i < passengerPlaner.Length; i++) if (passengerPlaner [i] == null) return i;return -1;}public Vector3 getEmptyPosition() {Vector3 pos = positions [getEmptyIndex ()];pos.x *= postion;return pos;}public void getOnCoast(RolesController characterCtrl) {int index = getEmptyIndex ();passengerPlaner [index] = characterCtrl;}public RolesController getOffCoast(string passenger_name) {	// 0->priest, 1->devilfor (int i = 0; i < passengerPlaner.Length; i++) if (passengerPlaner [i] != null && passengerPlaner [i].getName () == passenger_name) {RolesController charactorCtrl = passengerPlaner [i];passengerPlaner [i] = null;return charactorCtrl;}Debug.Log ("cant find passenger on coast: " + passenger_name);return null;}public int where() {return postion;}public int[] getRoleNum() {int[] count = {0, 0};for (int i = 0; i < passengerPlaner.Length; i++) {if (passengerPlaner [i] == null)continue;if (passengerPlaner [i].getType () == 0) 	// 0->priest, 1->devilcount[0]++;else count[1]++;}return count;}public void reset() {passengerPlaner = new RolesController[6];}}public class BoatController {readonly GameObject boat;readonly Moveable moveableScript;readonly Vector3 fromPosition = new Vector3 (5, 1, 0);readonly Vector3 toPosition = new Vector3 (-5, 1, 0);readonly Vector3[] beginPostion;readonly Vector3[] endPostion;// change frequentlyint postion; // end->-1; begin->1RolesController[] passenger = new RolesController[2];public BoatController() {postion = 1;beginPostion = new Vector3[] { new Vector3 (4.5F, 1.5F, 0), new Vector3 (5.5F, 1.5F, 0) };endPostion = new Vector3[] { new Vector3 (-5.5F, 1.5F, 0), new Vector3 (-4.5F, 1.5F, 0) };boat = Object.Instantiate (Resources.Load ("Perfabs/Boat", typeof(GameObject)), fromPosition, Quaternion.identity, null) as GameObject;boat.name = "boat";moveableScript = boat.AddComponent (typeof(Moveable)) as Moveable;boat.AddComponent (typeof(ClickGUI));}public void Move() {if (postion == -1) {moveableScript.setDestination(fromPosition);postion = 1;} else {moveableScript.setDestination(toPosition);postion = -1;}}public int getEmptyIndex() {for (int i = 0; i < passenger.Length; i++) if (passenger [i] == null) return i;return -1;}public bool isEmpty() {for (int i = 0; i < passenger.Length; i++) if (passenger [i] != null) return false;return true;}public Vector3 getEmptyPosition() {Vector3 pos;int emptyIndex = getEmptyIndex ();if (postion == -1) pos = endPostion[emptyIndex];else pos = beginPostion[emptyIndex];return pos;}public void GetOnBoat(RolesController characterCtrl) {int index = getEmptyIndex ();passenger [index] = characterCtrl;}public RolesController GetOffBoat(string passenger_name) {for (int i = 0; i < passenger.Length; i++)if (passenger [i] != null && passenger [i].getName () == passenger_name) {RolesController charactorCtrl = passenger [i];passenger [i] = null;return charactorCtrl;}Debug.Log ("Cant find passenger in boat: " + passenger_name);return null;}public GameObject getGameobj() {return boat;}public int where() { // end->-1; begin->1return postion;}public int[] getRoleNum() {int[] count = {0, 0};for (int i = 0; i < passenger.Length; i++) {if (passenger [i] == null)continue;if (passenger [i].getType () == 0)	// 0->priest, 1->devilcount[0]++;elsecount[1]++;}return count;}public void reset() {set ();if (postion == -1)Move ();passenger = new RolesController[2];}}
}

ClickGUI

相应玩家的点击,将该动作传给相应类实现操作

public class ClickGUI : MonoBehaviour {UserAction action;RolesController characterController;public void setController(RolesController rolectrl) {characterController = rolectrl;}void Start() {action = Instance ().currentSceneController as UserAction;}void OnMouseDown() {if (gameObject.name == "boat") {veBoat ();} else {action.characterIsClicked (characterController);}}
}

运行效果
源码

运行游戏的方法1:
下载asset替换自己新建的项目,并将两个GUI脚本挂载到空对象中,将firstconctroller脚本挂载到摄影机上。

运行游戏的方法2:
直接打开asset中的priestAndDevil.unity。

3、思考题【选做】

使用向量与变换,实现并扩展 Tranform 提供的方法,如 Rotate、RotateAround 等

对于i、j、k本身的几何意义可以理解为一种旋转,其中i旋转代表X轴与Y轴相交平面中X轴正向向Y轴正向的旋转,j旋转代表Z轴与X轴相交平面中Z轴正向向X轴正向的旋转,k旋转代表Y轴与Z轴相交平面中Y轴正向向Z轴正向的旋转,见下图:

静态方法 Quaternion.Euler(x,y,z),直观上按 z、x、y 轴旋转的一个序列。因为旋转矩阵连乘得到复合旋转,故 q = qy * qx * qz
Rotation

public void Rotate(Transform trans,float anglex, float angley, float anglez){Quaternion p1 = Quaternion.AngleAxis(anglez, Vector3.forward);Quaternion p2 = Quaternion.AngleAxis(anglex, Vector3.right);Quaternion p3 = Quaternion.AngleAxis(angley, Vector3.up);ation *= p3 * p2 * p1;
}

RotateAround
围绕通过世界坐标中点的轴旋转变换角度

public void RotateAround(Transform trans,Vector3 point, Vector3 axis, float angle){Quaternion p = Quaternion.AngleAxis(angle,axis);Vector3 distance = myTransform.position - point;trans.position = p * myTransform.ation *= p;  
}

本文发布于:2024-01-27 18:55:59,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17063529612014.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:作业   游戏
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23