141 lines
3.6 KiB
JavaScript
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]);
|