You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kaboom.js:如何实现按键触发单次碰撞检测而非持续检测

解决Kaboom.js按键瞬间单次碰撞检测问题

原代码的问题在于:每次按下d键时,都会注册一个新的onCollide持续碰撞监听,这个监听会一直生效,导致后续只要Player和Note发生碰撞就触发shake(),而非仅在按键瞬间检测一次。

修改方案

在按键按下的瞬间主动执行一次碰撞检测,而非注册持续监听。可以使用Kaboom提供的碰撞检测API实现:

import kaboom from "kaboom";

kaboom();

loadSprite("bean", "sprites/bean.png");

const player = add([
    sprite("bean"),
    pos(80, height() / 2),
    area(),
    "Player",
]);

function spawnRect() {
    add([
        rect(50, 50),
        pos(width(), height() / 2),
        outline(4),
        area(),
        solid(),
        color(127, 200, 255),
        move(LEFT, 500),
        cleanup(),
        "Rect",
    ])
    wait(rand(0.25, 1.5), () => {
        spawnNote();
    });
}

// 补充spawnNote函数(原代码缺失,这里假设生成Note实体的逻辑)
function spawnNote() {
    add([
        rect(30, 30),
        pos(width(), height() / 2),
        area(),
        color(255, 127, 127),
        move(LEFT, 500),
        cleanup(),
        "Note",
    ]);
    wait(rand(0.25, 1.5), () => {
        spawnNote();
    });
}

spawnNote();

onKeyPress("d", () => {
    // 方案1:检测玩家是否与任意Note碰撞
    if (player.isColliding("Note")) {
        shake();
        // 可选:碰撞后销毁对应Note,避免重复触发
        getFirst("Note")?.destroy();
    }

    // 方案2:遍历所有Note,检测每个Note与玩家的碰撞(适合多Note场景)
    // const notes = get("Note");
    // for (const note of notes) {
    //     if (player.collides(note)) {
    //         shake();
    //         note.destroy();
    //         break; // 只处理第一个碰撞的Note,按需移除该逻辑
    //     }
    // }
});

关键修改说明

  • 移除了onKeyPress内的onCollide注册逻辑,避免生成持续生效的碰撞监听
  • 改用player.isColliding("Note")或player.collides(note),在按键瞬间仅执行一次碰撞检测
  • 可选添加destroy()方法处理碰撞后的Note实体,防止重复触发逻辑

内容的提问来源于stack exchange,提问作者ColoredHue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 11:35:25