Robots/JavaScript
< Robots
Code
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const Grid = {
Player: "@",
Robot: "+",
Scrap: "*",
Mark: "~"
};
const dirs = [[-1, 1], [0, 1], [1, 1], [-1, 0], [1, 0], [-1, -1], [0, -1], [1, -1]];
let nRows = 38;
let nCols = 50;
let grid = [];
let playerRow, playerCol, score, hiScore, level;
let gameOver = true;
function initGrid() {
grid = Array(nRows).fill().map(() => Array(nCols).fill(null));
teleport();
const numRobots = 7 * level;
for (let i = 0; i < numRobots;) {
const r = Math.floor(Math.random() * nRows);
const c = Math.floor(Math.random() * nCols);
if (grid[r][c] === null) {
grid[r][c] = Grid.Robot;
i++;
}
}
}
function startNewGame() {
level = 1;
if (score > hiScore) hiScore = score;
score = 0;
initGrid();
gameOver = false;
draw();
}
function movePlayer(r, c) {
if (!withinBounds(r, c) || grid[r][c] !== null) {
gameOver = true;
} else {
if (playerRow !== undefined && playerCol !== undefined) {
grid[playerRow][playerCol] = null;
}
playerRow = r;
playerCol = c;
grid[r][c] = Grid.Player;
}
return !gameOver;
}
function move(dr, dc) {
if (playerRow === undefined || playerCol === undefined) return;
const r = playerRow + dr;
const c = playerCol + dc;
if (!withinBounds(r, c)) return;
if (!movePlayer(r, c)) return;
for (let rr = 0; rr < nRows; rr++) {
for (let cc = 0; cc < nCols; cc++) {
if (grid[rr][cc] === Grid.Robot) {
const nc = (c === cc ? 0 : (c - cc) / Math.abs(c - cc)) + cc;
const nr = (r === rr ? 0 : (r - rr) / Math.abs(r - rr)) + rr;
if (!withinBounds(nr, nc)) continue;
grid[rr][cc] = null;
if (grid[nr][nc] === Grid.Player) {
gameOver = true;
return;
} else if (grid[nr][nc] !== null) {
score++;
if (grid[nr][nc] !== Grid.Scrap) score++;
grid[nr][nc] = Grid.Scrap;
} else {
grid[nr][nc] = Grid.Mark;
}
}
}
}
let robotsLeft = 0;
for (let rr = 0; rr < nRows; rr++) {
for (let cc = 0; cc < nCols; cc++) {
if (grid[rr][cc] === Grid.Mark) grid[rr][cc] = Grid.Robot;
if (grid[rr][cc] === Grid.Robot) robotsLeft++;
}
}
if (robotsLeft === 0) {
level++;
initGrid();
}
}
function teleport() {
movePlayer(Math.floor(Math.random() * nRows), Math.floor(Math.random() * nCols));
}
function withinBounds(r, c) {
return c >= 0 && c < nCols && r >= 0 && r < nRows;
}
function drawBorder() {
ctx.strokeStyle = 'lightgray';
ctx.setLineDash([5, 5]);
ctx.strokeRect(22, 20, canvas.width - 41, canvas.height - 72);
ctx.setLineDash([]);
}
function drawGrid() {
ctx.font = '18px SansSerif';
ctx.fillStyle = 'black';
for (let r = 0; r < nRows; r++) {
for (let c = 0; c < nCols; c++) {
if (grid[r][c] !== null) {
ctx.fillText(grid[r][c], 24 + c * 15, 36 + r * 15);
}
}
}
}
function drawStartScreen() {
ctx.fillStyle = 'gray';
ctx.font = 'bold 48px SansSerif';
ctx.fillText('robots', 315, 280);
ctx.font = '18px SansSerif';
ctx.fillText('(use arrow keys to move player)', 270, 350);
ctx.fillText('(press T to teleport)', 300, 380);
ctx.fillText('(click to start)', 328, 410);
}
function drawScore() {
ctx.fillStyle = 'gray';
ctx.font = '18px SansSerif';
ctx.fillText(`hiscore ${hiScore} score ${score}`, 30, canvas.height - 17);
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, canvas.width, canvas.height);
drawBorder();
drawScore();
if (gameOver) {
drawStartScreen();
} else {
drawGrid();
}
}
canvas.addEventListener('mousedown', () => {
if (gameOver) {
startNewGame();
}
});
document.addEventListener('keydown', (e) => {
if (gameOver) return;
switch(e.key) {
case 'ArrowUp':
move(-1, 0);
break;
case 'ArrowDown':
move(1, 0);
break;
case 'ArrowLeft':
move(0, -1);
break;
case 'ArrowRight':
move(0, 1);
break;
case 't':
case 'T':
teleport();
break;
}
draw();
});
hiScore = 0;
score = 0;
initGrid();
draw();