Chapter 9: Keeping Score: Adding Game Logic

Creating a Scoring System

In game development, a scoring system adds depth and motivation for players to engage with your game. This chapter focuses on implementing a basic scoring system using JavaScript and HTML5 <canvas> for your platformer game.

To begin, set up your HTML file (index.html) with a <canvas> element and link your JavaScript file (script.js). Here’s an example structure:

html

<!DOCTYPE html>
<html>
<head>
<title>Keeping Score: Adding Game Logic</title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<h1>Creating a Scoring System</h1>
<canvas id="gameCanvas" width="800" height="600"></canvas>
<script src="script.js"></script>
</body>
</html>

Next, create a CSS file (styles.css) to style your page. This file should be in the same directory as your HTML file. Here’s an example of basic styling:

css

body {
font-family: Arial, sans-serif;
text-align: center;
background-color: #f0f0f0;
}

h1 {
color: #333;
}

canvas {
border: 2px solid #333;
margin-top: 20px;
}

Now, in your JavaScript file (script.js), implement a scoring system for your platformer game:

javascript

document.addEventListener('DOMContentLoaded', () => {
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

// Constants for the player character
const spriteWidth = 64; // Width of each sprite frame
const spriteHeight = 64; // Height of each sprite frame
let x = canvas.width / 2 - spriteWidth / 2; // Initial X position of the player
let y = canvas.height - spriteHeight - 10; // Initial Y position of the player
const speed = 4; // Movement speed of the player character
const jumpStrength = 12; // Strength of the jump

// Variables for player state
let isJumping = false;
let jumpVelocity = 0;
let score = 0; // Initialize score

// Game level data (example)
const level = [
{ x: 50, y: canvas.height - 50, width: 200, height: 10 },
{ x: 300, y: canvas.height - 100, width: 150, height: 10 },
{ x: 500, y: canvas.height - 150, width: 100, height: 10 }
// Add more platforms and obstacles as needed
];

// Function to draw the game level
function drawLevel() {
ctx.fillStyle = 'green'; // Example: fill color for platforms
level.forEach(platform => {
ctx.fillRect(platform.x, platform.y, platform.width, platform.height);
});
}

// Function to draw the player character
function drawPlayer() {
ctx.fillStyle = 'blue';
ctx.fillRect(x, y, spriteWidth, spriteHeight);
}

// Function to handle keyboard controls
let rightPressed = false;
let leftPressed = false;
let upPressed = false;
let downPressed = false;
document.addEventListener('keydown', keyDownHandler);
document.addEventListener('keyup', keyUpHandler);

function keyDownHandler(event) {
if (event.key === 'ArrowRight') {
rightPressed = true;
} else if (event.key === 'ArrowLeft') {
leftPressed = true;
}
if (event.key === 'ArrowUp' && !isJumping) {
upPressed = true;
isJumping = true;
jumpVelocity = jumpStrength;
}
}

function keyUpHandler(event) {
if (event.key === 'ArrowRight') {
rightPressed = false;
} else if (event.key === 'ArrowLeft') {
leftPressed = false;
}
}

// Function to move the player character based on keyboard input
function movePlayer() {
if (rightPressed && x < canvas.width - spriteWidth) {
x += speed;
} else if (leftPressed && x > 0) {
x -= speed;
}

// Apply jumping mechanics
if (isJumping) {
y -= jumpVelocity;
jumpVelocity -= 1; // Apply gravity
}

// Check for collisions with platforms to stop jumping
level.forEach(platform => {
if (x < platform.x + platform.width &&
x + spriteWidth > platform.x &&
y < platform.y + platform.height &&
y + spriteHeight > platform.y) {
// Collision detected
// Stop jumping when colliding with a platform
isJumping = false;
jumpVelocity = 0;
y = platform.y - spriteHeight;
}
});

// Apply gravity if not jumping and not on a platform
if (!isJumping) {
level.forEach(platform => {
if (!(x < platform.x + platform.width &&
x + spriteWidth > platform.x &&
y < platform.y + platform.height &&
y + spriteHeight > platform.y)) {
y += 1; // Apply gravity
}
});
}
}

// Function to check collisions between the player and game objects
function checkCollisions() {
// Example: Check collisions with obstacles or enemies
// Replace with your specific collision logic as needed
level.forEach(platform => {
if (x < platform.x + platform.width &&
x + spriteWidth > platform.x &&
y < platform.y + platform.height &&
y + spriteHeight > platform.y) {
// Collision detected
// Implement collision response logic (e.g., game over, score increment)
console.log('Collision with platform detected!');
}
});
}

// Function to update and display the score
function updateScore() {
ctx.font = '24px Arial';
ctx.fillStyle = 'black';
ctx.fillText('Score: ' + score, 10, 30);
}

// Function to draw everything on the canvas
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawLevel();
drawPlayer();
movePlayer();
checkCollisions();
updateScore();
requestAnimationFrame(draw);
}

// Start the game loop
draw();
});

In this JavaScript code:

  • The score variable tracks the player’s score throughout the game.
  • The updateScore function displays the current score on the canvas.
  • Implement scoring logic within collision detection or other game events to increase the score.
  • Customize scoring mechanics based on your game’s objectives and challenges to engage players effectively.

Integrating a scoring system enhances gameplay depth and motivates players to achieve higher scores. Experiment with additional features, such as level progression and leaderboard integration, to further enrich your platformer game. In the next section, explore advanced techniques like integrating sound effects and optimizing game performance to polish your game further.

Adding Lives and Levels

In game development, implementing lives and levels adds complexity and progression, enhancing player engagement and challenge. This chapter focuses on integrating lives and levels into your platformer game using JavaScript and HTML5 <canvas>.

To begin, set up your HTML file (index.html) with a <canvas> element and link your JavaScript file (script.js). Here’s an example structure:

html

<!DOCTYPE html>
<html>
<head>
<title>Keeping Score: Adding Game Logic</title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<h1>Adding Lives and Levels</h1>
<canvas id="gameCanvas" width="800" height="600"></canvas>
<script src="script.js"></script>
</body>
</html>

Next, create a CSS file (styles.css) to style your page. This file should be in the same directory as your HTML file. Here’s an example of basic styling:

css

body {
font-family: Arial, sans-serif;
text-align: center;
background-color: #f0f0f0;
}

h1 {
color: #333;
}

canvas {
border: 2px solid #333;
margin-top: 20px;
}

Now, in your JavaScript file (script.js), implement lives and levels for your platformer game:

javascript

document.addEventListener('DOMContentLoaded', () => {
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

// Constants for the player character
const spriteWidth = 64; // Width of each sprite frame
const spriteHeight = 64; // Height of each sprite frame
let x = canvas.width / 2 - spriteWidth / 2; // Initial X position of the player
let y = canvas.height - spriteHeight - 10; // Initial Y position of the player
const speed = 4; // Movement speed of the player character
const jumpStrength = 12; // Strength of the jump

// Variables for player state
let isJumping = false;
let jumpVelocity = 0;
let score = 0; // Initialize score
let lives = 3; // Number of lives
let currentLevel = 1; // Current game level

// Game level data (example)
const levels = [
[
{ x: 50, y: canvas.height - 50, width: 200, height: 10 },
{ x: 300, y: canvas.height - 100, width: 150, height: 10 },
{ x: 500, y: canvas.height - 150, width: 100, height: 10 }
// Add more platforms and obstacles for level 1
],
[
{ x: 100, y: canvas.height - 50, width: 250, height: 10 },
{ x: 400, y: canvas.height - 100, width: 200, height: 10 },
{ x: 600, y: canvas.height - 150, width: 150, height: 10 }
// Add more platforms and obstacles for level 2
]
// Add more levels as needed
];

let currentPlatforms = levels[currentLevel - 1]; // Set initial platforms for current level

// Function to draw the game level
function drawLevel() {
ctx.fillStyle = 'green'; // Example: fill color for platforms
currentPlatforms.forEach(platform => {
ctx.fillRect(platform.x, platform.y, platform.width, platform.height);
});
}

// Function to draw the player character
function drawPlayer() {
ctx.fillStyle = 'blue';
ctx.fillRect(x, y, spriteWidth, spriteHeight);
}

// Function to handle keyboard controls
let rightPressed = false;
let leftPressed = false;
let upPressed = false;
let downPressed = false;
document.addEventListener('keydown', keyDownHandler);
document.addEventListener('keyup', keyUpHandler);

function keyDownHandler(event) {
if (event.key === 'ArrowRight') {
rightPressed = true;
} else if (event.key === 'ArrowLeft') {
leftPressed = true;
}
if (event.key === 'ArrowUp' && !isJumping) {
upPressed = true;
isJumping = true;
jumpVelocity = jumpStrength;
}
}

function keyUpHandler(event) {
if (event.key === 'ArrowRight') {
rightPressed = false;
} else if (event.key === 'ArrowLeft') {
leftPressed = false;
}
}

// Function to move the player character based on keyboard input
function movePlayer() {
if (rightPressed && x < canvas.width - spriteWidth) {
x += speed;
} else if (leftPressed && x > 0) {
x -= speed;
}

// Apply jumping mechanics
if (isJumping) {
y -= jumpVelocity;
jumpVelocity -= 1; // Apply gravity
}

// Check for collisions with platforms to stop jumping
currentPlatforms.forEach(platform => {
if (x < platform.x + platform.width &&
x + spriteWidth > platform.x &&
y < platform.y + platform.height &&
y + spriteHeight > platform.y) {
// Collision detected
// Stop jumping when colliding with a platform
isJumping = false;
jumpVelocity = 0;
y = platform.y - spriteHeight;
}
});

// Apply gravity if not jumping and not on a platform
if (!isJumping) {
currentPlatforms.forEach(platform => {
if (!(x < platform.x + platform.width &&
x + spriteWidth > platform.x &&
y < platform.y + platform.height &&
y + spriteHeight > platform.y)) {
y += 1; // Apply gravity
}
});
}
}

// Function to check collisions between the player and game objects
function checkCollisions() {
// Example: Check collisions with obstacles or enemies
// Replace with your specific collision logic as needed
currentPlatforms.forEach(platform => {
if (x < platform.x + platform.width &&
x + spriteWidth > platform.x &&
y < platform.y + platform.height &&
y + spriteHeight > platform.y) {
// Collision detected
// Implement collision response logic (e.g., game over, score increment)
console.log('Collision with platform detected!');
}
});
}

// Function to update and display game information (score, lives, level)
function updateGameInfo() {
ctx.font = '24px Arial';
ctx.fillStyle = 'black';
ctx.fillText('Score: ' + score, 10, 30);
ctx.fillText('Lives: ' + lives, canvas.width - 100, 30);
ctx.fillText('Level: ' + currentLevel, 10, 60);
}

// Function to check if the player has completed the level
function checkLevelComplete() {
// Example: Implement logic to check if the player has completed the current level
// For demonstration, increase the score and move to the next level after collision with a platform
currentPlatforms.forEach(platform => {
if (x < platform.x + platform.width &&
x + spriteWidth > platform.x &&
y < platform.y + platform.height &&
y + spriteHeight > platform.y) {
// Increase score and move to the next level
score += 10;
currentLevel++;
if (currentLevel <= levels.length) {
currentPlatforms = levels[currentLevel - 1];
// Reset player position for the new level
x = canvas.width / 2 - spriteWidth / 2;
y = canvas.height - spriteHeight - 10;
} else {
// Implement game completion logic (e.g., display victory message)
console.log('Game completed!');
// Optionally: Restart game or show game over screen
}
}
});
}

// Function to draw everything on the canvas
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawLevel();
drawPlayer();
movePlayer();
checkCollisions();
checkLevelComplete();
updateGameInfo();
requestAnimationFrame(draw);
}

// Start the game loop
draw();
});

In this JavaScript code:

  • The lives variable tracks the remaining lives of the player.
  • The currentLevel variable manages the current level of the game.
  • The levels array stores data for multiple levels, each containing its own set of platforms and obstacles.
  • Functions like checkLevelComplete determine when a player completes a level, updates the score, and advances to the next level.
  • Customize game progression and difficulty by adjusting level designs, scoring mechanics, and collision detection logic.

Integrating lives and levels enhances gameplay depth, providing players with challenges to overcome and goals to achieve. Experiment with additional features, such as enemy interactions and power-ups, to further enrich your platformer game. In the next section, explore advanced techniques like implementing game over screens and optimizing game performance to polish your game further.

Adding Lives and Levels

In game development, incorporating lives and levels adds depth and progression, enhancing player engagement and challenge. This chapter focuses on integrating lives and levels into your platformer game using JavaScript and HTML5 <canvas>.

To start, set up your HTML file (index.html) with a <canvas> element and link your JavaScript file (script.js). Here’s an example structure:

html

<!DOCTYPE html>
<html>
<head>
<title>Keeping Score: Adding Game Logic</title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<h1>Adding Lives and Levels</h1>
<canvas id="gameCanvas" width="800" height="600"></canvas>
<script src="script.js"></script>
</body>
</html>

Next, create a CSS file (styles.css) to style your page. This file should be in the same directory as your HTML file. Here’s an example of basic styling:

css

body {
font-family: Arial, sans-serif;
text-align: center;
background-color: #f0f0f0;
}

h1 {
color: #333;
}

canvas {
border: 2px solid #333;
margin-top: 20px;
}

Now, in your JavaScript file (script.js), implement lives and levels for your platformer game:

javascript

document.addEventListener('DOMContentLoaded', () => {
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

// Constants for the player character
const spriteWidth = 64; // Width of each sprite frame
const spriteHeight = 64; // Height of each sprite frame
let x = canvas.width / 2 - spriteWidth / 2; // Initial X position of the player
let y = canvas.height - spriteHeight - 10; // Initial Y position of the player
const speed = 4; // Movement speed of the player character
const jumpStrength = 12; // Strength of the jump

// Variables for player state
let isJumping = false;
let jumpVelocity = 0;
let score = 0; // Initialize score
let lives = 3; // Number of lives
let currentLevel = 1; // Current game level

// Game level data (example)
const levels = [
[
{ x: 50, y: canvas.height - 50, width: 200, height: 10 },
{ x: 300, y: canvas.height - 100, width: 150, height: 10 },
{ x: 500, y: canvas.height - 150, width: 100, height: 10 }
// Add more platforms and obstacles for level 1
],
[
{ x: 100, y: canvas.height - 50, width: 250, height: 10 },
{ x: 400, y: canvas.height - 100, width: 200, height: 10 },
{ x: 600, y: canvas.height - 150, width: 150, height: 10 }
// Add more platforms and obstacles for level 2
]
// Add more levels as needed
];

let currentPlatforms = levels[currentLevel - 1]; // Set initial platforms for current level

// Function to draw the game level
function drawLevel() {
ctx.fillStyle = 'green'; // Example: fill color for platforms
currentPlatforms.forEach(platform => {
ctx.fillRect(platform.x, platform.y, platform.width, platform.height);
});
}

// Function to draw the player character
function drawPlayer() {
ctx.fillStyle = 'blue';
ctx.fillRect(x, y, spriteWidth, spriteHeight);
}

// Function to handle keyboard controls
let rightPressed = false;
let leftPressed = false;
let upPressed = false;
let downPressed = false;
document.addEventListener('keydown', keyDownHandler);
document.addEventListener('keyup', keyUpHandler);

function keyDownHandler(event) {
if (event.key === 'ArrowRight') {
rightPressed = true;
} else if (event.key === 'ArrowLeft') {
leftPressed = true;
}
if (event.key === 'ArrowUp' && !isJumping) {
upPressed = true;
isJumping = true;
jumpVelocity = jumpStrength;
}
}

function keyUpHandler(event) {
if (event.key === 'ArrowRight') {
rightPressed = false;
} else if (event.key === 'ArrowLeft') {
leftPressed = false;
}
}

// Function to move the player character based on keyboard input
function movePlayer() {
if (rightPressed && x < canvas.width - spriteWidth) {
x += speed;
} else if (leftPressed && x > 0) {
x -= speed;
}

// Apply jumping mechanics
if (isJumping) {
y -= jumpVelocity;
jumpVelocity -= 1; // Apply gravity
}

// Check for collisions with platforms to stop jumping
currentPlatforms.forEach(platform => {
if (x < platform.x + platform.width &&
x + spriteWidth > platform.x &&
y < platform.y + platform.height &&
y + spriteHeight > platform.y) {
// Collision detected
// Stop jumping when colliding with a platform
isJumping = false;
jumpVelocity = 0;
y = platform.y - spriteHeight;
}
});

// Apply gravity if not jumping and not on a platform
if (!isJumping) {
currentPlatforms.forEach(platform => {
if (!(x < platform.x + platform.width &&
x + spriteWidth > platform.x &&
y < platform.y + platform.height &&
y + spriteHeight > platform.y)) {
y += 1; // Apply gravity
}
});
}
}

// Function to check collisions between the player and game objects
function checkCollisions() {
// Example: Check collisions with obstacles or enemies
// Replace with your specific collision logic as needed
currentPlatforms.forEach(platform => {
if (x < platform.x + platform.width &&
x + spriteWidth > platform.x &&
y < platform.y + platform.height &&
y + spriteHeight > platform.y) {
// Collision detected
// Implement collision response logic (e.g., game over, score increment)
console.log('Collision with platform detected!');
}
});
}

// Function to update and display game information (score, lives, level)
function updateGameInfo() {
ctx.font = '24px Arial';
ctx.fillStyle = 'black';
ctx.fillText('Score: ' + score, 10, 30);
ctx.fillText('Lives: ' + lives, canvas.width - 100, 30);
ctx.fillText('Level: ' + currentLevel, 10, 60);
}

// Function to check if the player has completed the level
function checkLevelComplete() {
// Example: Implement logic to check if the player has completed the current level
// For demonstration, increase the score and move to the next level after collision with a platform
currentPlatforms.forEach(platform => {
if (x < platform.x + platform.width &&
x + spriteWidth > platform.x &&
y < platform.y + platform.height &&
y + spriteHeight > platform.y) {
// Increase score and move to the next level
score += 10;
currentLevel++;
if (currentLevel <= levels.length) {
currentPlatforms = levels[currentLevel - 1];
// Reset player position for the new level
x = canvas.width / 2 - spriteWidth / 2;
y = canvas.height - spriteHeight - 10;
} else {
// Implement game completion logic (e.g., display victory message)
console.log('Game completed!');
// Optionally: Restart game or show game over screen
}
}
});
}

// Function to draw everything on the canvas
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawLevel();
drawPlayer();
movePlayer();
checkCollisions();
checkLevelComplete();
updateGameInfo();
requestAnimationFrame(draw);
}

// Start the game loop
draw();
});

In this JavaScript code:

  • The lives variable tracks the remaining lives of the player.
  • The currentLevel variable manages the current level of the game.
  • The levels array stores data for multiple levels, each containing its own set of platforms and obstacles.
  • Functions like checkLevelComplete determine when a player completes a level, updates the score, and advances to the next level.
  • Customize game progression and difficulty by adjusting level designs, scoring mechanics, and collision detection logic.

Integrating lives and levels enhances gameplay depth, providing players with challenges to overcome and goals to achieve. Experiment with additional features, such as enemy interactions and power-ups, to further enrich your platformer game. In the next section, explore advanced techniques like implementing game over screens and optimizing game performance to polish your game further.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *