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>
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");
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);
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);
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;
}
}
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;
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);
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)
}
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);
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}`;
}
}
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);
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>
Game Features
Our platform game includes:
- Player character with physics-based movement
- Multiple platforms to jump on
- Collectible coins that increase score
- Moving enemies that reset the game on contact
- Score display
- Camera that follows the player
- Visual decorations
Next Steps
To expand this game, you could:
- Add multiple levels with increasing difficulty
- Implement different enemy types with unique behaviors
- Add power-ups (e.g., double jump, speed boost)
- Create a tilemap for more complex level design
- Add sound effects and background music
- 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)