Search code examples
javascripthtmltouch-event

how to make javascript game touch friendly?


I created flappy bird by following a youtube tutorial. Inside Bird.js there is a function called handleJump, inside that function when i put "Space", the bird jumps whenever i press space key on keyboard, but when i change it to "touchstart" the bird doesn't jump when i touch the screen! what am i doing wrong? what should i do?

The main page ( f.js ):

import { updateBird, setupBird, getBirdRect } from "./Bird.js";
import {
  updatePipes,
  setupPipes,
  getPassedPipesCount,
  getPipesRects,
} from "./Pipe.js";

//document.addEventListener("keypress", handleStart, { once: true });
document.addEventListener("touchstart", handleStart, { once: true });
const title = document.querySelector("[data-title]");
const subtitle = document.querySelector("[data-subtitle]");

let lastTime;
function updateLoop(time) {
  if (lastTime == null) {
    lastTime = time;
    window.requestAnimationFrame(updateLoop);
    return;
  }
  const delta = time - lastTime;
  updateBird(delta);
  updatePipes(delta);
  if (checkLose()) return handleLose();
  lastTime = time;
  window.requestAnimationFrame(updateLoop);
}

function checkLose() {
  const birdRect = getBirdRect();
  const insidePipe = getPipesRects().some((rect) =>
    isCollision(birdRect, rect)
  );
  const outsideWorld = birdRect.top < 0 || birdRect.bottom > window.innerHeight;
  return outsideWorld || insidePipe;
}

function isCollision(rect1, rect2) {
  return (
    rect1.left < rect2.right &&
    rect1.top < rect2.bottom &&
    rect1.right > rect2.left &&
    rect1.bottom > rect2.top
  );
}

function handleStart() {
  title.classList.add("hide");
  setupBird();
  setupPipes();
  lastTime = null;
  window.requestAnimationFrame(updateLoop);
}

function handleLose() {
  setTimeout(() => {
    title.classList.remove("hide");
    subtitle.classList.remove("hide");
    subtitle.textContent = `${getPassedPipesCount()} Pipes`;
    document.addEventListener("touchstart", handleStart, { once: true });
  }, 100);
}

Bird.js :

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); //keydown
  document.addEventListener("touchstart", handleJump); //keydown
}

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) {
  if (e.code !== "touchstart") return;

  timeSinceLastJump = 0;
}


Solution

  • I fixed it by removing the return

    Before:

    function handleJump(e) {
      if (e.code !== "touchstart") return;
    
      timeSinceLastJump = 0;
    }
    

    After:

    function handleJump(e) {
      if (e.code !== "touchstart");
    
      timeSinceLastJump = 0;
    }