#【开发分享】竖版动作跑酷——《峭壁逃亡》

大家好!本篇主要分享竖版跑酷动作类游戏——《峭壁逃亡》的开发,游戏模拟了悬崖攀登的过程,游戏的目标是尽可能攀到最高的高度,玩法如上面动画所示:
玩家角色会以一只手作为轴心旋转,当另一只手接近上方石头时,看准时机触屏,就可以使角色抓住新的石头,如果点击时游戏角色的手距离石头不够近,角色会掉下悬崖,游戏失败。
同时玩家不能在一个石头上停留太长时间,因为在下方还有水位追赶,如果水位淹到头的位置,同样视为游戏失败。
在项目实际开发时,经过分析归纳了以下两个主要的问题:
-
如何生成无尽关卡数据和处理画面表现层
-
角色抓取石头和表现细节方面的问题:
角色坠崖,落水,溺亡…等
一. 生成无尽关卡
既然是无尽关卡,和所有无尽跑酷游戏一样,关卡数据都是在游戏过程中分阶段生成的,换一种说法,就是
根据游戏角色当前所处的位置,预先生成下一可视范围的数据,防止玩着玩着关卡就断片了…
不过在说明关卡数据生成前,我们先确定一个更基础的问题:
在游戏角色攀爬过程中,到底是让角色运动?还是让关卡背景运动?
稍微思考一下,好像不管是哪种情况,都需要去处理拼接背景在视觉上铺满屏幕的问题。
这里我们采用了一种方法规避背景拼接问题:
1,将关卡分为背景和前景,背景只有一张图,始终不移动
2,前景节点上挂实时生成的石头及其它关卡装饰物,并且游戏角色也在前景节点下移动
3,滚屏时,只需要移动前景节点

定下这种节点结构后,滚屏的实现就很方便了,代码如下
//滚屏(在玩家抓取新的石头后调用)
let oldPos = Game.instance.stonesNode.parent.getPosition();
let newXPos = 330 - Game.instance.levelStones[i].xpos;
let newYPos = AppMain.instance.screenHalfHeight - Game.instance.levelStones[i].ypos;
let moveAction = cc.moveTo(0.3, cc.v2(newXPos, newYPos));
Game.instance.stonesNode.parent.runAction(moveAction);
接下来说明一下关卡生成的做法,为了让关卡的前景丰富一些,除了用于攀爬必要的石头,我们还准备了图腾,斑点,条纹,植物这几种装饰物,关卡算法的核心是:
做一个比可视范围稍大的矩形区域,回收已经超出矩形区下方的场景节点,同时从对象池中取空闲节点生成上方区域
这里我们结合了对象池使用,直接用的cc引擎提供的NodePool, 这样不管玩家攀到天荒地老,内存中的节点数量都是固定的




二. 角色
游戏角色为了制作不同状态的动画动作,采用DragonBones制作,图片素材也会省


两张角色图在压缩后仅15K

角色抓取石头判断:
角色两只手的Bone是在角色Local空间下,因此我们始终需要转换到World空间,再和目标石头做距离判断
//LHand的世界坐标
lHandWorldPos:
{
visible: false,
type: cc.Vec2,
get: function ()
{
let localPoint = cc.v2(this.lHandBone.global.x, -this.lHandBone.global.y);
return this.armature.display.convertToWorldSpace(localPoint);
}
},
//RHand 同理...
只要角色的HandBone和石头在同一坐标系下,那么抓取判断就好计算了,无非是两个cc.Vec2 的distance
let dis = lHandPos.sub(cc.v2(Game.instance.levelStones[i].xpos + Game.instance.stonesNode.parent.x, Game.instance.levelStones[i].ypos + Game.instance.stonesNode.parent.y)).mag();
if (dis <= holdDis)
{
//完美抓取判断
if (dis <= Game.instance.perfectHoldDis)
{
Game.instance.perfectHold();
}
else
//普通抓取
// 角色状态变化,动作切换,滚屏等其它处理...
}
else
{
//抓取失败,GameOver
}
水模拟:
水的模拟只需要两张不同波浪素材


场景中拼接如下,注意设置Sprite 的Pivot为底对齐,这样水位上涨只需要改变节点Height,
然后在Update中采用Position衔接方式模拟水体是无缝波动的

update(dt)
{
if (this.waveDir === -1)
{
this.node.x -= this.waveSpeed * dt;
if (this.node.x <= -AppMain.instance.designResolutionWidth)
this.node.x = 0;
}
else {
this.node.x += this.waveSpeed * dt;
if (this.node.x >= 0)
this.node.x = -AppMain.instance.designResolutionWidth;
}
if (AppMain.instance.gameStarted) {
for (let i = 0; i < this.node.childrenCount; i++) {
this.node.children[i].height += this.riseSpeed * dt;
}
let sceneNode = Game.instance.stonesNode.parent;
this.node.y = sceneNode.y;
}
},
作者简介:
肖尧,从事游戏 前端/后端/3D引擎开发多年
前盛大锦天主程,前成都网龙研发负责人,高级架构师
现任休闲游戏公司H5技术总监,未来将持续专注于基于H5的泛娱乐/教育/传媒/工具等产品的研究与开发。
微信/QQ : 1611471
