Communitygithub.com

BennyKok/omg.dev

在 omg.dev 的 Expo 项目中,利用 expo-game 模板构建实时游戏(赛车、街机、俯视角、平台跳跃、解谜、儿童学习、文字、简单 3D)。从游戏工具包开始,无需自行设计引擎。

omg.dev 是什么?

该技能指导开发者使用 `expo-game` 模板快速构建实时游戏,该模板已封装好固定时间步长循环、键盘/触控输入、碰撞检测、摄像机、HUD、菜单、暂停、结果、解锁和进度保存等功能。开发者只需根据用户需求,替换示例游戏(如 Coin Dash)中的内容,依次编辑 `theme.ts`、游戏逻辑文件(`logic.ts`)、游戏视图(`game-view.tsx`)、入口文件 `play.tsx` 以及相关 UI 页面。技能强调“首轮就写代码”,将每轮修改控制在单个文件或单一特性,并在修改后立即运行类型检查,避免长篇幅规划。支持 2D 和 3D 游戏(3D 需额外安装 three 及相关库,并处理平台差异),完成后需通过 `bun run typecheck`、`bun run build` 和 `bun run check:ui` 自动检查,并在 Expo Web 中手动验证键盘操控、游戏结束、结果展示和最高分保存。最后,技能提醒注意 Web 上的陷阱,如使用 `useViewSize()` 替代 `useWindowDimensions()`,进度保存在 `profileStore` 而非组件状态中,以及游戏时间应使用循环的 `dt` 而非 `setInterval` 或 `Date.now()`。所有工具和 API 都来自游戏工具包,开发者不得重复实现引擎功能。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/BennyKok/omg.dev/tree/HEAD/agents/skills/omg-game-builder

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

从工具包构建游戏

expo-game 模板已经包含了引擎:固定时间步长循环、键盘和触摸输入、摄像机、碰撞辅助、HUD、菜单、暂停、结果、解锁、进度保存以及一个可用的示例游戏(Coin Dash)。你的任务是替换示例内容,实现用户的游戏。请不要自行设计或编写引擎。

构建规则

  1. 在第一轮就编写代码。不要进行冗长的规划。用至多 10 行思路确定游戏规则,然后编辑文件。运行后修复问题。
  2. 保持每轮修改量小:只涉及一个文件或一个特性,然后运行 bun run typecheck。长时间推理而不写代码视为失败。
  3. 永远不要重新实现工具包已有的功能:循环、输入、碰撞、摄像机、HUD、屏幕、存储。
  4. 在添加菜单、美术或解锁之前,先让游戏实时可玩。示例已经包含了菜单。

项目

使用 omg_create_project 创建项目,template 参数设为 "expo-game"。在首次预览时,遵循 omg-app-builder 技能中的 Expo 快速路径。然后进行编辑。

需要编辑的文件(按顺序)

  1. src/game/theme.ts:根据设计设置颜色。
  2. src/games/<your-game>/logic.ts:复制 coin-dash/logic.ts。纯规则:createGame()、stepGame(game, input, dt)、finalScore()、UNLOCKS。不涉及 React、绘图或 Date.now()。仅通过 axisX/axisY/wasTapped(input, "p1" | "p2", ...) 读取输入。使用 seeded() 实现随机性。
  3. src/games/<your-game>/game-view.tsx:复制 coin-dash/game-view.tsx。使用 World 和 Sprite 进行绘制(彩色形状、emoji label 或 react-native-svg)。使用世界单位;摄像机负责转换。
  4. src/app/play.tsx:将导入从 coin-dash 改为你的游戏。在 TouchControls 上设置 kind(dpad、stick、steer)及其 buttons(例如 { action: "a", label: "JUMP" })。保持循环、键盘、暂停和完成连接不变。
  5. src/app/index.tsx、results.tsx、unlocks.tsx:修改标题、文本以及 UNLOCKS 的导入。 除非用户要求,否则不要编写自动化测试。改为通过自我检查进行验证(参见“完成”部分)。

除非工具包的错误阻塞了你,否则不要编辑 src/game/loop.ts、input.ts、collision.ts、camera.ts、progress.ts。在游戏文件夹中添加辅助函数。

工具包 API(使用这些名称)

  • createLoop({ step }) 和 useGameLoop(update, { paused }):更新以固定的 1/60 秒步长运行。
  • createInput()、axisX/axisY、wasTapped、endFrame、setAction、setStick。useKeyboard(input, players, onEscape):P1 使用 WASD + Space/E;双人模式中 P2 使用方向键 + Enter。
  • TouchControls players={1|2} kind="dpad|stick|steer" buttons={[...]}:双人模式将 P1 置于左侧,P2 置于右侧。对于分屏,渲染两个 GameView,每个使用独立的摄像机(参见 play.tsx)。
  • circlesOverlap、rectsOverlap、circleRectOverlap、pushCircleOutOfRect、keepCircleInside、angleDiff、seeded、clamp、lerp。
  • createCamera、followCamera(cam, target, dt, { velocity, lookAhead, world, viewW, viewH })。
  • profileStore.finishRun({ gameId, score, stats }, UNLOCKS)、useProfile()、profileStore.select(group, id)、setSettings。
  • 屏幕:MenuScreen、PauseOverlay、ResultsScreen、UnlocksScreen、SettingsRow、GameButton。HUD:Hud、HudStat、HudBar、Banner。

Web 陷阱

  • 使用 useViewSize()(基于 onLayout)测量游戏区域。在静态 Web 导出中,useWindowDimensions() 在发生 resize 之前始终为 0。
  • 在 Web 上,带有按钮的 Alert.alert 不生效。请使用 PauseOverlay 或屏幕内模态框。
  • 将进度保存在 profileStore 中,而不是组件状态:刷新后必须保留最高分和解锁状态。
  • 不要使用 setInterval 或 Date.now() 作为游戏时间。请使用循环的 dt 计数。
  • 不要将每帧状态放在 React 的 useState 中。将其保存在游戏对象(一个 ref)中;hook 会在每帧重新绘制。

3D 游戏

该工具包是 2D 的。对于 3D 游戏(确实是需求,而非风格选择),保留循环、输入、HUD 和屏幕,仅替换 game-view.tsx。

bunx expo install three @react-three/fiber expo-gl && bun add -d @types/three

编写两个小型文件,具有相同的导出,以便 Metro 选择正确的文件:

  • src/components/scene.web.tsx:import { Canvas, useFrame } from "@react-three/fiber"
  • src/components/scene.tsx:相同的代码,但使用 from "@react-three/fiber/native"

放置一个 <Canvas camera={{ position: [0, 0, 4] }}>,其中包含一个 ambientLight、一个 directionalLight 和每个游戏对象一个 <mesh>(盒子、球体、平面、纯色)。在每次渲染时从游戏对象复制位置;在 useGameLoop 中运行 stepGame,而不是在 useFrame 中。保持 HUD 和控件作为常规 React Native 视图位于画布之上。画布需要一个具有尺寸(flex: 1)的父容器。

在工具包 spike 中已验证:3D 场景可在 Expo Web 中渲染,Android JS 包可以编译。未验证:在设备或 Expo Go 上渲染。在最终消息中说明这一点。

完成

运行 bun run typecheck 和 bun run build。除非用户要求,否则不要编写自动化测试。然后运行 bun run check:ui:它将以 390x844 尺寸打开每个路由,在每个路由的 .omg/ui-check/ 目录下保存一张 PNG,并报告空白页面、错误边界、控制台错误、失败请求以及被其他元素遮挡的按钮。打开每张 PNG,与请求和任何设计参考资料进行比较,修复问题,然后重新运行直到报告干净。该检查不运行游戏,因此还需要在 Expo Web 中手动检查:必须能通过键盘移动、结束、显示结果屏幕,并在刷新后保持最高分。说明你测试了哪些表面;Web 运行不能证明原生行为。发布后,以手机尺寸打开实时 URL。omg 安装栏位于游戏下方,游戏成为其上方的卡片,因此该栏不会遮盖任何游戏控件。不要移动或隐藏它。

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

相关技能