DEV Community

Cover image for Creating a Platform Game with TCJSGame v3: Step-by-Step Tutorial
Kehinde Owolabi
Kehinde Owolabi

Posted on

Creating a Platform Game with TCJSGame v3: Step-by-Step Tutorial

Creating a Platform Game with TCJSGame v3: Step-by-Step Tutorial

In this tutorial, we'll create a simple platform game using TCJSGame v3, a lightweight JavaScript game engine. We'll cover everything from setting up the environment to adding player movement, platforms, and collision detection.

Prerequisites

  • Basic knowledge of HTML and JavaScript
  • A text editor (VS Code, Sublime Text, etc.)
  • A modern web browser

Step 1: Setting Up the HTML File

Create a new HTML file and include the TCJSGame v3 library:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Platform Game with TCJSGame v3</title>
    <style>
        body {
            margin: 0;
            padding: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            background: #2c3e50;
            font-family: Arial, sans-serif;
        }
        canvas {
            border: 3px solid #ecf0f1;
            border-radius: 5px;
            background: #34495e;
        }
    </style>
</head>
<body>
    <script src="http://tcjsgame.vercel.app/mat/tcjsgame-v3.js"></script>
    <script>
        // Our game code will go here
    </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Step 2: Initialize the Game Display

Inside the <script> tag, let's set up our game display:

// Create display instance
const display = new Display();

// Start the game with a 800x450 canvas
display.start(800, 450);

// Set background gradient
display.lgradient("bottom", "#3498db", "#2c3e50");
Enter fullscreen mode Exit fullscreen mode

Step 3: Create the Player Character

Now let's create our player character:

// Create player
const player = new Component(30, 50, "#e74c3c", 100, 100, "rect");

// Enable physics for the player
player.physics = true;
player.gravity = 0.5;
player.bounce = 0.2;

// Add player to the display
display.add(player);

// Set camera to follow player with smooth movement
display.camera.follow(player, true);
Enter fullscreen mode Exit fullscreen mode

Step 4: Create Platforms

Let's create some platforms for our player to jump on:

// Create platforms
const ground = new Component(800, 30, "#27ae60", 0, 420, "rect");
ground.physics = true;

const platform1 = new Component(200, 20, "#2980b9", 150, 350, "rect");
platform1.physics = true;

const platform2 = new Component(200, 20, "#2980b9", 450, 280, "rect");
platform2.physics = true;

const platform3 = new Component(200, 20, "#2980b9", 200, 200, "rect");
platform3.physics = true;

// Add platforms to display
display.add(ground);
display.add(platform1);
display.add(platform2);
display.add(platform3);
Enter fullscreen mode Exit fullscreen mode

Step 5: Implement Player Controls

Now let's add keyboard controls for our player:

// Player movement variables
const playerSpeed = 5;
const jumpStrength = 12;
let canJump = false;

// Update function for game logic
function update() {
    // Left and right movement
    if (display.keys[65] || display.keys[37]) { // A key or Left arrow
        player.speedX = -playerSpeed;
    } else if (display.keys[68] || display.keys[39]) { // D key or Right arrow
        player.speedX = playerSpeed;
    } else {
        player.speedX = 0;
    }

    // Jumping
    if ((display.keys[87] || display.keys[32] || display.keys[38]) && canJump) { // W, Space, or Up arrow
        player.gravitySpeed = -jumpStrength;
        canJump = false;
    }

    // Check if player is on a platform
    canJump = player.y >= display.canvas.height - player.height - 1 || 
              player.crashWith(ground) || 
              player.crashWith(platform1) || 
              player.crashWith(platform2) || 
              player.crashWith(platform3);

    // Keep player within screen bounds
    if (player.x < 0) player.x = 0;
    if (player.x > display.canvas.width - player.width) {
        player.x = display.canvas.width - player.width;
    }

    // Reset if player falls off the screen
    if (player.y > display.canvas.height) {
        player.x = 100;
        player.y = 100;
        player.speedX = 0;
        player.speedY = 0;
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 6: Add Collectible Items

Let's add some collectible coins to our game:

// Create coins
const coins = [];
const coinPositions = [
    [200, 320], [300, 320], [500, 250], [550, 250],
    [250, 170], [300, 170], [600, 370]
];

coinPositions.forEach((pos, index) => {
    const coin = new Component(15, 15, "#f1c40f", pos[0], pos[1], "rect");
    coin.index = index;
    display.add(coin);
    coins.push(coin);
});

let score = 0;
Enter fullscreen mode Exit fullscreen mode

Step 7: Add Score Display

Let's create a text component to display the score:

// Create score display
const scoreText = new Component("16px", "Arial", "#ecf0f1", 20, 30, "text");
scoreText.text = "Score: 0";
display.add(scoreText);
Enter fullscreen mode Exit fullscreen mode

Step 8: Enhance the Update Function

Now let's update our update function to handle coin collection and score:

// Enhanced update function
function update() {
    // ... (previous movement code)

    // Check for coin collection
    coins.forEach((coin, index) => {
        if (coin && player.crashWith(coin)) {
            // Remove the coin
            coin.hide();
            coins[index] = null;

            // Increase score
            score += 10;
            scoreText.text = `Score: ${score}`;
        }
    });

    // ... (previous bounds checking code)
}
Enter fullscreen mode Exit fullscreen mode

Step 9: Add Enemies

Let's add some moving enemies to make the game more challenging:

// Create enemies
const enemy1 = new Component(30, 30, "#e74c3c", 300, 390, "rect");
enemy1.physics = true;
enemy1.speedX = 2;

const enemy2 = new Component(30, 30, "#e74c3c", 600, 240, "rect");
enemy2.physics = true;
enemy2.speedX = -2;

display.add(enemy1);
display.add(enemy2);
Enter fullscreen mode Exit fullscreen mode

Step 10: Final Game Logic

Let's complete our game logic with enemy movement and game over conditions:

// Enhanced update function with enemy logic
function update() {
    // ... (previous movement and coin collection code)

    // Enemy movement and behavior
    if (enemy1.x <= 250 || enemy1.x >= 500) {
        enemy1.speedX *= -1;
    }

    if (enemy2.x <= 450 || enemy2.x >= 650) {
        enemy2.speedX *= -1;
    }

    // Check for collision with enemies
    if (player.crashWith(enemy1) || player.crashWith(enemy2)) {
        // Reset game
        player.x = 100;
        player.y = 100;
        player.speedX = 0;
        player.speedY = 0;

        // Reset enemies
        enemy1.x = 300;
        enemy2.x = 600;

        // Reset coins
        coins.forEach((coin, index) => {
            if (coin) {
                coin.show();
                coin.x = coinPositions[index][0];
                coin.y = coinPositions[index][1];
            } else {
                const newCoin = new Component(15, 15, "#f1c40f", 
                    coinPositions[index][0], coinPositions[index][1], "rect");
                display.add(newCoin);
                coins[index] = newCoin;
            }
        });

        // Reset score
        score = 0;
        scoreText.text = `Score: ${score}`;
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 11: Add Visual Enhancements

Let's add some visual improvements to make our game more appealing:

// Add decorative elements
const decoration = new Component(40, 40, "#8e44ad", 700, 100, "rect");
decoration.changeAngle = true;
display.add(decoration);

// Animate the decoration
setInterval(() => {
    decoration.angle += 0.1;
}, 100);
Enter fullscreen mode Exit fullscreen mode

Complete Game Code

Here's the complete code for our platform game:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Platform Game with TCJSGame v3</title>
    <style>
        body {
            margin: 0;
            padding: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            background: #2c3e50;
            font-family: Arial, sans-serif;
        }
        canvas {
            border: 3px solid #ecf0f1;
            border-radius: 5px;
            background: #34495e;
        }
    </style>
</head>
<body>
    <script src="http://tcjsgame.vercel.app/mat/tcjsgame-v3.js"></script>
    <script>
        // Create display instance
        const display = new Display();

        // Start the game with a 800x450 canvas
        display.start(800, 450);

        // Set background gradient
        display.lgradient("bottom", "#3498db", "#2c3e50");

        // Create player
        const player = new Component(30, 50, "#e74c3c", 100, 100, "rect");
        player.physics = true;
        player.gravity = 0.5;
        player.bounce = 0.2;
        display.add(player);

        // Set camera to follow player
        display.camera.follow(player, true);

        // Create platforms
        const ground = new Component(800, 30, "#27ae60", 0, 420, "rect");
        ground.physics = true;

        const platform1 = new Component(200, 20, "#2980b9", 150, 350, "rect");
        platform1.physics = true;

        const platform2 = new Component(200, 20, "#2980b9", 450, 280, "rect");
        platform2.physics = true;

        const platform3 = new Component(200, 20, "#2980b9", 200, 200, "rect");
        platform3.physics = true;

        display.add(ground);
        display.add(platform1);
        display.add(platform2);
        display.add(platform3);

        // Create coins
        const coins = [];
        const coinPositions = [
            [200, 320], [300, 320], [500, 250], [550, 250],
            [250, 170], [300, 170], [600, 370]
        ];

        coinPositions.forEach((pos, index) => {
            const coin = new Component(15, 15, "#f1c40f", pos[0], pos[1], "rect");
            coin.index = index;
            display.add(coin);
            coins.push(coin);
        });

        let score = 0;

        // Create score display
        const scoreText = new Component("16px", "Arial", "#ecf0f1", 20, 30, "text");
        scoreText.text = "Score: 0";
        display.add(scoreText);

        // Create enemies
        const enemy1 = new Component(30, 30, "#e74c3c", 300, 390, "rect");
        enemy1.physics = true;
        enemy1.speedX = 2;

        const enemy2 = new Component(30, 30, "#e74c3c", 600, 240, "rect");
        enemy2.physics = true;
        enemy2.speedX = -2;

        display.add(enemy1);
        display.add(enemy2);

        // Add decorative elements
        const decoration = new Component(40, 40, "#8e44ad", 700, 100, "rect");
        decoration.changeAngle = true;
        display.add(decoration);

        // Animate the decoration
        setInterval(() => {
            decoration.angle += 0.1;
        }, 100);

        // Player movement variables
        const playerSpeed = 5;
        const jumpStrength = 12;
        let canJump = false;

        // Update function for game logic
        function update() {
            // Left and right movement
            if (display.keys[65] || display.keys[37]) { // A key or Left arrow
                player.speedX = -playerSpeed;
            } else if (display.keys[68] || display.keys[39]) { // D key or Right arrow
                player.speedX = playerSpeed;
            } else {
                player.speedX = 0;
            }

            // Jumping
            if ((display.keys[87] || display.keys[32] || display.keys[38]) && canJump) {
                player.gravitySpeed = -jumpStrength;
                canJump = false;
            }

            // Check if player is on a platform
            canJump = player.y >= display.canvas.height - player.height - 1 || 
                      player.crashWith(ground) || 
                      player.crashWith(platform1) || 
                      player.crashWith(platform2) || 
                      player.crashWith(platform3);

            // Check for coin collection
            coins.forEach((coin, index) => {
                if (coin && player.crashWith(coin)) {
                    coin.hide();
                    coins[index] = null;
                    score += 10;
                    scoreText.text = `Score: ${score}`;
                }
            });

            // Enemy movement and behavior
            if (enemy1.x <= 250 || enemy1.x >= 500) {
                enemy1.speedX *= -1;
            }

            if (enemy2.x <= 450 || enemy2.x >= 650) {
                enemy2.speedX *= -1;
            }

            // Keep player within screen bounds
            if (player.x < 0) player.x = 0;
            if (player.x > display.canvas.width - player.width) {
                player.x = display.canvas.width - player.width;
            }

            // Check for collision with enemies
            if (player.crashWith(enemy1) || player.crashWith(enemy2)) {
                // Reset game
                player.x = 100;
                player.y = 100;
                player.speedX = 0;
                player.speedY = 0;

                enemy1.x = 300;
                enemy2.x = 600;

                coins.forEach((coin, index) => {
                    if (coin) {
                        coin.show();
                        coin.x = coinPositions[index][0];
                        coin.y = coinPositions[index][1];
                    } else {
                        const newCoin = new Component(15, 15, "#f1c40f", 
                            coinPositions[index][0], coinPositions[index][1], "rect");
                        display.add(newCoin);
                        coins[index] = newCoin;
                    }
                });

                score = 0;
                scoreText.text = `Score: ${score}`;
            }

            // Reset if player falls off the screen
            if (player.y > display.canvas.height) {
                player.x = 100;
                player.y = 100;
                player.speedX = 0;
                player.speedY = 0;
            }
        }
    </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Game Features

Our platform game includes:

  1. Player character with physics-based movement
  2. Multiple platforms to jump on
  3. Collectible coins that increase score
  4. Moving enemies that reset the game on contact
  5. Score display
  6. Camera that follows the player
  7. Visual decorations

Next Steps

To expand this game, you could:

  1. Add multiple levels with increasing difficulty
  2. Implement different enemy types with unique behaviors
  3. Add power-ups (e.g., double jump, speed boost)
  4. Create a tilemap for more complex level design
  5. Add sound effects and background music
  6. Implement a game menu and pause functionality

TCJSGame v3 provides a simple yet powerful framework for creating 2D games in JavaScript. With its component-based architecture and built-in physics, you can quickly prototype and build engaging browser-based games.

Top comments (0)