如何用p5.js检测按键长按时长实现游戏内长按拾取道具功能
p5.js 长按空格键拾取道具实现方案
实现思路
采用时间戳差值计算拾取进度,相比计数器方案不受帧率波动影响,精度更高,且完全不侵入原有功能逻辑:
- 新增全局变量独立维护拾取状态,原有移动逻辑仅需新增
canMove状态判断即可,无需修改核心实现 - 三个键盘事件分工明确:
keyPressed()校验拾取前置条件(角色处于道具上方),触发拾取初始化keyReleased()处理中途松手的拾取中断逻辑,自动回滚状态draw()中结合keyIsDown()校验长按状态,实时计算拾取进度并渲染进度条
完整实现代码
// 拾取配置常量 const PICK_DURATION = 5000; // 拾取总时长5秒 // 全局拾取状态变量 let isPicking = false; let pickStartTime = 0; let pickUpRate = 0; let canMove = true; function setup() { createCanvas(400, 400); } function draw() { background(220); // 拾取进度计算逻辑 if (isPicking && keyIsDown(32)) { // 32为空格键keyCode const elapsedTime = millis() - pickStartTime; pickUpRate = min(elapsedTime / PICK_DURATION * 100, 100); // 拾取完成逻辑 if (pickUpRate >= 100) { isPicking = false; canMove = true; pickUpRate = 0; // 此处新增你自己的拾取成功业务逻辑:道具消失、角色加属性等 console.log('道具拾取成功'); } } // 原有进度条渲染逻辑,仅替换了PickUpRate变量来源 push() let x = 100 let y = 100 let size = 64 fill(100,63) // 进度条底座 rect(x-size/2, y-size/2-20,size,10); // 进度填充 fill(0,220,0) rect(x-size/2, y-size/2-20,size*abs(pickUpRate)/100,10); pop() } function keyPressed(event){ // 仅响应空格键事件 if (event.keyCode === 32) { // 请将此处isOnItem替换为你自己的碰撞检测逻辑:判断角色是否处于道具上方 const isOnItem = true; if (isOnItem && !isPicking && canMove) { // 初始化拾取状态 isPicking = true; pickStartTime = millis(); canMove = false; pickUpRate = 0; } } } function keyReleased(event){ // 空格键松开且未完成拾取时,中断拾取 if (event.keyCode === 32 && isPicking && pickUpRate < 100) { isPicking = false; canMove = true; pickUpRate = 0; console.log('拾取中断'); } }
关键说明
- 前置条件替换:代码中
isOnItem为示例占位,你只需要替换成自己现有项目中角色和道具的碰撞检测逻辑即可 - 状态兼容:如果需要实现角色离开道具范围自动中断拾取,只需要在draw的拾取逻辑中额外加上碰撞检测的判断即可
- 无侵入改造:原有的角色移动代码,只需要在移动触发的逻辑前加
if (canMove)判断,就可以实现拾取时禁止移动的效果,不需要修改原有移动的核心代码
内容的提问来源于stack exchange,提问作者Steveit
相关产品推荐
相关产品推荐

