feat(cheap-gen): 阶段一B #4 gamefeel 加 CoyoteTimer/ComboWindow 工厂方法(免 new+传 time)
附A #4:gamefeel 的 CoyoteTimer/ComboWindow 是 class、须 new 且要传受控 TimeSource——AI 拿不到 受控 time、做不出来。加工厂方法 gamefeel.createCoyoteTimer(opts)/createComboWindow(opts): 用 init 时捕获的受控时间源自动注入,AI 直接调、免 new + 免找 time。全链路同改: - gamefeel/impl.js:init 捕获 ctx.time,加两个工厂方法(new CoyoteTimer/ComboWindow(time,opts)) - gamefeel/api.d.ts:GamefeelPlugin 接口加两个工厂声明 - skill line115:列工厂方法(免 new + 自动注入受控 time);内置 inputBuffer 改 gamefeel.inputBuffer 验证:gamefeel 18/18 + 确定性(init 后工厂可调、返带 isAvailable/hit 的实例)。prompt 不提 gamefeel 故不同改。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b29a379f9c
commit
5cb73a6d82
@ -112,7 +112,7 @@ export function createGame({ plugins, bundle, viewport }) {
|
||||
|---|---|---|
|
||||
| **collision** | 碰撞查询(纯数学) | `circleVsCircle/circleVsAabb/aabbVsAabb/satVsPolygon`→`{hit,depth,nx,ny}`;`raycast*`;`SpatialHash`。**⚠️ Aabb=中心+半宽半高 `{x,y,hw,hh}`(非 {x,y,w,h});Circle `{x,y,r}`** |
|
||||
| **physics-lite** | 街机运动原语(非刚体) | `Projectile{step,reset}`/`integrateProjectile(state,dt,opts)`;`springStep`/`criticalDamping`;`moveWithConstraint`;`clampSpeed`/`applyFriction`。**⚠️ ProjectileState=`{px,py,vx,vy}`(位置是 px/py 非 x/y);重力经 opts.gravity={x,y}`** |
|
||||
| **gamefeel** | 手感 | `easing`(13 曲线 in/out/inOut);`InputBuffer{consume,peek}`;`CoyoteTimer{setGrounded,isAvailable,consume}`;`ComboWindow{hit,getCount}` |
|
||||
| **gamefeel** | 手感 | `easing`(13 曲线 in/out/inOut);内置 `gamefeel.inputBuffer{consume,peek}`;**工厂(免 new + 自动注入受控 time,#4)**:`gamefeel.createCoyoteTimer(opts)→{setGrounded,isAvailable,consume}`、`gamefeel.createComboWindow(opts)→{hit,getCount}` |
|
||||
| **particles-juice** | 粒子 + 打击感 | `spawnEmitter(preset\|cfg,x,y)`(或 `burst(x,y)` 直发 burst 预设,#6/#10 母语别名);`hitStop(dur)`/`getTimeScale`;`shakeScreen`/`getShakeOffset`;`flashScreen`/`pulseScale`;`PRESETS`(burst/trail/drift)。**⚠️ `render(g)` 必须每帧手调(非自动);`step(dt)` 默认 autoStep 自驱(经 onFrame),要手调 step 须工厂传 `autoStep:false` 防双步进** |
|
||||
| **palette-post** | 调色 + 后处理 | `rgbToHsl/hslToRgb/applyPaletteMap/shiftHsl`;`setPost/renderPost`(vignette/dither/scanline)。**色板由你注入,插件不内置成品色** |
|
||||
| **audio-music** | 程序化音频 | `loadSong/play/stop/loop`;`setIntensity`/`setIntensityLayering`;`playSfx('blip'\|'thud'\|'chime')` |
|
||||
|
||||
4
game-runtime/src/plugins/gamefeel/api.d.ts
vendored
4
game-runtime/src/plugins/gamefeel/api.d.ts
vendored
@ -244,6 +244,10 @@ export interface GamefeelPlugin extends Plugin {
|
||||
* 永久走内置(引擎门面刻意不暴此二者)。
|
||||
*/
|
||||
readonly easing: EasingLib;
|
||||
/** #4:用插件 init 时捕获的受控时间源造一个 CoyoteTimer(免自己 new + 找 time)。init 后可用。 */
|
||||
createCoyoteTimer(opts?: CoyoteTimerOptions): CoyoteTimer;
|
||||
/** #4:用受控时间源造一个 ComboWindow(免自己 new + 找 time)。init 后可用。 */
|
||||
createComboWindow(opts?: ComboWindowOptions): ComboWindow;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -456,6 +456,8 @@ export function createGamefeelPlugin(opts) {
|
||||
/** @type {EngineMath|null} */
|
||||
let engMath = null;
|
||||
let disposed = false;
|
||||
/** @type {TimeSource|null} init 时捕获的受控时间源,供 #4 工厂方法 createCoyoteTimer/createComboWindow 注入。 */
|
||||
let time = null;
|
||||
|
||||
/** @type {GamefeelPlugin} */
|
||||
const plugin = {
|
||||
@ -471,6 +473,22 @@ export function createGamefeelPlugin(opts) {
|
||||
get easing() {
|
||||
return makeEasingFacade(engMath);
|
||||
},
|
||||
/**
|
||||
* #4 阶段一B:用受控时间源造一个 CoyoteTimer(AI 直觉 gamefeel.createCoyoteTimer(opts),免自己 new + 找 time)。
|
||||
* @param {CoyoteTimerOptions} [opts]
|
||||
* @returns {CoyoteTimer}
|
||||
*/
|
||||
createCoyoteTimer(opts) {
|
||||
return new CoyoteTimer(time, opts);
|
||||
},
|
||||
/**
|
||||
* #4 阶段一B:用受控时间源造一个 ComboWindow(AI 直觉 gamefeel.createComboWindow(opts))。
|
||||
* @param {ComboWindowOptions} [opts]
|
||||
* @returns {ComboWindow}
|
||||
*/
|
||||
createComboWindow(opts) {
|
||||
return new ComboWindow(time, opts);
|
||||
},
|
||||
/**
|
||||
* 初始化:经受控面 getInput()+time 接一个内置 InputBuffer(演示受控面正确接线),
|
||||
* 并缓存引擎 math 门面句柄(供 easing getter 门面优先取引擎 Ease)。
|
||||
@ -479,6 +497,7 @@ export function createGamefeelPlugin(opts) {
|
||||
init(ctx) {
|
||||
// 经受控面拿输入订阅与时间源(禁直接 addEventListener / Date.now)。
|
||||
const input = ctx.getInput();
|
||||
time = ctx.time; // #4:缓存受控时间源,供 createCoyoteTimer/createComboWindow 工厂注入。
|
||||
inputBuffer = new InputBuffer(input, ctx.time, {
|
||||
windowMs: options.inputBufferMs,
|
||||
types: options.inputTypes,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user