尧图精选

SpacetimeDB 实战:Blackholio Phaser 浏览器客户端(client-ts)架构与运行指南

🕒 发布时间:2026/9/12 13:13:39 📁 来源:尧图网络
SpacetimeDB 实战Blackholio Phaser 浏览器客户端client-ts架构与运行指南【免费下载链接】SpacetimeDBDevelopment at the speed of light项目地址: https://gitcode.com/GitHub_Trending/sp/SpacetimeDB本指南围绕开源仓库demo/Blackholio/client-ts目录完整讲解 Blackholio 游戏浏览器端的工程结构、依赖配置、本地运行、绑定再生成、连接参数与操作方式。Blackholio 是一个基于 SpacetimeDB 的太空主题多人竞技MMORPG 风格示例游戏本客户端用 TypeScript 与 Phaser 编写对接仓库内已有的 Rust 服务端模块。读完本文你将掌握如何独立启动这个 Phaser 客户端、如何在仓库内以 SDK 源码链接方式构建、如何重新生成客户端表绑定以及客户端各控制器模块在 SpacetimeDB 实时同步模型中的分工。项目定位为 Blackholio Rust 模块服务的浏览器客户端Blackholio 是整个 SpacetimeDB 仓库中的演示游戏玩法受 agar.io 启发玩家吸收比自己小的实体、不断成长进化最终在排行榜上占据一席之地。其整体目录结构见 demo/Blackholio/README.md包含client-unity/、client-unreal/、client-ts/三种不同的客户端实现server-csharp/、server-rust/、server-ts/三种语言的服务端模块实现。本文的主角client-ts正是其中的浏览器客户端它通过 TypeScript SDKspacetimedbnpm 包连接 SpacetimeDB用 Phaser 完成 2D 场景渲染。该客户端不包含自己的服务端逻辑它对接的是仓库内已有的 Blackholio Rust 模块位于 demo/Blackholio/server-rust核心实现见src/lib.rs因此文章开头即明确其定位为 Browser client for the existing Blackholio Rust SpacetimeDB module。环境要求运行该客户端需要满足以下前提Node.js 18 或更高版本由package.json中engines.node字段18约束pnpm 10.16.0 或更高版本package.json声明packageManager: pnpm10.16.0engines.pnpm为10.16.0本机可用的 SpacetimeDB CLI / 服务器客户端需要连接一个正在运行的 SpacetimeDB 实例默认ws://localhost:3000并且该实例上应已发布 Blackholio 服务端模块。独立的 pnpm 工程与依赖解析策略client-ts是一个独立的 pnpm 工程不参与仓库根目录的 workspace 解析。它通过两个手段保证这一点本地pnpm-workspace.yaml拦截仓库 workspace文件内容如下packages: - . minimumReleaseAge: 1440packages只声明当前目录自身这样 pnpm 就不会选中仓库根目录或sdks/typescript等其他位置的 workspaceminimumReleaseAge: 1440则强制依赖发布至少 1440 分钟24 小时才可使用避免开发中误用刚发布、尚未沉淀的新版本。本地依赖配置直接链接仓库内的 TypeScript SDK 源码。package.json中dependencies: { phaser: 4.1.0, spacetimedb: link:../../../crates/bindings-typescript }其中spacetimedb依赖以link:协议指向仓库内 crates/bindings-typescript即 TypeScript SDK 源码目录也就是说开发期构建会直接使用当前仓库的 SDK 实现而非 npm 上已发布的包。这与仓库中sdks/typescript对 SDK 源码的维护方式一致保证 demo 与 SDK 代码始终同步。发布注意当把这个 demo 发布到 SpacetimeDB 仓库之外时必须将本地link:替换为 npm 上当前已发布版本的版本号例如spacetimedb: latest-published-versionREADME 特别解释了为什么不把已发布版本写成注释形式package.json不支持被注释的依赖替代项因此只能把发布形态写在文档里而不是在 manifest 中留下一行非法的注释条目。本地运行两步启动运行前先按服务端模块的正常开发流程启动 Rust 服务器参考 demo/Blackholio/server-rust 下的publish.sh/publish.bat等脚本然后在本目录执行pnpm install pnpm devpnpm install按pnpm-workspace.yaml与package.json安装依赖spacetimedb会解析到仓库内 SDK 链接pnpm dev启动 Vite 开发服务器。vite.config.ts中配置了开发端口export default defineConfig({ server: { port: 5173, }, });因此默认开发地址为http://localhost:5173。package.json还提供了其他常用脚本build先执行pnpm run typechecktsc --noEmit再做vite build产物构建lint等价于 typechecktest运行vitest run测试文件位于 demo/Blackholio/client-ts/tests/game.test.tsspacetime:generate即下面的绑定再生成命令。重新生成 TypeScript 表绑定客户端依赖服务端模块的 schema 生成 TypeScript 绑定reducer 与表类型。如果不改动服务器项目仅重新生成本客户端签入的绑定可执行spacetime generate --lang typescript --out-dir src/module_bindings --module-path ../server-rust参数说明--lang typescript指定生成 TypeScript 绑定--out-dir src/module_bindings输出目录为本客户端的src/module_bindings--module-path ../server-rust指向相对本目录的服务端模块项目Blackholio Rust 模块所在位置。生成结果落在 demo/Blackholio/client-ts/src/module_bindings其中index.ts导出DbConnection与ErrorContext等入口types/目录提供reducers.tsreducer 调用类型与types.tsCircle、Entity、Food、Player、ConsumeEntityEvent等数据类型根目录下则是circle_table.ts、food_table.ts、player_table.ts、enter_game_reducer.ts、player_split_reducer.ts、suicide_reducer.ts等按表与按 reducer 拆分的模块。源码结构与 Unity 示例一致的控制器边界客户端遵循与 Blackholio Unity 客户端相同的控制器分层思想。核心源码位于 demo/Blackholio/client-ts/src/game各模块职责如下文件职责GameManager.tsSpacetimeDB 连接管理、订阅、实体/玩家注册表entities与players两个 MapPlayerController.ts本地输入处理与玩家所拥有圆owned circles的状态维护EntityController.ts/CircleController.ts/FoodController.ts三类可渲染实体的控制器CameraController.ts质心跟随与缩放逻辑BlackholioScene.tsPhaser 场景入口与关卡搭建input.ts/math.ts指针方向换算、质量-半径/质心等数学工具ui/用户名选择、死亡界面、排行榜与浏览器 HUD入口 main.ts 创建Phaser.Game渲染模式Phaser.AUTO容器为game元素背景色#050817缩放模式Phaser.Scale.RESIZE场景为BlackholioScene。GameManager连接、订阅与注册表GameManager是客户端与 SpacetimeDB 交互的中枢GameManager.ts。其连接流程从localStorage读取历史 tokenkey 形如${HOST}/${DB_NAME}/auth_token通过DbConnection.builder()链式构造连接.withUri(HOST)指定 WebSocket 地址、.withDatabaseName(DB_NAME)指定数据库名注册onConnect/onDisconnect/onConnectError回调。onConnect中保存返回的 token 到localStorage、更新 HUD 状态并注册各表回调若存在历史 token 则调用.withToken(storedToken)做身份复用最后builder.build()建立连接。onConnect内还通过connection.subscriptionBuilder().onApplied(...).subscribeToAllTables()订阅所有表——Blackholio 采用全表订阅模式客户端本地维护完整的实体状态镜像。订阅应用完成后handleSubscriptionApplied读取config表中id 0的配置行取worldSize交给场景搭建竞技场边界用当前identity查询player表若无玩家或无用户名则弹出用户名选择界面若已有玩家但尚无对应 circle则调用enterGamereducer 重新入场。各表的回调registerCallbacks展示了 SpacetimeDB 客户端 SDK 的典型事件模型entity.onInsert→ 同步实体entity.onUpdate→ 通知对应控制器更新entity.onDelete→ 移除控制器若实体是被吸收动画的一部分则跳过直接销毁circle.onInsert/onDelete→ 创建/清理 CircleController 并维护 PlayerController 的 ownedCirclesfood.onInsert→ 创建 FoodControllerplayer.onInsert/onUpdate/onDelete→ 创建/更新/移除 PlayerControllerconsumeEntityEvent.onInsert→ 触发被吸收实体朝向吞噬者的despawnToward动画。首次订阅后syncSubscribedState会把player、circle、food三表的现存数据全部灌入场景实现断线重连/刷新后的状态重建。PlayerController20Hz 输入上报与三键操作PlayerController.ts 负责本地玩家的输入与状态。它以SEND_UPDATES_FREQUENCY_MS 1000 / 2050ms即 20Hz的频率把指针方向换算后通过 reducer 上报void this.gameManager.connection?.reducers.updatePlayerInput({ direction });方向由 input.ts 的pointerDirection计算以视口中心为原点、以视口高度的 1/3 为缩放基准把指针坐标映射到归一化方向向量。键盘操作Phaser.Input.Keyboard.JustDown检测按下沿对应三个 reducerSpaceplayerSplit分裂成为多圆玩家QlockKey锁定/解锁当前指针方向lockedPointer置位时方向不再跟随鼠标Ssuicide自杀释放所有圆。当本地玩家的所有圆都被吞噬onCircleDeleted后ownedCircles.length 0会触发DeathScreen显示玩家可通过respawnreducer 重生。totalMass()与centerOfMass()汇总所拥有圆的表数据供 HUD 与相机使用。CameraController 与 math质心跟随与动态缩放CameraController.ts 让主相机持续对准本地玩家的质量加权质心并依据总质量与圆数量动态缩放camera.centerOn(center.x, center.y)跟随目标视野尺寸由 math.ts 的cameraSize(totalMass, circleCount)计算基础 50加上min(50, totalMass / 5)的质量加成分裂为多圆时再加 30缩放以Phaser.Math.Linear做每帧插值Math.min(1, (delta / 1000) * 2)保证平滑玩家不存在时相机落在世界中心worldSize / 2。同一文件中的massToRadius(mass) Math.sqrt(mass)用于实体半径换算centerOfMass则实现按质量加权的质心公式质量为零时返回undefined。连接参数与环境变量覆盖客户端默认连接ws://localhost:3000、数据库blackholio。这两项在GameManager.ts中读取自 Vite 环境变量并带默认值const HOST import.meta.env.VITE_SPACETIMEDB_HOST ?? ws://localhost:3000; const DB_NAME import.meta.env.VITE_SPACETIMEDB_DB_NAME ?? blackholio;因此启动 Vite 时可通过环境变量覆盖例如连接远程或本地其他端口的服务器VITE_SPACETIMEDB_HOSTws://localhost:3000 \ VITE_SPACETIMEDB_DB_NAMEblackholio \ pnpm dev注意VITE_前缀是 Vite 向客户端代码暴露环境变量的约定只有以VITE_开头的变量才会被打进import.meta.env。操作方式总览连接成功后游戏操作与 README 记载的完全一致指针Pointer控制移动方向相对屏幕中心的方向向量20Hz 上报Space分裂把当前圆拆成多个圆以分散风险或加速移动Q锁定或解锁当前移动方向锁定时指针位置不再影响移动方向S自杀立即释放所有质量。从源码看客户端与服务端的对接契约把客户端回调与生成绑定对照可以清晰还原 Blackholio 的数据流契约依据 demo/Blackholio/client-ts/src/module_bindings表config含worldSize的全局配置、player玩家档案与身份、entity所有实体的位置/质量、circle玩家所拥有的圆、food食物、consumeEntityEvent吞噬事件流水reducerenterGame入场、updatePlayerInput上报方向、playerSplit分裂、suicide自杀、respawn重生。客户端把服务端表变化映射为 Phaser 场景对象的生命周期插入即创建、更新即同步位置/质量、删除即回收并触发特效如吞噬动画。这一全表订阅 事件驱动渲染的模式正是 SpacetimeDB 客户端 SDK 在实时游戏场景中的典型用法也是 Blackholio 展示的核心最佳实践。小结demo/Blackholio/client-ts是一份完整可运行、可二次开发的 SpacetimeDB Phaser 浏览器客户端示例。通过本文你可以按pnpm install pnpm dev两行命令启动它用spacetime generate重新生成与服务端同步的表绑定用VITE_SPACETIMEDB_HOST/VITE_SPACETIMEDB_DB_NAME切换连接目标并依据GameManager、PlayerController、CameraController等控制器边界快速理解甚至改造一个实时多人游戏的客户端结构。若需进一步了解服务端 reducer 与表的完整实现可继续阅读 demo/Blackholio/server-rust/src/lib.rs 及其配套math.rs。【免费下载链接】SpacetimeDBDevelopment at the speed of light项目地址: https://gitcode.com/GitHub_Trending/sp/SpacetimeDB创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →