Watermelon Game

Watermelon Game made with html, css, js

Some product links are affiliate links which means if you something we'll receive a small commission.

Youtube Link

html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Watermelon Game</title>
    <style>
      body {
        text-align: center;
      }
    </style>
  </head>
  <body>
    <h1>Watermelon Game</h1>
    <script type="module" src="./index.js"></script>
  </body>
</html>

js

import { Bodies, Body, Engine, Events, Render, Runner, World } from "matter-js";

const FRUITS = [
  {
    name: "base/00_cherry",
    radius: 33 / 2,
  },
  {
    name: "base/01_strawberry",
    radius: 48 / 2,
  },
  {
    name: "base/02_grape",
    radius: 61 / 2,
  },
  {
    name: "base/03_gyool",
    radius: 69 / 2,
  },
  {
    name: "base/04_orange",
    radius: 89 / 2,
  },
  {
    name: "base/05_apple",
    radius: 114 / 2,
  },
  {
    name: "base/06_pear",
    radius: 129 / 2,
  },
  {
    name: "base/07_peach",
    radius: 156 / 2,
  },
  {
    name: "base/08_pineapple",
    radius: 177 / 2,
  },
  {
    name: "base/09_melon",
    radius: 220 / 2,
  },
  {
    name: "base/10_watermelon",
    radius: 259 / 2,
  },
];

const engine = Engine.create();
const render = Render.create({
  engine,
  element: document.body,
  options: {
    wireframes: false,
    background: "#F7F4C8",
    width: 620,
    height: 850,
  },
});

const world = engine.world;

const leftWall = Bodies.rectangle(15, 395, 30, 790, {
  isStatic: true,
  render: { fillStyle: "#E6B143" },
});

const rightWall = Bodies.rectangle(605, 395, 30, 790, {
  isStatic: true,
  render: { fillStyle: "#E6B143" },
});

const ground = Bodies.rectangle(310, 820, 620, 60, {
  isStatic: true,
  render: { fillStyle: "#E6B143" },
});

const topLine = Bodies.rectangle(310, 150, 620, 2, {
  name: "topLine",
  isStatic: true,
  isSensor: true,
  render: { fillStyle: "#E6B143" },
});

World.add(world, [leftWall, rightWall, ground, topLine]);

Render.run(render);
Runner.run(engine);

let currentBody = null;
let currentFruit = null;
let disableAction = false;
let interval = null;

function addFruit() {
  const index = Math.floor(Math.random() * 5);
  const fruit = FRUITS[index];

  const body = Bodies.circle(300, 50, fruit.radius, {
    index: index,
    isSleeping: true,
    render: {
      sprite: {
        texture: `${fruit.name}.png`,
      },
    },
    restitution: 0.2,
  });

  currentBody = body;
  currentFruit = fruit;

  World.add(world, body);
}

window.onkeydown = (event) => {
  if (disableAction) {
    return;
  }

  switch (event.code) {
    case "KeyJ":
      if (interval) return;

      interval = setInterval(() => {
        if (currentBody.position.x - currentFruit.radius > 30)
          Body.setPosition(currentBody, {
            x: currentBody.position.x - 1,
            y: currentBody.position.y,
          });
      }, 5);
      break;

    case "KeyL":
      if (interval) return;

      interval = setInterval(() => {
        if (currentBody.position.x + currentFruit.radius < 590)
          Body.setPosition(currentBody, {
            x: currentBody.position.x + 1,
            y: currentBody.position.y,
          });
      }, 5);
      break;

    case "KeyK":
      currentBody.isSleeping = false;
      disableAction = true;
      setTimeout(() => {
        addFruit();
        disableAction = false;
      }, 1000);
      break;
  }
};

window.onkeyup = (event) => {
  switch (event.code) {
    case "KeyJ":
    case "KeyL":
      clearInterval(interval);
      interval = null;
  }
};

Events.on(engine, "collisionStart", (event) => {
  event.pairs.forEach((collision) => {
    if (collision.bodyA.index === collision.bodyB.index) {
      const index = collision.bodyA.index;

      if (index === FRUITS.length - 1) {
        return;
      }

      World.remove(world, [collision.bodyA, collision.bodyB]);

      const newFruit = FRUITS[index + 1];

      const newBody = Bodies.circle(collision.collision.supports[0].x, collision.collision.supports[0].y, newFruit.radius, {
        render: {
          sprite: {
            texture: `${newFruit.name}.png`,
          },
        },
        index: index + 1,
      });

      World.add(world, newBody);
    }

    if (!disableAction && (collision.bodyA.name === "topLine" || collision.bodyB.name === "topLine")) {
      alert("Game over");
    }
  });
});

addFruit();