JavaScript开发Flappy Bird时touchstart触摸跳跃失效如何解决
Flappy Bird触摸屏幕无法触发跳跃问题修复
核心错误点
Bird.js中选择小鸟DOM的选择器语法错误,缺少闭合方括号,无法获取到小鸟元素handleJump函数错误沿用键盘事件的判断逻辑:touchstart是触摸事件,事件对象不存在code属性,原有判断if (e.code !== "touchstart") return会直接拦截所有触摸操作,跳跃逻辑永远不会执行- 游戏失败时没有移除跳跃事件监听,会和重启游戏的监听产生事件冲突,导致重启逻辑异常
修复步骤
1. 修改Bird.js文件
- 修正DOM选择器语法
- 删除
handleJump中错误的e.code判断,添加阻止默认事件逻辑,避免移动端滚动、缩放干扰游戏操作 - 新增游戏结束时移除跳跃监听的方法,避免事件冲突
修复后完整代码:
// 修正选择器,补全闭合方括号 const birdElem = document.querySelector("[data-bird]"); const BIRD_SPEED = 0.5; const JUMP_DURATION = 120; let timeSinceLastJump = Number.POSITIVE_INFINITY; export function setupBird() { setTop(window.innerHeight / 2); document.removeEventListener("touchstart", handleJump); // 传入passive:false 允许调用preventDefault document.addEventListener("touchstart", handleJump, { passive: false }); } // 新增销毁方法,游戏结束时移除监听 export function teardownBird() { document.removeEventListener("touchstart", handleJump); } export function updateBird(delta) { if (timeSinceLastJump < JUMP_DURATION) { setTop(getTop() - BIRD_SPEED * delta); } else { setTop(getTop() + BIRD_SPEED * delta); } timeSinceLastJump += delta; } export function getBirdRect() { return birdElem.getBoundingClientRect(); } function setTop(top) { birdElem.style.setProperty("--bird-top", top); } function getTop() { return parseFloat(getComputedStyle(birdElem).getPropertyValue("--bird-top")); } function handleJump(e) { // 移除错误的e.code判断,阻止默认事件 e.preventDefault(); timeSinceLastJump = 0; }
2. 修改主文件f.js
- 导入新增的
teardownBird方法 - 游戏失败逻辑中先调用
teardownBird移除跳跃监听,避免和重启监听冲突
需要修改的部分:
首先修改导入语句:
import { updateBird, setupBird, getBirdRect, teardownBird } from "./Bird.js";
然后修改handleLose函数:
function handleLose() { // 先移除跳跃监听,避免事件冲突 teardownBird(); setTimeout(() => { title.classList.remove("hide"); subtitle.classList.remove("hide"); subtitle.textContent = `${getPassedPipesCount()} Pipes`; document.addEventListener("touchstart", handleStart, { once: true }); }, 100); }
扩展:同时支持键盘和触摸操作
如果需要同时兼容PC端键盘空格、移动端触摸操作,可以按如下方式修改Bird.js的事件绑定和判断逻辑:
export function setupBird() { setTop(window.innerHeight / 2); document.removeEventListener("touchstart", handleJump); document.removeEventListener("keydown", handleJump); document.addEventListener("touchstart", handleJump, { passive: false }); document.addEventListener("keydown", handleJump); } export function teardownBird() { document.removeEventListener("touchstart", handleJump); document.removeEventListener("keydown", handleJump); } function handleJump(e) { // 键盘事件仅响应空格键 if (e.type === "keydown" && e.code !== "Space") return; e.preventDefault(); timeSinceLastJump = 0; }
内容的提问来源于stack exchange,提问作者Oliver
相关产品推荐
相关产品推荐

