Skip to content

Commit 89fb7ab

Browse files
authored
Merge pull request #70 from HARSH-1607/add-js-platformer
Added Simple Platformer game in Javascript
2 parents af56ccb + 3573672 commit 89fb7ab

5 files changed

Lines changed: 307 additions & 0 deletions

File tree

INDEX.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ A responsive, difficulty-based memory card game built with HTML, CSS, and JavaSc
4848
### 🎯 [NumberGuessingGame](./Javascript/NumberGuessingGame/)
4949
A simple web-based number guessing game built with HTML, CSS, and JavaScript.
5050

51+
### 🎯 [Simple Platformer](./Javascript/SimplePlatformer/)
52+
A classic 2D platformer game with jumping, collision detection, and a win condition, built with HTML Canvas and vanilla JavaScript.
53+
5154
### 🎯 [Rock Paper Scissor](./Javascript/Rock Paper Scissor/)
5255
A fun game built with core programming concepts
5356

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
🎮 Simple Platformer Game
2+
3+
A classic 2D platformer game built with HTML, CSS, and vanilla JavaScript.
4+
5+
🕹️ How to Play
6+
7+
Open the index.html file in your web browser.
8+
9+
Use the Arrow Keys or WASD keys to move your character left and right.
10+
11+
Use the Spacebar or W key to jump.
12+
13+
Navigate the platforms to reach the Gold Block to win.
14+
15+
If you fall off the bottom or hit the side walls, the game will restart. You can also click the "Reset Game" button at any time.
16+
17+
🛠️ Features
18+
19+
HTML Canvas: The entire game is rendered on an HTML <canvas>.
20+
21+
Physics: Includes basic gravity and jumping mechanics.
22+
23+
Collision Detection: The player can land on top of platforms.
24+
25+
Win/Lose States: A clear win condition (reaching the goal) and multiple restart conditions (falling, hitting walls).
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Simple Platformer</title>
7+
<link rel="stylesheet" href="style.css">
8+
</head>
9+
<body>
10+
<h1>Simple JS Platformer</h1>
11+
<canvas id="gameCanvas" width="800" height="600"></canvas>
12+
<div class="controls">
13+
<button id="resetButton">Reset Game</button>
14+
<p>Controls: Arrows or WASD (Move), Spacebar or W (Jump)</p>
15+
</div>
16+
<script src="script.js"></script>
17+
</body>
18+
</html>
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
const canvas = document.getElementById('gameCanvas');
2+
const ctx = canvas.getContext('2d');
3+
const resetButton = document.getElementById('resetButton');
4+
5+
const GRAVITY = 0.5;
6+
let player;
7+
let platforms = [];
8+
let goal;
9+
let keys = {
10+
right: false,
11+
left: false,
12+
up: false
13+
};
14+
let gameActive = true;
15+
let winMessage = "You Win!";
16+
17+
// Player Class
18+
class Player {
19+
constructor() {
20+
this.position = { x: 100, y: 400 };
21+
this.velocity = { x: 0, y: 0 };
22+
this.width = 30;
23+
this.height = 30;
24+
this.onGround = false;
25+
}
26+
27+
draw() {
28+
ctx.fillStyle = '#4CAF50';
29+
ctx.fillRect(this.position.x, this.position.y, this.width, this.height);
30+
}
31+
32+
update() {
33+
this.draw();
34+
this.position.x += this.velocity.x;
35+
this.position.y += this.velocity.y;
36+
37+
// Apply gravity if not at bottom of canvas
38+
if (this.position.y + this.height + this.velocity.y < canvas.height) {
39+
this.velocity.y += GRAVITY;
40+
this.onGround = false;
41+
} else {
42+
this.velocity.y = 0;
43+
this.position.y = canvas.height - this.height;
44+
this.onGround = true;
45+
}
46+
47+
// --- NEW ---
48+
// Restart if player hits horizontal boundaries
49+
if (this.position.x < 0 || this.position.x + this.width > canvas.width) {
50+
init();
51+
}
52+
53+
// Restart if player falls off bottom
54+
if (this.position.y > canvas.height) {
55+
init();
56+
}
57+
}
58+
}
59+
60+
// Platform Class
61+
class Platform {
62+
constructor(x, y, width, height) {
63+
this.position = { x, y };
64+
this.width = width;
65+
this.height = height;
66+
}
67+
68+
draw() {
69+
ctx.fillStyle = '#8B4513'; // Brown color for platforms
70+
ctx.fillRect(this.position.x, this.position.y, this.width, this.height);
71+
}
72+
}
73+
74+
// Goal Class
75+
class Goal {
76+
constructor(x, y, width, height) {
77+
this.position = { x, y };
78+
this.width = width;
79+
this.height = height;
80+
}
81+
82+
draw() {
83+
ctx.fillStyle = '#FFD700'; // Gold color for the goal
84+
ctx.fillRect(this.position.x, this.position.y, this.width, this.height);
85+
}
86+
}
87+
88+
// Initialize game elements
89+
function init() {
90+
gameActive = true;
91+
player = new Player();
92+
platforms = [
93+
new Platform(0, 550, 300, 50),
94+
new Platform(400, 450, 200, 50),
95+
new Platform(650, 350, 150, 50),
96+
new Platform(400, 250, 100, 50)
97+
];
98+
goal = new Goal(425, 200, 50, 50); // Goal on the top platform
99+
}
100+
101+
// Main animation loop
102+
function animate() {
103+
if (!gameActive) {
104+
// Display win message
105+
ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
106+
ctx.fillRect(0, 0, canvas.width, canvas.height);
107+
ctx.font = '60px Arial';
108+
ctx.fillStyle = '#FFD700';
109+
ctx.textAlign = 'center';
110+
ctx.fillText(winMessage, canvas.width / 2, canvas.height / 2);
111+
return;
112+
}
113+
114+
requestAnimationFrame(animate);
115+
ctx.clearRect(0, 0, canvas.width, canvas.height);
116+
117+
// Draw goal
118+
goal.draw();
119+
120+
// Draw platforms
121+
platforms.forEach(platform => {
122+
platform.draw();
123+
});
124+
125+
// Update player
126+
player.update();
127+
128+
// Player movement (boundary checks moved to player.update)
129+
if (keys.left) {
130+
player.velocity.x = -5;
131+
} else if (keys.right) {
132+
player.velocity.x = 5;
133+
} else {
134+
player.velocity.x = 0;
135+
}
136+
137+
// Platform collision detection
138+
platforms.forEach(platform => {
139+
// Check for collision on top of the platform
140+
if (
141+
player.position.y + player.height <= platform.position.y &&
142+
player.position.y + player.height + player.velocity.y >= platform.position.y &&
143+
player.position.x + player.width >= platform.position.x &&
144+
player.position.x <= platform.position.x + platform.width
145+
) {
146+
player.velocity.y = 0;
147+
player.position.y = platform.position.y - player.height;
148+
player.onGround = true;
149+
}
150+
});
151+
152+
// Goal collision detection
153+
if (
154+
player.position.x < goal.position.x + goal.width &&
155+
player.position.x + player.width > goal.position.x &&
156+
player.position.y < goal.position.y + goal.height &&
157+
player.position.y + player.height > goal.position.y
158+
) {
159+
gameActive = false; // Stop the game
160+
}
161+
}
162+
163+
// Event Listeners
164+
function handleKeyDown({ keyCode }) {
165+
switch (keyCode) {
166+
case 37: // Left Arrow
167+
case 65: // A
168+
keys.left = true;
169+
break;
170+
case 39: // Right Arrow
171+
case 68: // D
172+
keys.right = true;
173+
break;
174+
case 32: // Spacebar
175+
case 87: // W
176+
if (player.onGround) {
177+
player.velocity.y = -12; // Jump height
178+
player.onGround = false;
179+
}
180+
break;
181+
}
182+
}
183+
184+
function handleKeyUp({ keyCode }) {
185+
switch (keyCode) {
186+
case 37: // Left Arrow
187+
case 65: // A
188+
keys.left = false;
189+
break;
190+
case 39: // Right Arrow
191+
case 68: // D
192+
keys.right = false;
193+
break;
194+
}
195+
}
196+
197+
window.addEventListener('keydown', handleKeyDown);
198+
window.addEventListener('keyup', handleKeyUp);
199+
200+
// --- UPDATED ---
201+
// Reset button listener logic fixed
202+
resetButton.addEventListener('click', () => {
203+
const wasGameStopped = !gameActive;
204+
init(); // Resets gameActive to true
205+
if (wasGameStopped) {
206+
animate(); // Manually restart the animation loop if it was stopped (on win screen)
207+
}
208+
});
209+
210+
// Start the game
211+
init();
212+
animate();
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
body {
2+
font-family: Arial, sans-serif;
3+
display: flex;
4+
flex-direction: column;
5+
justify-content: center;
6+
align-items: center;
7+
min-height: 100vh;
8+
background-color: #1a1a1a;
9+
color: #fff;
10+
margin: 0;
11+
}
12+
13+
h1 {
14+
font-size: 2rem;
15+
color: #4CAF50;
16+
}
17+
18+
canvas {
19+
background-color: #000;
20+
border: 2px solid #4CAF50;
21+
border-radius: 8px;
22+
box-shadow: 0 0 15px rgba(76, 175, 80, 0.5);
23+
}
24+
25+
.controls {
26+
text-align: center;
27+
margin-top: 20px;
28+
}
29+
30+
#resetButton {
31+
background-color: #4CAF50;
32+
color: white;
33+
border: none;
34+
padding: 10px 20px;
35+
font-size: 16px;
36+
border-radius: 5px;
37+
cursor: pointer;
38+
transition: background-color 0.3s;
39+
}
40+
41+
#resetButton:hover {
42+
background-color: #45a049;
43+
}
44+
45+
p {
46+
margin-top: 10px;
47+
font-size: 0.9rem;
48+
color: #ccc;
49+
}

0 commit comments

Comments
 (0)