JSFiddle - React, Tailwind, and code Playground

by dledle2

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Jelly Car Clone</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <h1>Jelly Car Clone</h1>
        <div id="game-container">
            <!-- Canvas will be inserted here by Matter.js -->
        </div>
        <div class="controls-info">
            <p>Controls: Left Arrow (Backward) | Right Arrow (Forward)</p>
            <button id="resetButton">Reset Game</button>
        </div>
    </div>

    <!-- Matter.js ES Module -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.min.js"></script>
    <script type="module" src="script.js"></script>
</body>
</html>

CSS

body {
    font-family: 'Arial', sans-serif;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    margin: 0;
    background-color: #f0f0f0;
    color: #333;
    overflow: hidden; /* Prevent scrollbars from canvas extending */
}

.container {
    text-align: center;
    background-color: #fff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}

#game-container {
    width: 800px;
    height: 600px;
    border: 1px solid #ccc;
    position: relative; /* For Matter.js renderer to attach canvas */
    margin: 20px auto;
    overflow: hidden; /* Clip anything drawn outside */
}

canvas {
    display: block; /* Remove extra space below canvas */
    background-color: #e0f7fa; /* Light blue sky */
}

.controls-info {
    margin-top: 15px;
    font-size: 0.9em;
}

button {
    padding: 10px 15px;
    font-size: 1em;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: background-color 0.3s ease;
}

button:hover {
    background-color: #45a049;
}

JavaScript

// Ensure Matter.js is loaded globally
const { Engine, Render, Runner, Bodies, Body, Composite, Composites, Constraint, Events, Vector } = Matter;

let engine;
let render; // This is our main render object
let runner;
let world;

let car;
let wheels = [];
let groundSegments = [];

const gameContainer = document.getElementById('game-container');
const canvasWidth = 800;
const canvasHeight = 600;

const wallThickness = 50; 
let totalTerrainWidth = 0;

const keys = {
    ArrowLeft: false,
    ArrowRight: false,
};

const carWidth = 80;
const carHeight = 40;
const wheelRadius = 20;

const segmentWidthMin = 150;
const segmentWidthMax = 300;
const segmentHeightVariation = 80;
const numSegments = 100; // Keep the long map
const startFlatSegments = 3;


function setup() {
    console.log("Setup: Start");
    if (typeof Matter === 'undefined' || !Engine) {
        alert("Matter.js is not loaded correctly! Check the script tag in HTML or network tab.");
        console.error("Matter.js is not loaded correctly!");
        return;
    }

    engine = Engine.create();
    world = engine.world;
    engine.gravity.y = 1;

    render = Render.create({ // Assign to the global 'render'
        element: gameContainer,
        engine: engine,
        options: {
            width: canvasWidth,
            height: canvasHeight,
            wireframes: false,
            background: '#e0f7fa',
            // No hasBounds: true, so we should have full control over render.bounds
        }
    });
    console.log("Setup: Render object created. Initial render.bounds:", JSON.parse(JSON.stringify(render.bounds)));
    Render.run(render); // Starts the rendering loop for this 'render' object
    console.log("Setup: Render.run(render) called.");

    runner = Runner.create();
    Runner.run(runner, engine); // Starts the physics engine loop
    console.log("Setup: Runner.run(runner, engine) called.");

    // Initial game state setup
    resetGameInternals(true); // Call a helper to setup...