3D 游戏编程与设计:第3次作业
姓名:韩宝欣 学号:20331013
代码仓库:https://gitee.com/sse_20331013/3d-game.git
1、简答并用程序验证【建议做】
-
游戏对象运动的本质是什么?
本质是游戏对象在游戏每一帧的渲染过程中Transform属性在发生变化。这里物体的Transform属性是指Position与Rotation两个属性。
-
请用三种方法以上方法,实现物体的抛物线运动。(如,修改Transform属性,使用向量Vector3的方法…)
- 第一种方法
using System.Collections; using System.Collections.Generic; using UnityEngine; public class parabola : MonoBehaviour { public float speed1 = 4; public float speed2 = 0; public float speed = 3; // Use this for initialization void Start () { Debug.Log("Init start"); } // Update is called once per frame void Update () { if(speed1 >= 0){ speed1 = speed1 - 10 * Time.deltaTime; this.transform.position += Vector3.up * Time.deltaTime * speed1 / 2; } //此处为实现物体先上抛在竖直方向上位置的变化。 else{ speed2 = speed2 + 10 * Time.deltaTime; this.transform.position += Vector3.down * Time.deltaTime * speed2 / 2; } //此处为实现物体竖直方向速度减为0后 //平抛运动在竖直方向上位置的变化。 this.transform.position += Vector3.left * Time.deltaTime * speed; //此处为物体在水平上位置的变化。 } }
- 第二种方法,使用transform中的translate方法改变对象的位置。代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class parabola : MonoBehaviour {
public float speed1 = 4;
public float speed2 = 0;
public float speed = 3;
// Use this for initialization
void Start () {
Debug.Log("Init start");
}
// Update is called once per frame
void Update () {
if(speed1 >= 0)
{
speed1 = speed1 - 10 * Time.deltaTime;
transform.Translate(Vector3.up * Time.deltaTime * speed1 / 2, Space.World);
}
//此处为实现物体先上抛在竖直方向上位置的变化。
else
{
speed2 = speed2 + 10 * Time.deltaTime;
transform.Translate(Vector3.down * Time.deltaTime * speed2 / 2, Space.World);
}
//此处为实现物体竖直方向速度减为0后
//平抛运动在竖直方向上位置的变化。
transform.Translate(Vector3.left * Time.deltaTime * speed);
//此处为物体在水平上位置的变化。
}
}
- 第三种方法,新建一个vector3对象,改变这个对象的值,然后直接赋给物体。代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class parabola : MonoBehaviour {
public float speed1 = 4;
public float speed2 = 0;
public float speed = 3;
// Use this for initialization
void Start () {
Debug.Log("Init start");
}
// Update is called once per frame
void Update () {
if(speed1 >= 0)
{
speed1 = speed1 - 10 * Time.deltaTime;
Vector3 newOne = new Vector3(Time.deltaTime * speed, Time.deltaTime * speed1 / 2, 0);
this.transform.position += newOne;
}
//此处为实现物体先上抛在竖直方向上位置的变化。
else
{
speed2 = speed2 + 10 * Time.deltaTime;
Vector3 newOne = new Vector3(Time.deltaTime * speed, -Time.deltaTime * speed2 / 2, 0);
this.transform.position += newOne;
}
//此处为实现物体竖直方向速度减为0后
//平抛运动在竖直方向上位置的变化。
}
}
写一个程序,实现一个完整的太阳系, 其他星球围绕太阳的转速必须不一样,且不在一个法平面。
- 代码:3d-game/作业三/太阳系
- 运行截图
介绍框架和核心代码,源代码放在gitee上(省略了月球)
-
首先,在游戏Scene中设置太阳、水星、金星、地球、火星、木星、土星、天王星和海王星。将图片放置在球体上,如下:
-
设置各个行星的公转与自转速度,以及各自的法平面。
- 运动中心参考物体:太阳;
- Vector3变量axis:由两个float型的随机数组成:rx与ry,作为各行星运动的轴,代表行星运动的法平面;
- 设置除了Sun外所有行星的中心体为Sun:
-
将脚本
plantMove.cs
挂载到各个行星上,核心代码如下:void Update()
{
GameObject.Find(“Sun”).transform.Rotate(Vector3.up * Time.deltaTime * 5 );
GameObject.Find(“Mercury”).transform.RotateAround(Vector3.zero, new Vector3(0.1f, 1, 0), 60 * Time.deltaTime);
GameObject.Find(“Mercury”).transform.Rotate(Vector3.up * Time.deltaTime * 1 / 58);GameObject.Find("Venus").transform.RotateAround(Vector3.zero, new Vector3(0, 1, -0.1f), 55 * Time.deltaTime); GameObject.Find("Venus").transform.Rotate(Vector3.up * Time.deltaTime * 10 / 243); GameObject.Find("Earth").transform.RotateAround(Vector3.zero, new Vector3(0, 1, 0), 50 * Time.deltaTime); GameObject.Find("Earth").transform.Rotate(Vector3.up * Time.deltaTime * 10); GameObject.Find("Mars").transform.RotateAround(Vector3.zero, new Vector3(0.2f, 1, 0), 45 * Time.deltaTime); GameObject.Find("Mars").transform.Rotate(Vector3.up * Time.deltaTime * 10); GameObject.Find("Jupiter").transform.RotateAround(Vector3.zero, new Vector3(-0.1f, 2, 0), 35 * Time.deltaTime); GameObject.Find("Jupiter").transform.Rotate(Vector3.up * Time.deltaTime * 10 / 0.3f); GameObject.Find("Saturn").transform.RotateAround(Vector3.zero, new Vector3(0, 1, 0.2f), 20 * Time.deltaTime); GameObject.Find("Saturn").transform.Rotate(Vector3.up * Time.deltaTime * 10 / 0.4f); GameObject.Find("Uranus").transform.RotateAround(Vector3.zero, new Vector3(0, 2, 0.1f), 15 * Time.deltaTime); GameObject.Find("Uranus").transform.Rotate(Vector3.up * Time.deltaTime * 10 / 0.6f); GameObject.Find("Neptune").transform.RotateAround(Vector3.zero, new Vector3(-0.1f, 1, -0.1f), 10 * Time.deltaTime); GameObject.Find("Neptune").transform.Rotate(Vector3.up * Time.deltaTime * 10 / 0.7f); }
-
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!
-
代码要求
- 游戏效果:http://www.flash-game.net/game/2535/priests-and-devils.html
- 请将游戏中对象做成预制 (Prefab)
- 在场景控制器
LoadResources
方法中加载并初始化长方形、正方形、球及其色彩代表游戏中的对象 - 使用 C# 集合类型 有效组织对象
- 整个游戏仅主摄像机 和一个
Empty
对象, 其他对象必须代码动态生成!!!整个游戏不许出现Find 游戏对象,SendMessage
这类突破程序结构的通讯耦合语句 - 请使用课件架构图编程,不接受非 MVC 结构程序
- 注意细节,例如:船未靠岸,牧师与魔鬼上下船运动中,均不能接受用户事件
游戏实现
只介绍框架,源代码放在gitee上
-
代码:3d-game/作业三/牧师和恶魔
-
运行视频
-
游戏获胜截图:
-
游戏中提及的事物
- Priest
- Devil
- Boat
- Other environmental objects ——
Water
、Riverbank
-
玩家动作表(规则表)
动作 参数 结果 启动游戏 切换至初始界面 开始游戏(初始界面) 切换至游戏界面 重新开始(游戏界面 重新加载游戏界面资源 点击对象(游戏界面) 对象 对象根据当前位置移动 返回(游戏界面) 初始界面 -
MVC 架构
-
M (Model):代表游戏中所有的游戏对象,它们受各自的Controller控制。Model是游戏中存在的实体。
-
V (View):代表游戏呈现出的界面。主要包括GUI和Click两部分,GUI负责展示游戏结果,Click负责处理用户点击事件。
-
C (Controller):代表游戏中的控制器,分为FitstController(场景控制器)和SSDirector(导演)。由于本游戏只有一个场景,所以导演只用负责退出和暂停;场景控制器需要控制场景中的所有物体。
-
本游戏中,一共创建7个C#脚本来支持MVC架构。
- 游戏对象内部逻辑的实现(ModelController.cs):
- 水
- 陆地 (LandModel)
- 变量landSign:区分出发点和目的地;
- Vector3数组:存储角色的位置,共6个位置;
- RoleMode数组:存储角色的信息,共6个角色;
- 成员函数:更改成员变量,实现角色的上船和上岸动作。
- 船(BoatModel)
- Move对象和Click对象:被点击和移动;
- 变量boatSign:记录移动方向;
- Vector3数组startPos和endPos:保存角色的位置;
- RoleModel数组roles:保存角色的信息;
- 成员函数:移动和支持角色上船以及上岸动作。
- 角色/牧师和魔鬼(RoleMode)
- 变量roleSign,onBoat,landSign:标记身份,是否在船上,在哪块陆地上;
- Move和Click:角色的移动和被点击事件处理;
- 其他成员函数:例如状态设置set,移动move等。
- 控制类的实现
(SSDirect.cs/Interfaces.cs/FirstController.cs/MoveController.cs/ClickController.cs):
-
SSDirect.cs 使用单例模式,掌控全局;
- 写一个单例模式即可。
-
FirstController.cs 用于控制场景Scene;
- 其中具有之前的模型;
也要包含Interface中所有的成员函数
- 其中具有之前的模型;
-
Interfaces.cs 给FirstController.cs提供接口的,规范FirstController.cs的内容;
- ISceneController提供场景接口;
- IUserAction提供用户动作接口。
-
MoveController.cs 是用来控制物体的移动功能;
-
ClickController.cs 是用来控制物体被点击的动作。文章来源:https://www.toymoban.com/news/detail-486471.html
- GUI 类
- 实现UserGUI.cs:
主要绘制文本框和按钮即可,游戏对象不通过GUI展现。
变量sign:标记游戏的胜负;
按钮 restart :实现重新开始;
文本框 gametext :公布游戏结果。
参考:
Assets中其他的部分是直接copy师兄师的文章来源地址https://www.toymoban.com/news/detail-486471.html
到了这里,关于3D 游戏编程与设计:第3次作业的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!