摘要:游戏启动后不久,画面前方将出现怪物,游戏的目标是不停地看到怪物并持续前进
一、怪物出现的时间节点
我们首先来看如何来确定怪物出现的间隔。
- 若是怪物相继出现的时间间隔很短,玩家就必须快速地点击按键,这样游戏就比较难。
- 若是怪物出现的间隔较长,或者移动的速度比较慢,那么游戏就会比较简单
因此,我们首先考虑到怪物的运动速度和出现间隔=难易度,我们在每次成功攻击怪物后就增加游戏的难度(当然,要设置一个难度上限),并使食物后游戏会回到最初的状态。
每当武士前进了一段距离,怪物就将在其前方出现,正好位于画面之外即将进入画面的位置。如果这个距离过短,画面上会突然出现一个怪物。反之,则会导致在画面渲染区域之外存在许多怪物,增加不必要的开销。
在我们设计怪物出现模式的时候,需要算出武士从当前位置出发应当前进多远才让下一个怪物出现。如果玩家可以很顺利地斩杀怪物,就让这个距离越来越短,如果出现失误,则恢复到最初的长度。
这些时间间隔其实并不是一上来就得到的,都需要在玩的时候反复调整,最终得出合适的值。
二、怪物出现模式的变化
虽然速度极快会导致游戏变难,不过反复是玩几次后我们就会发现完全能够适应。这主要是因为目前怪物出现的间隔是固定值的缘故。(究其原因是节奏一直不变,只要找到节奏就可以了)
其实原本为了是玩家能够体会到斩杀的爽快感,是要求游戏具备一定的节奏的。不过如果一直一成不变的节奏,太简单了,这样的游戏就有些无聊了。
也就是说,问题不在速度,而在于节奏。那么我们就可以尝试,每隔一段时间,就是用特别的出现模式。本游戏制作了以下几种和破铜模式不一样的特别模式
- 连续:怪物短于正常时间的时间间隔涌上来
- 缓慢:怪物移动的速度比一般模式的最低速度还慢,而且出现的时间间隔很长。我们在持续玩难度较大的关卡时会感到匹拉怕,因此可以插入这个模式来提供休息调整的机会
- 赶超:后出现的怪物追赶并超越更早出现的怪物。后登场的怪物将会更早到达武士的位置,这会使玩家难于决定出手的时机,使其猝不及防。可以说这是比较难的一种模式
- 加速->减速:登场的怪物到达画面中央附近为之后加速,快要接近武士时减速,然后再朝着五十前进。游戏的情景就好像伴随着“危险!快跑!”“不!这样不行!”这样的台词。相比用于控制游戏的难易度,这种模式更适合用于营造游戏的演示效果
我们把这四种特别模式和普通模式混在一起来控制怪物的出现。每经过若干次普通模式后,就随机选择一把特殊模式。普通模式的持续次数也通过随机决定
下面给出流程图
开始特别模式时,以及从特别模式恢复到普通模式时,必须确保画面中的怪物已经完全消失。这样可以防止特别模式和普通模式的怪物同时出现。
比如在“加速->减速”模式中怪物出现的情况。当一个怪物在画面右边加速前进时又出现了别的怪物,有时就会造成两个怪物以非常短的时间间隔到达武士的位置。
为了避免这种情况,需要在使用特别模式前后等待一段时间,直到画面上怪物的“编队”完全消失。
下面展示具体代码(摘要)
public void oniAppearControl()
{
//检查是否准备好了新生成的怪物
if(this.can_dispatch) {
// 已准备好生成下一个分组
} else {
// 未准备好生成下一个分组
if(this.is_exclusive_group()) { //检测现在是普通模式还是特别模式
// 特别模式情况下,等待怪物从画面中消失
if(GameObject.FindGameObjectsWithTag("OniGroup").Length == 0) {
this.can_dispatch = true;
}
} else {
// 普通模式下,马上产生
this.can_dispatch = true;
}
if(this.can_dispatch) {
// 准备好出现后,通过玩家的当前位置计算应该出现的位置
if(this.group_type_next == GROUP_TYPE.NORMAL) {
this.oni_generate_line = this.player.transform.position.x + this.next_line;
} else if(this.group_type_next == GROUP_TYPE.SLOW) {
this.oni_generate_line = this.player.transform.position.x + 50.0f;
} else {
this.oni_generate_line = this.player.transform.position.x + 10.0f;
}
}
}
// 玩家前进了一定距离后,生成下一个分组
do {
if(this.scene_control.oni_group_num >= this.scene_control.oni_group_appear_max) {
break;
}
if(!this.can_dispatch) {
break;
}
if(this.player.transform.position.x <= this.oni_generate_line) {
break;
}
//
this.group_type = this.group_type_next;
switch(this.group_type) {
case GROUP_TYPE.SLOW:
{
this.dispatch_slow();
}
break;
case GROUP_TYPE.DECELERATE:
{
this.dispatch_decelerate();
}
break;
case GROUP_TYPE.PASSING:
{
this.dispatch_passing();
}
break;
case GROUP_TYPE.RAPID:
{
this.dispatch_rapid();
}
break;
case GROUP_TYPE.NORMAL:
{
this.dispatch_normal(this.next_speed);
}
break;
}
// 更新下次出现分组时的怪物数量
// (逐渐增加)
this.oni_appear_num++;
this.oni_appear_num = Mathf.Min(this.oni_appear_num, SceneControl.ONI_APPEAR_NUM_MAX);
this.can_dispatch = false;
this.no_miss_count++;
this.scene_control.oni_group_num++;
if(this.is_random) {
// 选择下次出现的分组
this.select_next_group_type();
}
} while(false);
}
- 首先,检查是否准备好了下一批怪物。
- 如果没做好生成怪物的准备,就检查现在和下一批怪物的出现模式使特别模式还是普通模式。如果现在或者下一批属于特别模式,那么this.is_exclusive_group()就会返回true,然后处于当前为普通模式或当前为特别模式并且画面中已经没有怪物了的时候,可以生成下一批怪物
- 以现在的武士所在位置为基准,计算出怪物的生成位置。怪物从登场开始到消失为止武士前进的距离随各模式不同而不同。因此,需要再准备好生成怪物的时候,就定好怪物将要出现的位置
- 武士的位置超过oni_generate_line后生成新的怪物
- 最后,提前选择下一次将生成的怪物类型。