文章目录
打飞碟(Hit UFO)游戏
- 游戏内容要求:
- 游戏有 n 个 round,每个 round 都包括10 次 trial;
- 每个 trial 的飞碟的色彩、大小、发射位置、速度、角度、同时出现的个数都可能不同。它们由该 round 的 ruler 控制;
- 每个 trial 的飞碟有随机性,总体难度随 round 上升;
- 鼠标点中得分,得分规则按色彩、大小、速度不同计算,规则可自由设定。
- 游戏的要求:
- 使用带缓存的工厂模式管理不同飞碟的生产与回收,该工厂必须是场景单实例的!具体实现见参考资源 Singleton 模板类
- 尽可能使用前面 MVC 结构实现人机交互与游戏模型分离
参考:弹药和敌人:减少,重用和再利用
代码与视频
Github: https://github.com/colorfuljor/3D-Game/tree/master/homework/hw5/src/Hit%20UFO
打飞碟演示视频:https://v.youku.com/v_show/id_XNDM3OTU4OTU4MA==.html?spm=a2hzp.8244740.0.0
00:08 展示了游戏暂停功能
00:16 Round 1
00:50 Round 2
01:30 Round 3
02:15 展示了扣分功能
游戏简介
该游戏总共有三个回合,每个回合都比上一个回合难度更大,每个回合都是40秒的时间,三个回合结束后游戏结束,获得最终分数。首先是回合一,只有黄色飞碟(普通飞碟,速度正常,奖励1分),这一回合需要达到20分才能晋级到下一回合。然后是回合二,加进了红色飞碟(快速飞碟,速度快,奖励2分),这一回合需要达到50分才能晋级下一回合。最后一个回合,加进了蓝色飞碟(分身飞碟,速度正常,但会同时3个飞碟一起飞到空中,一个飞碟奖励1分,总共3分),这一回合40秒过后游戏结束。同时,还有一个注意点,遗漏了飞碟会扣两分。
实现过程:
在阐述实现过程之前,我先解释一下。此游戏仍然用之前的MVC结构进行实现,所以很多代码重用了之前的游戏的代码,相当于这一整个框架是没有变,变得是一些具体的实现。同时我还增加了一个模块——DiskFactory,用以代替之前的Model模块,因为此次主要的游戏对象只有飞碟,用这个DiskFactory管理不同飞碟的生产与回收,减少了创建与销毁的次数。在这之前,先看一下UML图,可能会更为清晰:
可以看到游戏主要由这几个模块组成,分别为负责与用户交互的用户界面(UserGUI)、负责游戏对象的动作的运动管理师(ActionManager)、负责管理飞碟的生产与回收的飞碟厂(DiskFactory)以及统筹这几个模块的中心管理模块也是这个唯一场景的管理者——Controller模块。下面就来展示每个模块的核心代码。
- UserGUI
在这个模块中主要实现与用户的交互,首先需要在游戏的不同状态展示不同的UI组件,所以这里我利用到了action.action.GetGameState(),同时也要向中心控制模块传递某组件被点击的消息以实现与用户的交互。同时该游戏的玩法正是鼠标点击交互,所以当游戏进行中时,点击事件的发生触发Hit()。
//UserGUI.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UserGUI : MonoBehaviour
{
private IUserAction action;
readonly float roundTime = 40f;
GUIStyle style;
GUIStyle buttonStyle;
GUIStyle pauseStyle;
GUIStyle resultStyle;
void Start()
{
action = SSDirector.GetInstance().CurrentScenceController as IUserAction;
style = new GUIStyle();
style.fontSize = 20;
buttonStyle = new GUIStyle("button");
buttonStyle.fontSize = 30;
pauseStyle = new GUIStyle("button");
pauseStyle.alignment = TextAnchor.MiddleCenter;
pauseStyle.fontSize = 15;
resultStyle = new GUIStyle();
resultStyle.fontSize = 50;
resultStyle.alignment = TextAnchor.MiddleCenter;
resultStyle.normal.textColor = Color.white;
}
void OnGUI()
{
if (Input.GetButtonDown("Fire1") && action.GetGameState() == GameState.RUNNING)
{
Vector3 pos = Input.mousePosition;
action.Hit(pos);
}
if (action.GetGameState() != GameState.START)
{