内容一:修改飞碟游戏
要求:
- 按设计图修改飞碟游戏
- 使它同时支持物理运动与运动学(变换)运动
架构图
根据MVC结构,以及物理运动和运动学运动分离的要求,我参照别人的博客的UML来编写代码。
层次安排
Prefabs放的是爆炸的产生效果等预制Resources放的是预制的飞碟和地面,Scenes存放的是场景,Scripts存放的是c#代码。
代码组织
【飞碟类】
把属性和动作分别用DiskData和DiskFactoru实现,达到动作和属性的分离。
【飞碟动作类】
动作有两类,管理和实现分别由Action和Manager类负责。飞碟的动作类别由一个人为设定的变量控制是物理运动还是运动学运动。
运动学和物理学的不同就在于,运动学需要用代码设置位移的变化,而物理学只需要设置初始的向量和速度方向即可实现斜抛运动。
运动学:
【计分类】
游戏的计分由ScoreRecorder类负责。击中一个飞碟得1分,总共分三回合,累计10分进入第二个回合,累积25分进入第三个回合,飞碟速度随着回合数增加。
【游戏控制类】
FirstController负责整个游戏的运行,包括加载资源、开始游戏、发送并回收飞碟、判断击中、游戏结束、获取分数、重新开始游戏。
【用户UI类】
在游戏界面上呈现游戏分数、玩家生命(初始为5条生命)。游戏结束后会呈现最高分和重新开始按钮。
void OnGUI ()
{
bold_style.normal.textColor = new Color(1, 0, 0);
bold_style.fontSize = 16;
text_style.normal.textColor = new Color(0,0,0, 1);
text_style.fontSize = 16;
score_style.normal.textColor = new Color(1,0,1,1);
score_style.fontSize = 16;
over_style.normal.textColor = new Color(1, 0, 0);
over_style.fontSize = 25;
if (game_start)
{
//用户射击
if (Input.GetButtonDown("Fire1"))
{
Vector3 pos = Input.mousePosition;
action.Hit(pos);
}
GUI.Label(new Rect(10, 5, 200, 50), "Score:", text_style);
GUI.Label(new Rect(55, 5, 200, 50), action.GetScore().ToString(), score_style);
GUI.Label(new Rect(Screen.width - 120, 5, 50, 50), "Life:", text_style);
//显示当前血量
for (int i = 0; i < life; i++)
{
GUI.Label(new Rect(Screen.width - 75 + 10 * i, 5, 50, 50), "X", bold_style);
}
//游戏结束
if (life == 0)
{
high_score = high_score > action.GetScore() ? high_score : action.GetScore();
GUI.Label(new Rect(Screen.width / 2 - 20, Screen.width / 2 - 250, 100, 100), "Game Over", over_style);
GUI.Label(new Rect(Screen.width / 2 - 10, Screen.width / 2 - 200, 50, 50), "Top Score:", text_style);
GUI.Label(new Rect(Screen.width / 2 + 50, Screen.width / 2 - 200, 50, 50), high_score.ToString(), text_style);
if (GUI.Button(new Rect(Screen.width / 2 - 20, Screen.width / 2 - 150, 100, 50), "Restart"))
{
life = 5;
action.ReStart();
return;
}
action.GameOver();
}
}
else
{
if (GUI.Button(new Rect(Screen.width / 2 - 20, Screen.width / 2-150, 100, 50), "Start"))
{
game_start = true;
action.BeginGame();
}
}
}
代码和游戏视频
内容二:打靶游戏
要求:
- 靶标对象
- Root
- Target(显示网格)
- Objective1…5(一圈一个,计分用)
- 箭对象
- Root(射中后,变为运动学刚体)
- 箭头(射中后,箭头会inactive)
- 箭身(射中后,箭身插在靶标上
- 请完成该第一人称游戏(使用物理)!
- 添加一个风向和强度标志,提高游戏难度
架构图
和上一个游戏类似,箭的属性和运动控制都有专门的类,除此之外,参考师兄的博客,多了主副相机和碰撞检测的类。
代码组织
【Camera类】
主摄像机跟随弓的移动而移动,它们之间有一个固定的相对距离。
副摄像机只固定拍摄放大靶子的情况,便于玩家判断是否射中。当箭没有射出去时不显示副摄像机的内容,当箭射出去之后显示。
【弓箭类】
- 箭发射出去,但还没有到达靶子时,箭头可见。
ArrowFactory.cs
- 碰撞检测类:箭触碰到靶子后,箭的飞行速度变为0,箭头消失。
CollisionDetection.cs
- 箭中靶后,通过回调函数告诉动作管理器,去执行箭颤抖动作。箭颤抖是通过短时间内上下快速移动实现的。
【场景控制类】 - SSActionEvent
在箭飞行后会执行一个回调函数SSActionEvent,传递现在中靶的GameObject。实现这个回调函数就可以让箭颤抖动作开始。
- FirstSceneController
(1)游戏每帧更新时,都要检查当前场景中的箭是否需要回收,如果超过5根箭或者箭超出了边界,则回收。
(2)弓在未发射箭时,可以自由移动,但是有一定的范围。
(3)生成风向的时候以x、y为轴,随机生成一个位置,根据位置的正负和绝对值的大小来定义风向和风级。以下是部分代码:
【UI类】 - 在游戏开始时,呈现游戏的操作方法,通过WSAD键或者方向键来控制弓的移动,鼠标点击表示射出一根箭。
- 游戏过程中,屏幕会呈现当前分数、目标分数、所剩弓箭数和风向级别。
- 游戏结束后,会显示“重新开始”按钮,可以点击重玩。