Last active
August 24, 2025 18:47
-
-
Save AtnNn/c39992a1a1e3a4ef2bdfd01d0edf6be8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A simple game engine | |
// #1: The state of the game | |
// Aliens starting positions | |
const aliens = [{x: 10, y: 10}, {x:20, y:5}, {x: 25, y:15}] | |
// Ship info | |
const ship = { x: 5, direction: 0 } | |
// Size of the game screen | |
const width = 30 | |
const height = 15 | |
// Message to display | |
let message = 'A or D to move. Q to quit' | |
let score = 0; | |
// #2: Rendering | |
const draw = () => { | |
// Use a buffer to avoid flickering | |
// | |
// The first character in the buffer is | |
// a special code that clears the screen | |
const buffer = ['\033c', `Score: ${score} ${message}\n`] | |
// Loop `y` from top to bottom | |
for(let y = height; y >= 0 ; y--){ | |
// Loop `x` from left to right | |
for(let x = 0; x < width; x++){ | |
let out = ' '; | |
// Draw some stars at pseudo-random locations | |
if ((x * y) % 11 == 3) { | |
out = '.' | |
} | |
// Draw the ship | |
if (y == 0 && x == ship.x) { | |
out = 'W'; | |
} | |
// Draw the aliens | |
for (let alien of aliens) { | |
if(alien.x == x && alien.y == y){ | |
out = '@'; | |
} | |
} | |
buffer.push(out) | |
} | |
if(y !== 0) { | |
buffer.push('\n'); // next line | |
} | |
} | |
// write the buffer to the screen | |
process.stdout.write(buffer.join('')) | |
} | |
// #3: The game logic and physics engine | |
// make the aliens fall | |
const fall = () => { | |
for(let alien of aliens) { | |
alien.y-- | |
// If an alien touches the ground | |
if (alien.y < 0) { | |
// If it touched the ship, game over! | |
if (alien.x === ship.x) { | |
console.log('Game Over!') | |
process.exit(0); | |
} | |
// Give the player one point | |
score++; | |
// Move it back to the top | |
alien.y = height; | |
// Add another random alien | |
aliens.push({ | |
x: randomBetween(0, width), | |
y: randomBetween(height - 5, height) | |
}) | |
} | |
} | |
} | |
// Move the ship | |
const move = () => { | |
ship.x += ship.direction; | |
if (ship.x < 0) ship.x = 0; | |
if (ship.x >= width) ship.x = width - 1; | |
ship.direction = 0; | |
} | |
// #4: handling player input | |
process.stdin.setRawMode(true); | |
process.stdin.on('data', (input) => { | |
const code = input[0]; | |
switch (code) { | |
case 3: // Ctrl+C | |
case 113: // 'q' | |
process.exit(0); | |
case 97: // 'a' | |
ship.direction = -1; | |
break; | |
case 100: // 'd' | |
ship.direction = 1; | |
break; | |
default: | |
message = `Unkown character code: ${code}` | |
} | |
}); | |
const tick = () => { | |
fall(); | |
move(); | |
draw(); | |
} | |
// The game loop | |
const tickAndContinue = () => { | |
tick(); | |
setTimeout(tickAndContinue, 250); // four frames per second | |
} | |
// Run the game | |
tickAndContinue() | |
// Utility functions | |
const randomBetween = (a, b) => { | |
return Math.floor(a + Math.random() * (b - a + 1)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Run using NodeJS