This is a fun and engaging star collection game built with Kaplay. The player controls a character using left and right keys to catch falling stars while avoiding letting too many fall to the ground. Every time a star is collected, the score increases, and the timer keeps running to challenge players to beat their own time and score. With gravity and player movement physics in place, this game offers a good mix of action and timing. The game ends when too many stars are missed, and players are rewarded with a final score based on how many stars they caught. Plus, there’s a fun audio element with a collect sound when stars are gathered and a game over sound at the end.
Following step-by-step procedure helps you to build the game.
1: Set Up Your Game Environment
Before you start coding, ensure that you have Kaplay installed and your development environment is ready. The game uses assets like images, sounds, and the Kaplay library itself.
1.1 Import Kaplay: The first step is importing the Kaplay library.
import kaplay from "kaplay";
1.2 Initialize the Kaplay Game Engine: You create an instance of the Kaplay game engine (k) where you define the game configuration like background color and button mappings.
const k = kaplay({ background: [250, 250, 250], // Light blue background (sky-like) buttons: { left: { keyboard: ["left"], gamepad: ["west"] }, right: { keyboard: ["right"], gamepad: ["east"] }, }, });
2. Define Game Constants and Variables
To control the game’s difficulty and behavior, define a few constants and variables:
2.1 Player Speed and Gravity: The speed at which the player moves and the gravity that affects falling stars.
const PLAYER_SPEED = 2000; const GRAVITY = 500; let score = 0; let missedStars = 0; const MAX_MISSED_STARS = 10; let secondsElapsed = 0;
2.2 Set Gravity: The game world’s gravity pulls objects down, simulating a natural environment.
k.setGravity(GRAVITY);
3. Load Game Assets
Next, we load the necessary game assets like sprites for the player and stars, and sounds for collecting stars and game over.
k.loadSprite("bean", "sprites/bean.png"); k.loadSprite("star", "sprites/star.svg"); k.loadSound("collect", "sounds/collect.mp3"); k.loadSound("gameOver", "sounds/game_over.mp3");
4. Create UI Elements
For a better gaming experience, display the score, missed stars, and timer on the screen.
const scoreLabel = k.add([k.text(`Score: ${score}`, 10), k.pos(20, 20), k.fixed(), k.color(0, 0, 0)]); const missedLabel = k.add([k.text(`Missed: ${missedStars}/${MAX_MISSED_STARS}`, 20), k.pos(20, 50), k.fixed(), k.color(0, 0, 0)]); const timerLabel = k.add([k.text(`Time: 0s`, 24), k.pos(k.width() - 400, 20), k.fixed(), k.color(0, 0, 0)]);
5. Create the Player Character
You need a player character that can move and interact with stars.
5.1 Add Player: The player is a "bean" sprite that can move left and right, and jump to avoid missing stars.
const player = k.add([k.sprite("bean"), k.pos(k.width() / 2, k.height() - 100), k.body(), k.area()]);
5.2 Player Movement: Define how the player moves with the left and right arrow keys.
k.onKeyDown("left", () => { if (player.pos.x > 0) { player.move(-PLAYER_SPEED, 0); } }); k.onKeyDown("right", () => { if (player.pos.x < k.width() - player.width) { player.move(PLAYER_SPEED, 0); } });
6. Score and Missed Stars Logic
The core of the gameplay revolves around collecting stars and avoiding missed ones.
6.1 Update Score: Each time the player collects a star, the score increases and a sound plays.
const updateScore = () => { score += 1; scoreLabel.text = `Score: ${score}`; k.play("collect", { volume: 1 }); // Play collect sound };
6.2 Update Missed Stars: If a star falls off the screen, the player
misses it, and the game updates the missed stars count. If the player misses
too many stars, the game ends.
const updateMissedStars = () => { missedStars += 1; missedLabel.text = `Missed: ${missedStars}/${MAX_MISSED_STARS}`; if (missedStars >= MAX_MISSED_STARS) { endGame(); } };
7. Star Spawning
Stars fall from the top of the screen, and the player must catch them.
7.1 Spawn Stars: A function that spawns stars randomly across the screen. Stars have random colors and a fall animation.
const spawnStar = () => { const x = k.rand(20, k.width() - 20); // Random x position const star = k.add([k.sprite("star"), k.pos(x, -20), k.area(), k.body(), k.scale(3), k.color(...getRandomColor()), "star"]); star.onCollide("ground", () => { updateMissedStars(); k.destroy(star); }); };
Loop to Spawn Stars: Every 1.5 seconds, a new star is created and falls.
let starSpawnner = k.loop(1.5, spawnStar);
8. Game Over Condition
The game ends when the player misses too many stars.
8.1 End Game: If the player misses enough stars, the game stops, and a "Game Over" message appears.
const endGame = () => { gameEnded = true; starSpawnner.cancel(); k.play("gameOver", { volume: 1 }); // Play game over sound k.add([k.text("Game Over", 48), k.pos(k.width() / 2 - 150, k.height() / 2), k.color(255, 0, 0)]); };
9. Timer Function
A timer keeps track of how long the player has been playing.
9.1 Update Timer: The timer updates every second and is displayed on the screen.
const updateTimer = () => { if (!gameEnded) { secondsElapsed += 1; timerLabel.text = `Time: ${secondsElapsed}s`; } else { timerController.cancel(); } };
Loop to Update Timer: This loop updates the timer at regular intervals.
let timerController = k.loop(1, updateTimer);
Project Setup and make the Application run in your system.
Step 1: Create a KAPLAY project star-collection by executing below command.
npx create-kaplay star-collection
Upon successful execution of above command, you can see a project structure looks like below.
Step 2: Update src/main.js with below content.
main.js
import kaplay from "kaplay"; function getInt(min, max) { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min + 1)) + min; } function getRandomColor() { return [getInt(0, 255), getInt(0, 255), getInt(0, 255)]; } // Initialize Kaplay const k = kaplay({ background: [250, 250, 250], // Light blue background (sky-like), buttons: { left: { keyboard: ["left"], gamepad: ["west"] }, right: { keyboard: ["right"], gamepad: ["east"] }, }, }); // Game Configuration const PLAYER_SPEED = 2000; const GRAVITY = 500; let score = 0; let missedStars = 0; const MAX_MISSED_STARS = 10; let secondsElapsed = 0; // Timer variable // Set gravity for the game world k.setGravity(GRAVITY); // Load assets k.loadRoot("./"); k.loadSprite("bean", "sprites/bean.png"); k.loadSprite("star", "sprites/star.svg"); k.loadSound("collect", "sounds/collect.mp3"); k.loadSound("gameOver", "sounds/game_over.mp3"); // Display the score, missed stars, and timer const scoreLabel = k.add([ k.text(`Score: ${score}`, 10), k.pos(20, 20), k.fixed(), k.color(0, 0, 0), ]); const missedLabel = k.add([ k.text(`Missed: ${missedStars}/${MAX_MISSED_STARS}`, 20), k.pos(20, 50), k.fixed(), k.color(0, 0, 0), ]); const timerLabel = k.add([ k.text(`Time: 0s`, 24), k.pos(k.width() - 400, 20), k.fixed(), k.color(0, 0, 0), ]); // Create the player const player = k.add([ k.sprite("bean"), k.pos(k.width() / 2, k.height() - 100), k.body(), k.area(), ]); // Function to update the score const updateScore = () => { score += 1; scoreLabel.text = `Score: ${score}`; k.play("collect", { volume: 1 }); // Play collect sound }; // Function to update missed stars count const updateMissedStars = () => { missedStars += 1; missedLabel.text = `Missed: ${missedStars}/${MAX_MISSED_STARS}`; // End the game if missed stars exceed the limit if (missedStars >= MAX_MISSED_STARS) { endGame(); } }; let gameEnded = false; // Function to end the game const endGame = () => { gameEnded = true; starSpawnner.cancel(); k.play("gameOver", { volume: 1 }); // Play game over sound k.add([ k.text("Game Over", 48), k.pos(k.width() / 2 - 150, k.height() / 2), k.color(255, 0, 0), ]); }; // Function to spawn stars const spawnStar = () => { const x = k.rand(20, k.width() - 20); // Random x position const star = k.add([ k.sprite("star"), k.pos(x, -20), // Spawn above the screen k.area(), k.body(), k.scale(3), k.color(...getRandomColor()), "star", ]); // Remove star if it collides with the ground star.onCollide("ground", () => { updateMissedStars(); k.destroy(star); }); }; // Spawn stars every 1.5 seconds let starSpawnner = k.loop(1, spawnStar); // Handle player movement k.onKeyDown("left", () => { if (player.pos.x > 0) { player.move(-PLAYER_SPEED, 0); } }); k.onKeyDown("right", () => { if (player.pos.x < k.width() - player.width) { player.move(PLAYER_SPEED, 0); } }); k.onKeyPress("space", () => { player.jump(); }); // Handle star collection player.onCollide("star", (star) => { updateScore(); // Increase score k.destroy(star); // Remove the star }); // Add the ground k.add([ k.rect(k.width(), 50), k.pos(0, k.height() - 50), k.area(), k.color(109, 99, 19), k.body({ isStatic: true }), "ground", // Tag for collision detection ]); // Timer function that updates every second const updateTimer = () => { if (!gameEnded) { secondsElapsed += 1; timerLabel.text = `Time: ${secondsElapsed}s`; } else { timerController.cancel(); } }; // Update the timer every second let timerController = k.loop(1, updateTimer);
Step 3: Place collect.mp3 and game_over.mp3 files in public/sounds folder. You can download these files from below link.
Step 4: Execute below commands from project root folder to run the Application.
npm install npm run dev
Launch the url ‘http://localhost:3001/’ in a browser to play with the Application.
You can see a demo recording here (https://www.youtube.com/watch?v=ewroGaX-Nr4)
You can download the Application from this link.
References
Sounds to download: https://mixkit.co/free-sound-effects/game/
Previous Next Home
No comments:
Post a Comment