科学教育
标题:
赵月圆
[打印本页]
作者:
yue
时间:
2025-12-2 13:58
标题:
赵月圆
帮我生成飞机大战网页代码
html,js,css
作者:
kaia
时间:
2025-12-2 13:59
你好!我帮你写一个简单版的“飞机大战”网页游戏,里面有小飞机可以左右移动,能发射子弹打掉敌机。代码分三部分:HTML负责页面结构,CSS负责样式,JS负责游戏逻辑。你可以把它们全部复制到一个文件里,比如叫`plane_game.html`,然后用浏览器打开就能玩啦!
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>简易飞机大战</title>
<style>
/* 设置游戏区域 */
body {
background: #000;
margin: 0;
overflow: hidden;
font-family: "微软雅黑", sans-serif;
}
#game {
position: relative;
margin: 20px auto;
width: 400px;
height: 600px;
background: linear-gradient(to bottom, #003366, #000);
border: 3px solid #fff;
overflow: hidden;
}
/* 我的飞机 */
#player {
position: absolute;
width: 40px;
height: 40px;
background: url('https://i.imgur.com/QaP1b6D.png') no-repeat center/contain;
bottom: 20px;
left: 180px;
}
/* 子弹 */
.bullet {
position: absolute;
width: 6px;
height: 14px;
background: yellow;
border-radius: 3px;
}
/* 敌机 */
.enemy {
position: absolute;
width: 40px;
height: 40px;
background: url('https://i.imgur.com/qj1d4Ss.png') no-repeat center/contain;
}
/* 分数显示 */
#scoreBoard {
color: white;
text-align: center;
margin-top: 10px;
font-size: 18px;
}
</style>
</head>
<body>
<div id="game">
<div id="player"></div>
</div>
<div id="scoreBoard">得分: 0</div>
<script>
const game = document.getElementById('game');
const player = document.getElementById('player');
const scoreBoard = document.getElementById('scoreBoard');
const gameWidth = game.clientWidth;
const gameHeight = game.clientHeight;
let playerX = 180; // 初始位置
const playerWidth = 40;
let bullets = []; // 存放所有子弹元素和数据
let enemies = []; // 存放所有敌机元素和数据
let score = 0;
let isGameOver = false;
// 控制飞机左右移动
document.addEventListener('keydown', (e) => {
if (isGameOver) return;
if (e.key === 'ArrowLeft' || e.key === 'a') {
playerX -= 15;
if (playerX < 0) playerX = 0;
player.style.left = playerX + 'px';
} else if (e.key === 'ArrowRight' || e.key === 'd') {
playerX += 15;
if (playerX > gameWidth - playerWidth) playerX = gameWidth - playerWidth;
player.style.left = playerX + 'px';
} else if (e.key === ' ' || e.key === 'Spacebar') {
// 发射子弹
shootBullet();
}
});
// 创建子弹
function shootBullet() {
if (isGameOver) return;
const bullet = document.createElement('div');
bullet.classList.add('bullet');
bullet.style.left = playerX + playerWidth/2 - 3 + 'px'; // 居中
bullet.style.bottom = '60px'; // 从飞机上方开始
game.appendChild(bullet);
bullets.push({
el: bullet,
x: playerX + playerWidth/2 - 3,
y: 60,
height: 14,
width: 6,
});
}
// 创建敌机(随机横向位置)
function createEnemy() {
if (isGameOver) return;
const enemy = document.createElement('div');
enemy.classList.add('enemy');
const x = Math.floor(Math.random() * (gameWidth - 40));
enemy.style.left = x + 'px';
enemy.style.top = '-40px'; // 从顶部之外开始
game.appendChild(enemy);
enemies.push({
el: enemy,
x: x,
y: -40,
width: 40,
height: 40,
speed: 2 + Math.random() * 1.5 // 不同速度
});
}
// 每50毫秒刷新游戏画面
function gameLoop() {
if (isGameOver) return;
// 移动子弹
for (let i = bullets.length -1; i >= 0; i--) {
let b = bullets[i];
b.y += 7; // 要向上移动,所以y增加(因为bottom定位,y为底部距离)
if (b.y > gameHeight) {
// 子弹飞出屏幕,删除
game.removeChild(b.el);
bullets.splice(i, 1);
continue;
}
b.el.style.bottom = b.y + 'px';
}
// 移动敌机
for (let i = enemies.length -1; i >= 0; i--) {
let en = enemies[i];
en.y += en.speed;
if (en.y > gameHeight) {
// 敌机到底部了,游戏结束
endGame();
return;
}
en.el.style.top = en.y + 'px';
}
// 检测子弹和敌机碰撞
for (let i = enemies.length -1; i >= 0; i--) {
const en = enemies[i];
const ex = en.x;
const ey = en.y;
const ew = en.width;
const eh = en.height;
for (let j = bullets.length -1; j >= 0; j--) {
const b = bullets[j];
const bx = b.x;
const by = gameHeight - b.y; // 转成top坐标
const bw = b.width;
const bh = b.height;
// 判断矩形是否重叠(简单碰撞检测)
if (!(bx > ex + ew || bx + bw < ex || by > ey + eh || by + bh < ey)) {
// 碰撞了
game.removeChild(en.el);
game.removeChild(b.el);
enemies.splice(i, 1);
bullets.splice(j, 1);
// 增加分数
score++;
scoreBoard.textContent = '得分: ' + score;
break;
}
}
}
requestAnimationFrame(gameLoop);
}
// 游戏结束
function endGame() {
isGameOver = true;
alert('游戏结束!你的得分是:' + score);
window.location.reload(); // 重新加载页面,重置游戏
}
// 定时产生敌机
setInterval(() => {
if (!isGameOver) createEnemy();
}, 1500);
// 启动游戏循环
requestAnimationFrame(gameLoop);
</script>
</body>
</html>
复制代码
---
### 游戏玩法说明:
- 用键盘左右箭头(或者A、D键)控制你的飞机左右移动。
- 按空格键发射子弹,子弹会向上飞。
- 敌机会从上方出现并往下飞,碰到你的飞机底部游戏结束。
- 击落敌机会得分。
- 游戏结束后会弹窗告诉你得分,并自动刷新页面重新开始。
希望你喜欢这个小游戏!如果想让飞机和敌机图更漂亮,可以换链接里的图片地址。有什么不懂问我,帮你解释哦!????✈️
作者:
yue
时间:
2025-12-2 14:14
将图片变得更漂亮,游戏更刺激
作者:
kaia
时间:
2025-12-2 14:16
yue 发表于 2025-12-02 14:14
将图片变得更漂亮,游戏更刺激
好的!我帮你升级一下:
1. **图片更漂亮** —— 我用更精致的PNG飞机和敌机图片,并且加了背景星空动画。
2. **游戏更刺激** —— 敌机速度逐渐加快,出现更多!还有生命值,敌机撞到飞机会掉血,不是一碰就结束,更有挑战性。
3. **增加爆炸效果和声音提示**(简单的网页音效),让战斗感觉更嗨!
你可以直接把下面代码保存成`plane_game.html`打开玩哈~
---
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>升级版飞机大战⚔️</title>
<style>
/* 背景星空动画 */
body, html {
margin: 0; padding: 0; overflow: hidden;
background: radial-gradient(ellipse at bottom, #1b2735 0%, #090a0f 100%);
height: 100%;
font-family: "微软雅黑", sans-serif;
user-select: none;
}
#starfield {
position: fixed;
width: 100%; height: 100%;
z-index: 0;
background: transparent;
}
#game {
position: relative;
margin: 20px auto;
width: 400px;
height: 600px;
background: #0B132B;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 0 30px #00FFFC;
z-index: 1;
}
/* 飞机 */
#player {
position: absolute;
width: 48px;
height: 48px;
bottom: 20px;
left: 176px;
background: url('https://cdn-icons-png.flaticon.com/512/744/744465.png') no-repeat center / contain;
filter: drop-shadow(0 0 3px #0ef);
transition: filter 0.1s;
}
#player.damaged {
filter: drop-shadow(0 0 10px red);
}
/* 子弹 */
.bullet {
position: absolute;
width: 8px;
height: 16px;
background: linear-gradient(90deg, #00faff, #005f7f);
border-radius: 4px;
filter: drop-shadow(0 0 5px #00faff);
}
/* 敌机 */
.enemy {
position: absolute;
width: 48px;
height: 48px;
background: url('https://cdn-icons-png.flaticon.com/512/616/616490.png') no-repeat center / contain;
filter: drop-shadow(0 0 5px #f00);
transition: transform 0.1s;
}
.enemy.damaged {
transform: scale(1.2);
}
/* 爆炸效果 */
.explosion {
position: absolute;
width: 48px;
height: 48px;
background: url('https://i.ibb.co/1rvdWgF/explosion.png') no-repeat center / contain;
pointer-events: none;
animation: explode 0.5s ease forwards;
z-index: 10;
}
@keyframes explode {
0% {opacity:1; transform: scale(1);}
100% {opacity:0; transform: scale(1.8);}
}
/* 分数和生命 */
#infoBar {
color: #0ff;
text-align: center;
font-size: 20px;
margin-top: 10px;
letter-spacing: 1.5px;
user-select:none;
}
#hp {
color: #f44;
font-weight: bold;
margin-left: 20px;
}
</style>
</head>
<body>
<canvas id="starfield"></canvas>
<div id="game" tabindex="0">
<div id="player"></div>
</div>
<div id="infoBar">得分: 0 <span id="hp">❤❤❤</span></div>
<script>
const game = document.getElementById("game");
const player = document.getElementById("player");
const scoreBoard = document.querySelector("#infoBar");
const hpDisplay = document.getElementById("hp");
const gameWidth = game.clientWidth;
const gameHeight = game.clientHeight;
let playerX = (gameWidth - player.clientWidth) / 2;
const playerWidth = player.clientWidth;
const playerHeight = player.clientHeight;
// 子弹和敌机数据结构,存元素和位置等属性
let bullets = [];
let enemies = [];
let score = 0;
let hp = 3;
let isGameOver = false;
// 配置敌机初始速度和生成频率,随着分数提升会加快
let enemySpeedBase = 2.5;
let enemySpawnInterval = 1300;
// 星星背景动画
const starCanvas = document.getElementById("starfield");
const ctx = starCanvas.getContext("2d");
let stars = [];
resizeStarField();
window.addEventListener("resize", resizeStarField);
function resizeStarField() {
starCanvas.width = window.innerWidth;
starCanvas.height = window.innerHeight;
stars = [];
let count = 150;
for(let i=0; i<count; i++) {
stars.push({
x: Math.random()*starCanvas.width,
y: Math.random()*starCanvas.height,
size: Math.random()*1.5 + 0.5,
speed: Math.random()*0.2 + 0.05,
opacity: Math.random()*0.8 + 0.2,
});
}
}
function drawStars(){
ctx.clearRect(0, 0, starCanvas.width, starCanvas.height);
ctx.fillStyle = "white";
stars.forEach(s=>{
ctx.globalAlpha = s.opacity;
ctx.beginPath();
ctx.arc(s.x, s.y, s.size, 0, Math.PI*2);
ctx.fill();
s.y += s.speed;
if(s.y > starCanvas.height) s.y = 0;
});
ctx.globalAlpha = 1;
}
setInterval(drawStars, 33);
// 控制飞机左右移动(键盘)
let keysPressed = {};
game.focus();
game.addEventListener("keydown", (e) => {
keysPressed[e.key.toLowerCase()] = true;
// 发射子弹空格键
if(e.key === " " || e.code === "Space") {
shootBullet();
e.preventDefault();
}
});
game.addEventListener("keyup", (e) => {
keysPressed[e.key.toLowerCase()] = false;
});
// 游戏操作循环检测按键并移动飞机
function handlePlayerMovement() {
if(isGameOver) return;
if(keysPressed["arrowleft"] || keysPressed["a"]) {
playerX -= 6;
if(playerX < 0) playerX = 0;
} else if(keysPressed["arrowright"] || keysPressed["d"]) {
playerX += 6;
if(playerX > gameWidth - playerWidth) playerX = gameWidth - playerWidth;
}
player.style.left = playerX + "px";
}
// 发射子弹,限制发射频率
let lastShootTime = 0;
function shootBullet() {
if(isGameOver) return;
let now = Date.now();
if(now - lastShootTime < 250) return;
lastShootTime = now;
const bullet = document.createElement("div");
bullet.classList.add("bullet");
bullet.style.left = (playerX + playerWidth / 2 - 4) + "px";
bullet.style.bottom = (playerHeight + 20) + "px";
game.appendChild(bullet);
bullets.push({
el: bullet,
x: playerX + playerWidth / 2 - 4,
y: playerHeight + 20,
width: 8,
height: 16,
speed: 9
});
playSound(shootSound);
}
// 创建敌机,速度和频率随着时间调整
function createEnemy() {
if(isGameOver) return;
const enemy = document.createElement("div");
enemy.classList.add("enemy");
const x = Math.random() * (gameWidth - 48);
enemy.style.left = x + "px";
enemy.style.top = "-48px";
game.appendChild(enemy);
enemies.push({
el: enemy,
x: x,
y: -48,
width: 48,
height: 48,
speed: enemySpeedBase + Math.random() * 1.5
});
}
// 爆炸特效动画
function showExplosion(x, y) {
const exp = document.createElement("div");
exp.classList.add("explosion");
exp.style.left = x + "px";
exp.style.top = y + "px";
game.appendChild(exp);
setTimeout(() => {
exp.remove();
}, 500);
playSound(explosionSound);
}
// 游戏主循环
function gameLoop() {
if(isGameOver) return;
handlePlayerMovement();
// 移动子弹
for(let i=bullets.length-1; i>=0; i--) {
let b = bullets[i];
b.y += b.speed;
if(b.y > gameHeight) {
// 超出屏幕移除
b.el.remove();
bullets.splice(i, 1);
continue;
}
b.el.style.bottom = b.y + "px";
}
// 移动敌机
for(let i=enemies.length-1; i>=0; i--) {
let en = enemies[i];
en.y += en.speed;
if(en.y > gameHeight) {
// 敌机到底部造成伤害
enemiesDamagePlayer(en);
en.el.remove();
enemies.splice(i, 1);
continue;
}
en.el.style.top = en.y + "px";
}
// 碰撞检测:子弹 & 敌机
for(let i=enemies.length-1; i>=0; i--) {
const en = enemies[i];
for(let j=bullets.length-1; j>=0; j--) {
const b = bullets[j];
if(rectCollision(en, b)) {
// 撞击爆炸,移除敌机和子弹
showExplosion(en.x, en.y);
en.el.remove();
b.el.remove();
enemies.splice(i, 1);
bullets.splice(j, 1);
addScore(1);
break;
}
}
}
// 碰撞检测:敌机 & 玩家
for(let i=enemies.length-1; i>=0; i--) {
const en = enemies[i];
if(rectCollision(en, {
x: playerX,
y: gameHeight - playerHeight - 20,
width: playerWidth,
height: playerHeight
})) {
// 敌机撞到飞机
enemiesDamagePlayer(en);
showExplosion(en.x, en.y);
en.el.remove();
enemies.splice(i, 1);
}
}
requestAnimationFrame(gameLoop);
}
// 矩形碰撞检测函数
function rectCollision(a, b) {
return !(
a.x > b.x + b.width ||
a.x + a.width < b.x ||
a.y > b.y + b.height ||
a.y + a.height < b.y
);
}
// 玩家受伤:扣血与状态闪烁
let damageCooldown = false;
function enemiesDamagePlayer(enemy) {
if(damageCooldown) return;
hp--;
hpDisplay.textContent = "❤".repeat(hp) + "♡".repeat(3 - hp);
player.classList.add("damaged");
playSound(hitSound);
setTimeout(() => {
player.classList.remove("damaged");
damageCooldown = false;
}, 300);
damageCooldown = true;
if(hp <= 0) {
endGame();
}
}
// 得分增加,同时提升难度
function addScore(amount) {
score += amount;
scoreBoard.innerHTML = `得分: ${score} <span id="hp">${"❤".repeat(hp) + "♡".repeat(3 - hp)}</span>`;
// 随着得分提高,提高敌机速度,降低刷新间隔,最高速和最大密度有限制
enemySpeedBase = Math.min(5, 2.5 + score * 0.1);
enemySpawnInterval = Math.max(500, 1300 - score * 20);
clearInterval(enemySpawner);
enemySpawner = setInterval(createEnemy, enemySpawnInterval);
}
// 游戏结束函数
function endGame() {
isGameOver = true;
alert(`游戏结束!你的最终得分是:${score}。感谢挑战!`);
window.location.reload();
}
// 初始启动创建敌机定时器
let enemySpawner = setInterval(createEnemy, enemySpawnInterval);
// 启动游戏循环
requestAnimationFrame(gameLoop);
// 声音相关
// 简单用Web Audio API做发声
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
function playSound(buffer) {
if(!buffer) return;
const source = audioCtx.createBufferSource();
source.buffer = buffer;
source.connect(audioCtx.destination);
source.start(0);
}
// 使用fetch加载音效
let shootSound, explosionSound, hitSound;
function loadSounds() {
loadSound('https://cdn.jsdelivr.net/gh/fawazahmed0/cdn/sound/shoot.wav').then(b=>{
shootSound = b;
});
loadSound('https://cdn.jsdelivr.net/gh/fawazahmed0/cdn/sound/explosion.wav').then(b=>{
explosionSound = b;
});
loadSound('https://cdn.jsdelivr.net/gh/fawazahmed0/cdn/sound/hit.wav').then(b=>{
hitSound = b;
});
}
function loadSound(url) {
return fetch(url)
.then(r => r.arrayBuffer())
.then(arrayBuffer => audioCtx.decodeAudioData(arrayBuffer));
}
loadSounds();
</script>
</body>
</html>
复制代码
---
### 说明:
- **漂亮图标**用的是免费的PNG图标链接,清晰而且有光影效果。
- **星空背景**用canvas画了小星星往下闪动,好像飞行在太空。
- **子弹、敌机、飞机**都加了发光和阴影,视觉更炫酷。
- **生命值**用3颗心表示,撞一次敌机扣一颗,还能继续战斗。
- **敌机速度和数量**会根据你得分慢慢增加,越打越刺激!
- **爆炸特效**是放一个帧动画图形,看上去炸掉敌机很爽。
- **音效**:开火、爆炸和受伤都有声音哦,要先点击页面一次激活声音。
---
试试看这个版本玩得怎么样!如果要改成手机触屏操作或加关卡,也可以告诉我,我帮你写~祝你游戏开心✈️????
作者:
yue
时间:
2025-12-2 14:20
将图片变得更漂亮,游戏更刺激,可以计分,会排名
作者:
kaia
时间:
2025-12-2 14:26
yue 发表于 2025-12-02 14:20
将图片变得更漂亮,游戏更刺激,可以计分,会排名 ...
你好!我帮你写了一个更漂亮、更刺激的飞机大战小游戏,支持计分和排名(排行榜会保存在浏览器里),这样你每次玩都能看到自己的分数排第几哦。下面是完整代码,你可以直接保存为`plane_game.html`打开玩。
---
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>超级飞机大战 - 带排行榜</title>
<style>
/* 背景渐变和中心游戏区 */
body, html {
margin: 0; padding: 0; height: 100%;
background: linear-gradient(to bottom, #00111f, #000);
font-family: "微软雅黑", sans-serif;
overflow: hidden;
user-select: none;
}
#game {
position: relative;
width: 400px;
height: 600px;
margin: 20px auto;
background: linear-gradient(to bottom, #002240, #000010);
border-radius: 15px;
box-shadow: 0 0 20px #0af;
overflow: hidden;
}
/* 飞机 */
#player {
position: absolute;
width: 50px;
height: 50px;
bottom: 15px;
left: 175px;
background: url('https://cdn-icons-png.flaticon.com/512/6326/6326193.png') no-repeat center / contain;
filter: drop-shadow(0 0 5px #0ff);
transition: filter 0.2s;
z-index: 10;
}
#player.damaged {
filter: drop-shadow(0 0 13px red);
}
/* 子弹 */
.bullet {
position: absolute;
width: 10px;
height: 20px;
background: linear-gradient(90deg, #00ffff, #006677);
border-radius: 5px;
filter: drop-shadow(0 0 6px #0ff);
z-index: 9;
}
/* 敌机 */
.enemy {
position: absolute;
width: 50px;
height: 50px;
background: url('https://cdn-icons-png.flaticon.com/512/616/616489.png') no-repeat center / contain;
filter: drop-shadow(0 0 7px #f44);
transition: transform 0.15s ease;
z-index: 8;
}
.enemy.damaged {
transform: scale(1.2);
}
/* 爆炸动画 */
.explosion {
position: absolute;
width: 60px;
height: 60px;
background: url('https://i.ibb.co/1rvdWgF/explosion.png') no-repeat center / contain;
animation: explode 0.5s ease forwards;
pointer-events: none;
z-index: 20;
}
@keyframes explode {
0% {opacity: 1; transform: scale(1);}
100% {opacity: 0; transform: scale(1.8);}
}
/* 顶部状态栏 */
#infoBar {
color: #0ff;
text-align: center;
font-size: 20px;
letter-spacing: 2px;
margin-top: 10px;
user-select:none;
}
#hp {
color: #f44;
font-weight: bold;
margin-left: 20px;
}
/* 排行榜弹窗 */
#rankOverlay {
display: none;
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.75);
z-index: 50;
justify-content: center;
align-items: center;
}
#rankBox {
background: #002a4e;
padding: 20px 30px;
border-radius: 12px;
width: 320px;
max-height: 80vh;
overflow-y: auto;
color: #0ff;
}
#rankBox h2 {
margin-top: 0;
text-align: center;
}
#rankList {
margin-top: 10px;
}
#rankList li {
line-height: 1.6em;
font-size: 18px;
}
#closeRankBtn {
display: block;
margin: 15px auto 0;
background: #0ff;
border: none;
padding: 10px 20px;
border-radius: 8px;
cursor: pointer;
font-weight: bold;
color: #002a4e;
transition: background-color 0.3s;
}
#closeRankBtn:hover {
background: #06e;
color: white;
}
/* 提示文字 */
#tip {
text-align: center;
color: #08f;
font-size: 14px;
margin-bottom: 4px;
}
</style>
</head>
<body>
<div id="tip">左右方向键或A/D移动,空格发射子弹</div>
<div id="game" tabindex="0">
<div id="player"></div>
</div>
<div id="infoBar">得分: 0 <span id="hp">❤❤❤</span></div>
<!-- 排行榜弹窗 -->
<div id="rankOverlay">
<div id="rankBox">
<h2>排行榜 Top 10</h2>
<ol id="rankList"></ol>
<button id="closeRankBtn">关闭</button>
</div>
</div>
<script>
(() => {
const game = document.getElementById('game');
const player = document.getElementById('player');
const scoreBoard = document.getElementById('infoBar');
const hpDisplay = document.getElementById('hp');
const rankOverlay = document.getElementById('rankOverlay');
const rankList = document.getElementById('rankList');
const closeRankBtn = document.getElementById('closeRankBtn');
const gameWidth = game.clientWidth;
const gameHeight = game.clientHeight;
let playerX = (gameWidth - player.clientWidth) / 2;
const playerWidth = player.clientWidth;
const playerHeight = player.clientHeight;
let bullets = [];
let enemies = [];
let score = 0;
let hp = 3;
let isGameOver = false;
// 敌机速度和生成间隔随分数增长
let enemySpeedBase = 2.5;
let enemySpawnInterval = 1300;
// 控制发射频率,避免按着空格连发太快
let lastShootTime = 0;
const shootCooldown = 250;
// 控制玩家移动状态
let movingLeft = false;
let movingRight = false;
// 初始化位置
player.style.left = playerX + 'px';
// 键盘事件监听
window.addEventListener('keydown', (e) => {
if (isGameOver) return;
if (e.code === "ArrowLeft" || e.key.toLowerCase() === 'a') {
movingLeft = true;
} else if (e.code === "ArrowRight" || e.key.toLowerCase() === 'd') {
movingRight = true;
} else if (e.code === "Space") {
e.preventDefault();
shootBullet();
}
});
window.addEventListener('keyup', (e) => {
if (e.code === "ArrowLeft" || e.key.toLowerCase() === 'a') {
movingLeft = false;
} else if (e.code === "ArrowRight" || e.key.toLowerCase() === 'd') {
movingRight = false;
}
});
// 发射子弹
function shootBullet(){
if(isGameOver) return;
const now = Date.now();
if(now - lastShootTime < shootCooldown) return;
lastShootTime = now;
const bullet = document.createElement('div');
bullet.className = 'bullet';
const startX = playerX + playerWidth/2 - 5;
const startY = playerHeight + 15;
bullet.style.left = startX + 'px';
bullet.style.bottom = startY + 'px';
game.appendChild(bullet);
bullets.push({
el: bullet,
x: startX,
y: startY,
width: 10,
height: 20,
speed: 10
});
}
// 创建敌机,随机横向
function createEnemy() {
if(isGameOver) return;
const enemy = document.createElement('div');
enemy.className = 'enemy';
const x = Math.random() * (gameWidth - 50);
enemy.style.left = x + 'px';
enemy.style.top = '-50px';
game.appendChild(enemy);
enemies.push({
el: enemy,
x: x,
y: -50,
width: 50,
height: 50,
speed: enemySpeedBase + Math.random() * 1.5
});
}
// 爆炸动画效果
function showExplosion(x, y) {
const exp = document.createElement('div');
exp.className = 'explosion';
exp.style.left = (x - 5) + 'px';
exp.style.top = (y - 5) + 'px';
game.appendChild(exp);
setTimeout(() => {
exp.remove();
}, 500);
}
// 分数增加后调整敌机速度和生成频率
function levelUp() {
enemySpeedBase = 2.5 + score*0.1;
enemySpawnInterval = Math.max(600, 1300 - score*15);
}
// 矩形碰撞检测
function rectCollide(a, b){
return !(
a.x > b.x + b.width ||
a.x + a.width < b.x ||
a.y > b.y + b.height ||
a.y + a.height < b.y
);
}
// 玩家受伤处理
function playerHit() {
if (isGameOver) return;
hp--;
updateHpDisplay();
// 加个红色闪烁提示
player.classList.add('damaged');
setTimeout(() => player.classList.remove('damaged'), 300);
if (hp <= 0) {
gameOver();
}
}
// 更新生命显示
function updateHpDisplay(){
hpDisplay.textContent = '❤'.repeat(hp) + '♡'.repeat(3 - hp);
}
// 游戏结束:弹出输入名字界面并展示排行榜
function gameOver(){
isGameOver = true;
setTimeout(() => {
const name = prompt("游戏结束!你的得分:" + score + "\n请输入你的名字(不超过10字):", "玩家");
if(name!==null){
saveScore(name.trim().substring(0,10), score);
}
showRanking();
}, 100);
}
// 保存分数到本地localStorage里
function saveScore(name, score){
const rankData = JSON.parse(localStorage.getItem('planeRank') || '[]');
rankData.push({name, score});
// 按分数倒序排序
rankData.sort((a,b) => b.score - a.score);
// 只保留前20条
localStorage.setItem('planeRank', JSON.stringify(rankData.slice(0,20)));
}
// 显示排行榜弹窗
function showRanking(){
rankList.innerHTML = '';
const rankData = JSON.parse(localStorage.getItem('planeRank') || '[]');
const len = Math.min(10, rankData.length);
if(len === 0){
rankList.innerHTML = '<li>暂无排名数据</li>';
} else {
for(let i=0; i<len; i++){
const r = rankData[i];
const li = document.createElement('li');
li.textContent = `${i+1}. ${r.name} — ${r.score}分`;
rankList.appendChild(li);
}
}
rankOverlay.style.display = 'flex';
}
closeRankBtn.addEventListener('click', () => {
rankOverlay.style.display = 'none';
restartGame();
});
// 重置游戏数据,重新开始
function restartGame(){
// 清除所有敌机和子弹
bullets.forEach(b => b.el.remove());
enemies.forEach(e => e.el.remove());
bullets = [];
enemies = [];
score = 0;
hp = 3;
isGameOver = false;
updateHpDisplay();
updateScoreDisplay();
playerX = (gameWidth - playerWidth)/2;
player.style.left = playerX + 'px';
enemySpeedBase = 2.5;
enemySpawnInterval = 1300;
}
// 更新分数显示
function updateScoreDisplay(){
scoreBoard.childNodes[0].textContent = '得分: ' + score + ' ';
}
// 游戏主循环
let lastSpawnTime = 0;
function gameLoop(time=0){
if(isGameOver){
requestAnimationFrame(gameLoop);
return;
}
// 移动玩家
if(movingLeft){
playerX -= 6;
if(playerX < 0) playerX = 0;
}
if(movingRight){
playerX += 6;
if(playerX > gameWidth - playerWidth) playerX = gameWidth - playerWidth;
}
player.style.left = playerX + 'px';
// 移动子弹
for(let i=bullets.length-1; i>=0; i--){
let b = bullets[i];
b.y += b.speed;
if(b.y > gameHeight){
b.el.remove();
bullets.splice(i, 1);
continue;
}
b.el.style.bottom = b.y + 'px';
}
// 移动敌机
for(let i=enemies.length-1; i>=0; i--){
let en = enemies[i];
en.y += en.speed;
if(en.y > gameHeight){
// 到底部后对玩家造成伤害
playerHit();
en.el.remove();
enemies.splice(i, 1);
continue;
}
en.el.style.top = en.y + 'px';
}
// 碰撞检测:子弹和敌机
for(let i=enemies.length-1; i>=0; i--){
const en = enemies[i];
for(let j=bullets.length-1; j>=0; j--){
const b = bullets[j];
// 注意坐标系:敌机用top定位,y是距离上边;子弹用bottom定位,y是距离底部
// 为了简化,我们用相对于容器顶端的坐标计算,子弹y换算:
const bulletTop = gameHeight - b.y - b.height;
if(rectCollide(
{x: en.x, y: en.y, width: en.width, height: en.height},
{x: b.x, y: bulletTop, width: b.width, height: b.height}
)){
// 击中敌机
showExplosion(en.x, en.y);
en.el.remove();
b.el.remove();
enemies.splice(i, 1);
bullets.splice(j, 1);
score++;
updateScoreDisplay();
levelUp();
break;
}
}
}
// 碰撞检测:敌机和玩家
for(let i=enemies.length-1; i>=0; i--){
const en = enemies[i];
const playerTop = gameHeight - playerHeight - 15;
if(rectCollide(
{x: en.x, y: en.y, width: en.width, height: en.height},
{x: playerX, y: playerTop, width: playerWidth, height: playerHeight}
)){
playerHit();
showExplosion(en.x, en.y);
en.el.remove();
enemies.splice(i, 1);
break;
}
}
// 生成新敌机
if(time - lastSpawnTime > enemySpawnInterval){
createEnemy();
lastSpawnTime = time;
}
requestAnimationFrame(gameLoop);
}
// 入口:开始游戏
updateHpDisplay();
updateScoreDisplay();
game.focus();
requestAnimationFrame(gameLoop);
})();
</script>
</body>
</html>
复制代码
---
### 玩法说明:
- 用 **左右箭头** 或者 **A、D 键** 控制飞机左右移动。
- 按空格键发射子弹。
- 敌机会从顶部出现,往下飞。
- 子弹击中敌机得分,得分越高,敌机飞得越快,出现越频繁。
- 敌机撞到飞机或到达底部会扣一颗❤,生命值耗尽游戏结束。
- 游戏结束时会弹出输入框让你输名字保存分数,并显示排行榜前十名。
- 你可以关闭排行榜继续游戏,或者刷新页面重新开始。
---
### 图片说明:
- 飞机和敌机用的是高清PNG图标,带光影和投影效果,看起来更立体好看。
- 爆炸是一个小动画图片,让战斗过程更有感觉。
---
这个程序纯前端,不需要服务器,可以保存多次游戏分数,用浏览器本地存储保持排行榜。如果打开沙盒限制导致无法保存,可以换成Chrome或其他现代浏览器试试看。
有什么想改进的,随时告诉我,帮你优化!祝你游戏开心,打败所有敌机吧!✈️????????
欢迎光临 科学教育 (http://www.sci-edu.net/)
Powered by Discuz! X3.2