Files
InfoGenie/InfoGenie-frontend/public/smallgame/推箱子/game.js
2026-03-28 20:59:52 +08:00

141 lines
3.6 KiB
JavaScript

const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const tileSize = 40;
const levels = [
[
'##########',
'# #',
'# @ #',
'# #',
'# $ #',
'# #',
'# . #',
'# #',
'##########'
],
[
'##########',
'# . #',
'# $ #',
'# @ #',
'# #',
'##########'
],
[
'##########',
'# #',
'# @ $. #',
'# #',
'# . #',
'# #',
'##########'
]
];
let currentLevel = 0;
let player = { x: 0, y: 0 };
let boxes = [];
let goals = [];
function loadLevel(level) {
boxes = [];
goals = [];
for (let y = 0; y < level.length; y++) {
for (let x = 0; x < level[y].length; x++) {
const char = level[y][x];
if (char === '@') {
player = { x, y };
} else if (char === '$') {
boxes.push({ x, y });
} else if (char === '.') {
goals.push({ x, y });
}
}
}
drawLevel(level);
}
function drawLevel(level) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let y = 0; y < level.length; y++) {
for (let x = 0; x < level[y].length; x++) {
const char = level[y][x];
if (char === '#') {
ctx.fillStyle = '#000';
ctx.fillRect(x * tileSize, y * tileSize, tileSize, tileSize);
} else if (char === '.') {
ctx.fillStyle = '#0f0';
ctx.fillRect(x * tileSize, y * tileSize, tileSize, tileSize);
}
}
}
drawPlayer();
drawBoxes();
}
function drawPlayer() {
ctx.fillStyle = '#00f';
ctx.fillRect(player.x * tileSize, player.y * tileSize, tileSize, tileSize);
}
function drawBoxes() {
ctx.fillStyle = '#f00';
boxes.forEach(box => {
ctx.fillRect(box.x * tileSize, box.y * tileSize, tileSize, tileSize);
});
}
function movePlayer(dx, dy) {
const newX = player.x + dx;
const newY = player.y + dy;
if (levels[currentLevel][newY][newX] === '#') return;
const boxIndex = boxes.findIndex(box => box.x === newX && box.y === newY);
if (boxIndex >= 0) {
const box = boxes[boxIndex];
const newBoxX = box.x + dx;
const newBoxY = box.y + dy;
if (levels[currentLevel][newBoxY][newBoxX] === '#' || boxes.some(b => b.x === newBoxX && b.y === newBoxY)) return;
box.x = newBoxX;
box.y = newBoxY;
}
player.x = newX;
player.y = newY;
checkLevelComplete();
drawLevel(levels[currentLevel]);
}
function checkLevelComplete() {
if (boxes.every(box => goals.some(goal => goal.x === box.x && goal.y === box.y))) {
currentLevel++;
if (currentLevel < levels.length) {
loadLevel(levels[currentLevel]);
} else {
alert('恭喜你完成了所有关卡!');
currentLevel = 0;
loadLevel(levels[currentLevel]);
}
}
}
window.addEventListener('keydown', (e) => {
switch (e.key) {
case 'ArrowUp':
movePlayer(0, -1);
break;
case 'ArrowDown':
movePlayer(0, 1);
break;
case 'ArrowLeft':
movePlayer(-1, 0);
break;
case 'ArrowRight':
movePlayer(1, 0);
break;
}
});
loadLevel(levels[currentLevel]);