<!DOCTYPE html>
<html>
<head>
<title>Z Project</title>
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
}
canvas {
display: block;
width: 100vw;
height: 100vh;
image-rendering: pixelated;
}
</style>
</head>
<body>
<canvas id="gameCanvas"></canvas>
<script>
// 初始化Canvas并全屏
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// 动态调整Canvas分辨率
function resizeCanvas() {
const dpr = window.devicePixelRatio || 1;
canvas.width = window.innerWidth * dpr;
canvas.height = window.innerHeight * dpr;
canvas.style.width = '100vw';
canvas.style.height = '100vh';
}
window.addEventListener('resize', () => {
resizeCanvas();
player.x = canvas.width / 2 - player.width / 2;
player.y = canvas.height / 2 - player.height / 2;
});
resizeCanvas();
// 玩家属性
let player = {
x: canvas.width / 2 - 25,
y: canvas.height / 2 - 25,
width: 20,
height: 20,
speed: 5 // 移动速度
};
// 子弹数组
let bullets = [];
// 僵尸数组
let zombies = [];
// 鼠标坐标
let mouseX = 0, mouseY = 0;
// 游戏状态
let score = 0;
let gameRunning = true;
// 按键状态(WASD)
const keys = {
w: false,
a: false,
s: false,
d: false
};
// 监听键盘事件
document.addEventListener('keydown', (e) => {
if (e.key.toLowerCase() === 'w') keys.w = true;
if (e.key.toLowerCase() === 'a') keys.a = true;
if (e.key.toLowerCase() === 's') keys.s = true;
if (e.key.toLowerCase() === 'd') keys.d = true;
});
document.addEventListener('keyup', (e) => {
if (e.key.toLowerCase() === 'w') keys.w = false;
if (e.key.toLowerCase() === 'a') keys.a = false;
if (e.key.toLowerCase() === 's') keys.s = false;
if (e.key.toLowerCase() === 'd') keys.d = false;
});
// 监听鼠标事件
canvas.addEventListener('mousedown', (e) => {
const rect = canvas.getBoundingClientRect();
const scaleX = canvas.width / rect.width;
const scaleY = canvas.height / rect.height;
mouseX = (e.clientX - rect.left) * scaleX;
mouseY = (e.clientY - rect.top) * scaleY;
if (e.button === 0) shootBullet();
});
canvas.addEventListener('mousemove', (e) => {
const rect = canvas.getBoundingClientRect();
const scaleX = canvas.width / rect.width;
const scaleY = canvas.height / rect.height;
mouseX = (e.clientX - rect.left) * scaleX;
mouseY = (e.clientY - rect.top) * scaleY;
});
// 子弹射击函数
function shootBullet() {
const playerCenterX = player.x + player.width / 2;
const playerCenterY = player.y + player.height / 2;
const dx = mouseX - playerCenterX;
const dy = mouseY - playerCenterY;
const length = Math.sqrt(dx * dx + dy * dy);
const directionX = dx / length;
const directionY = dy / length;
bullets.push({
x: playerCenterX,
y: playerCenterY,
speedX: directionX * 10,
speedY: directionY * 10
});
}
// 游戏主循环
function gameLoop() {
update();
draw();
if (gameRunning) requestAnimationFrame(gameLoop);
}
// 更新游戏状态
function update() {
updatePlayer();
updateBullets();
updateZombies();
checkCollisions();
checkGameOver();
}
// 玩家移动逻辑
function updatePlayer() {
const speed = player.speed;
if (keys.w) player.y -= speed;
if (keys.s) player.y += speed;
if (keys.a) player.x -= speed;
if (keys.d) player.x += speed;
// 边界检测
const padding = 10;
if (player.x < padding) player.x = padding;
if (player.x + player.width > canvas.width - padding) player.x = canvas.width - player.width - padding;
if (player.y < padding) player.y = padding;
if (player.y + player.height > canvas.height - padding) player.y = canvas.height - player.height - padding;
}
// 子弹更新
function updateBullets() {
for (let b of bullets) {
b.x += b.speedX;
b.y += b.speedY;
if (b.x < 0 || b.x > canvas.width || b.y < 0 || b.y > canvas.height) {
const index = bullets.indexOf(b);
if (index > -1) bullets.splice(index, 1);
}
}
}
// 僵尸生成与移动(追踪逻辑)
function updateZombies() {
// 随机边缘生成僵尸
if (Math.random() < 0.02) {
const edge = Math.floor(Math.random() * 4); // 0-上 1-右 2-下 3-左
zombies.push({
x: edge === 1 ? canvas.width : edge === 3 ? 0 : Math.random() * canvas.width,
y: edge === 0 ? 0 : edge === 2 ? canvas.height : Math.random() * canvas.height,
width: 20,
height: 20,
speed: 1.5 // 调整速度
});
}
for (let z of zombies) {
// 计算方向向量
const dx = player.x - z.x;
const dy = player.y - z.y;
const length = Math.sqrt(dx*dx + dy*dy);
// 防止除零错误
if (length > 0) {
const directionX = dx / length;
const directionY = dy / length;
z.x += directionX * z.speed;
z.y += directionY * z.speed;
}
}
}
// 碰撞检测
function checkCollisions() {
for (let b of bullets) {
for (let z of zombies) {
if (collision(b, z)) {
const zIdx = zombies.indexOf(z);
const bIdx = bullets.indexOf(b);
if (zIdx > -1) zombies.splice(zIdx, 1);
if (bIdx > -1) bullets.splice(bIdx, 1);
score += 10;
return;
}
}
}
}
// 碰撞函数
function collision(a, b) {
return (
a.x < b.x + b.width &&
a.x + 5 > b.x &&
a.y < b.y + b.height &&
a.y + 10 > b.y
);
}
// 游戏结束检测
function checkGameOver() {
for (let z of zombies) {
if (collision(player, z)) {
gameRunning = false;
alert('Game Over! Final Score: ' + score);
}
}
}
// 绘制游戏画面
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制玩家
ctx.fillStyle = 'blue';
ctx.fillRect(player.x, player.y, player.width, player.height);
// 绘制子弹
for (let b of bullets) {
ctx.fillStyle = 'red';
ctx.fillRect(b.x - 2.5, b.y - 5, 5, 5);
}
// 绘制僵尸
for (let z of zombies) {
ctx.fillStyle = 'green';
ctx.fillRect(z.x, z.y, z.width, z.height);
}
// 绘制准星
ctx.beginPath();
ctx.arc(mouseX, mouseY, 5, 0, Math.PI * 2);
ctx.fillStyle = 'red';
ctx.fill();
// 显示分数
ctx.fillStyle = 'black';
ctx.font = '20px Arial';
ctx.fillText(`Score: ${score}`, 10, 30);
}
// 启动游戏
gameLoop();
</script>
</body>
</html>