欢迎光临,登录后可以发帖和回帖。登录注册

小游戏开发规范

创建一个小游戏只需要一个 plugin.php 文件,放在 app/plugins/game_center_xxx/ 目录下,注册 game_center.register Hook 即可。

目录结构

app/plugins/game_center_dice/   # 插件目录 = 插件 ID
└── plugin.php                   # 所有代码都在此文件

命名规范

所有游戏中心子插件必须以 game_center_ 为统一前缀:

项目规则示例
目录名 / manifest idgame_center_ + 小写字母game_center_dice
游戏注册 ID与插件 ID 一致$games['game_center_dice']
PHP 函数前缀game_center_xxx_game_center_dice_register()
CSS 类/ID 前缀game-center-xxx-*.game-center-dice-board

注册合约

在 manifest 中声明 Hook,注册函数接收当前游戏列表并追加自己的游戏:

'hooks' => [
    'game_center.register' => 'game_center_dice_register',
],

function game_center_dice_register(array $games, array $ctx): array
{
    $games = is_array($games) ? $games : [];
    $games['game_center_dice'] = [
        'id'       => 'game_center_dice',   // 唯一 ID,与插件 ID 一致
        'name'     => '掷骰子',              // 显示名称
        'desc'     => '三颗骰子猜大小',       // 简短描述
        'cost'     => 10,                   // 每次消耗积分
        'max_win'  => 2000,                 // 最高赢取积分(展示用)
        'svg_icon' => 'game_center_dice_svg_icon',  // 返回 SVG 图标的函数名
        'render'   => 'game_center_dice_render',    // 返回游戏界面 HTML
        'play'     => 'game_center_dice_play',      // 处理游戏操作
    ];
    return $games;
}

注册字段说明

字段类型必填说明
idstring全局唯一,与插件 ID 一致
namestring游戏名称,显示在游戏大厅
descstring简短描述,显示在游戏卡上
costint每次消耗积分,必须 ≥ 1
max_winint最高可赢积分,展示用
svg_iconstring返回 SVG HTML 的函数名
renderstring返回游戏界面 HTML 的函数名
playstring处理游戏操作的函数名

render 回调

function game_center_dice_render(array $ctx): string

传入上下文 $ctx

字段说明
game该游戏的注册数据
balance当前用户积分
message上一次游戏的结果消息

返回游戏界面 HTML。游戏中心会将其包裹在统一容器中,不需要包含标题、返回按钮或积分余额。

必须包含:data-replace-target=".game-center-play" 的表单,用于 AJAX 提交替换。

play 回调

function game_center_dice_play(array $ctx): array

传入上下文 $ctx

字段说明
user_id当前用户 ID
cost本次消耗的积分
bet用户提交的押注数据
game该游戏的注册数据

返回值:

return [
    'payout'  => 0,           // 总派彩积分(0=没赢)
    'result'  => [...],       // 游戏结果数据(JSON,存入记录表)
    'html'    => '...',       // 更新后的游戏界面 HTML
    'message' => '...',       // 结果消息(toast 提示)
];

积分说明

游戏中心在调用 play() 之前已扣除 cost 积分:

  • payout = 0:玩家净损失 cost 积分
  • payout = cost × 2:玩家净赚 cost 积分(翻倍)
  • payout = cost × 200:玩家净赚 cost × 199 积分(大奖)

押注无效时用 err() 终止,游戏中心会回滚积分扣减。

表单与 AJAX

  • 表单 method="post",不设置 data-no-ajax
  • 设置 data-replace-target=".game-center-play"
  • 包含 form_token()name="game_id" 隐藏字段
  • play() 返回的 html 替换到 .game-center-play 容器
  • message 以 toast 提示显示

CSS 规范

  • 所有选择器以 game-center-xxx- 开头
  • 颜色使用系统变量(--brand--bg 等),禁止写死颜色值
  • 字号使用 --font-size-* 变量
  • 禁止使用 !important
  • 处理窄屏适配(@media(max-width:720px)

完整示例

参考 app/plugins/game_center_dice/plugin.php,或者老虎机、猜数字、幸运转盘、石头剪刀布的源码。

交付检查清单

  • ✅ 目录名和 manifest id 一致,以 game_center_ 开头
  • plugin.phpif (!defined('APP_ROOT')) exit; 开头
  • ✅ 所有 PHP 函数以 game_center_xxx_ 前缀
  • ✅ 所有 CSS 选择器以 game-center-xxx- 前缀
  • ✅ manifest 声明了 game_center.register Hook
  • ✅ 注册函数返回包含 id、name、desc、cost、svg_icon、render、play 的完整数组
  • render() 返回的表单含 data-replace-target=".game-center-play"
  • ✅ 表单包含 form_token()name="game_id"
  • play() 返回含 payout、result、html、message
  • ✅ 所有用户输入输出使用 h() 转义
  • ✅ 颜色使用系统 CSS 变量,无写死颜色,无 !important