当我做了一个网页版的地铁跑酷

背景

由于笔者最近在研究图形学Three.js相关的知识,也是想自己实现一个有趣且有一丢丢难度的demo,所以就决定做一个地铁跑酷的一个游戏,之前也搜过一些资料也没人做过类似地铁跑酷的游戏,所以可以简单的算是全网第一个地铁跑酷网页版游戏了

仓库地址:https://github.com/DanielLin0516/SUBWAY-SURFERS

游戏体验地址:https://subway-surfers-threejs.vercel.app/

玩法介绍

目前只有一些基本玩法,见下图:
在这里插入图片描述

代码结构介绍

主要核心代码还是在controlPlayer模块,大量的碰撞检测、游戏判定等都在这个里面,如果要看实现逻辑就看这个就好啦

未命名文件 (2).png

核心技术实现

无限地图

首先我们需要把我们的环境分组,好让我们能够一组一组的进行添加场景,我是这样进行划分的,下面的蓝框则为一整组场景:

image.png
我们可以发现在地铁跑酷过程当中,角色不倒下那么地图也是永无止境的,那么这个“永无止境”的地图是怎么实现的呢?
方案其实有两个:

  1. 让角色动,去动态添加地图
  2. 让角色原地跑动,动态添加障碍物

而在本项目实现方案是方案1,当我们人物在跑动的时候我们可以算出他跑动的距离
在角色没死的情况下,将每秒跑动的距离相加,就能获取到总跑动路程:

const moveZ = this.runVelocity * delta;
if (!this.frontCollide) {
   
    if (this.status !== playerStatus.DIE) {
   
        this.playerRunDistance += moveZ;
        this.model.position.z -= moveZ;
    }
}

在我们获取到角色跑动的路程和每个场景的地板长度,那么就可以很轻松获取到角色占当前板块的百分比 0-100%,在我们人物跑到当前板块的45%距离时候添加下一组板块,这样就形成了无线地图:

注意:添加完新的场景,记得把跑过的板块销毁,不然会随着人物跑动越远板块也无法销毁,内存增加造成掉帧卡死的情况,在本项目还没做这部分,后面会进行完善

// 检查玩家距离
checkPlayerDistance() {
   
    const ds = this.playerRunDistance;
    // 当前所在的地板块
    const nowPlane = Math.floor(ds / roadLength) + 1;

    // 当前走的路程站总长度的百分比
    // 当到达45%的时候动态添加场景  无限地图
    const runToLength = (ds - roadLength * (nowPlane - 1)) / roadLength;
    if (runToLength > 0.45 && this.currentPlane !== nowPlane) {
   
        console.log('添加下一个地板');
        this.currentPlane = nowPlane;
        this.environement.z -= roadLength;
        const newZ = this.environement.z;
        // 放置在z轴方向上
        this.environement.setGroupScene(newZ, -5 - nowPlane * roadLength, false);
    }
}

碰撞检测

在本项目里其实最复杂的就是碰撞检测,可能有很多种case,例如:左右碰撞火车回弹、正面大面积碰撞火车、小部分碰撞障碍物(不会终止游戏)等,也尝试过以下碰撞检测方案,最终还是选择了射线碰撞检测,以下说明原因以及实现细节

  1. 八叉树碰撞 ❌
  2. 射线碰撞 ✅
  3. 包围盒碰撞 ❌

方案三包围盒由于人物是骨骼动画会导致包围盒大小获取错误,只能自己给固定大小,也没太深入钻研包围盒碰撞检测的一些方法

项目刚开始选择的是八叉树碰撞,具体八叉树原理这里就不仔细讲解了,在使用的过程中发现Threejs提供给我们暴露出的八叉树碰撞api有点鸡肋,他只能将胶囊体赋值给人物角色,并将胶囊体碰撞检测结果给角色去做对应的操作,并且缺少我们需要的一些功能,当然我们也可以进行魔改八叉树的逻辑但这样往往时间成本以及上手成本会大大提升,例如:

  1. 碰到障碍物,获取障碍物信息
  2. 若八叉树场景有动态(例如火车),不用全局再构建八叉树,
  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值