同样问题:写一个网页版 射击小游戏代码,键盘控制左右,鼠标控制射击,并有记分
腾讯元宝普通
当然,可以为你提供一个更完善且功能丰富的网页版射击小游戏代码。这个游戏将使用HTML5 Canvas进行绘图,通过键盘控制飞船左右移动,鼠标控制射击,并实时显示得分。以下是完整的代码示例:
html
body {
margin: 0;
background-color: 000;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
canvas {
border: 2px solid fff;
}
scoreboard {
margin-top: 20px;
font-size: 24px;
color: fff;
}
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreboard = document.getElementById('scoreboard');
const settings = {
width: canvas.width,
height: canvas.height,
playerSpeed: 5,
bulletSpeed: 8,
enemySpeed: 3,
bulletInterval: 200, // milliseconds
scoreIncrement: 10,
gameOverScore: -100
};
let score = 0;
let gameOver = false;
let lastShotTime = 0;
class Player {
constructor() {
this.width = 40;
this.height = 40;
this.x = (settings.width - this.width) / 2;
this.y = settings.height - this.height - 10;
this.speed = settings.playerSpeed;
}
draw() {
ctx.fillStyle = 'blue';
ctx.fillRect(this.x, this.y, this.width, this.height);
}
move(dx) {
this.x += dx;
if (this.x < 0) this.x = 0;
if (this.x + this.width > settings.width) this.x = settings.width - this.width;
}
}
class Bullet {
constructor(x, y) {
this.width = 5;
this.height = 15;
this.x = x - this.width / 2;
this.y = y;
this.speed = settings.bulletSpeed;
}
draw() {
ctx.fillStyle = 'green';
ctx.fillRect(this.x, this.y, this.width, this.height);
}
update() {
this.y -= this.speed;
}
}
class Enemy {
constructor() {
this.width = 30;
this.height = 30;
this.x = Math.random() * (settings.width - this.width);
this.y = -this.height;
this.speed = settings.enemySpeed;
}
draw() {
ctx.fillStyle = 'red';
ctx.fillRect(this.x, this.y, this.width, this.height);
}
update() {
this.y += this.speed;
}
}
const player = new Player();
const bullets = ;
const enemies = ;
function draw() {
ctx.fillStyle = 'rgba(0, 0, 0, 0.2)';
ctx.fillRect(0, 0, settings.width, settings.height);
player.draw();
bullets.forEach((bullet, index) => {
bullet.draw();
if (bullet.y + bullet.height < 0) bullets.splice(index, 1);
});
enemies.forEach((enemy, index) => {
enemy.draw();
if (enemy.y > settings.height) {
score += settings.gameOverScore;
enemies.splice(index, 1);
}
});
ctx.fillStyle = 'white';
ctx.font = '20px Arial';
ctx.fillText(`得分: ${score}`, 10, 30);
if (score <= settings.gameOverScore) {
gameOver = true;
ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
ctx.fillRect(0, 0, settings.width, settings.height);
ctx.fillStyle = 'white';
ctx.font = '48px Arial';
ctx.fillText('游戏结束', settings.width / 2 - 120, settings.height / 2);
}
}
function update() {
if (gameOver) return;
bullets.forEach(bullet => bullet.update());
enemies.forEach(enemy => enemy.update());
// 碰撞检测
bullets.forEach((bullet, bIdx) => {
enemies.forEach((enemy, eIdx) => {
if (
bullet.x < enemy.x + enemy.width &&
bullet.x + bullet.width > enemy.x &&
bullet.y < enemy.y + enemy.height &&
bullet.y + bullet.height > enemy.y
) {
score += settings.scoreIncrement;
bullets.splice(bIdx, 1);
enemies.splice(eIdx, 1);
}
});
});
requestAnimationFrame(update);
}
function gameLoop() {
draw();
update();
}
const enemyInterval = setInterval(() => {
if (!gameOver) enemies.push(new Enemy());
}, 1000);
document.addEventListener('keydown', (e) => {
if (gameOver) return;
if (e.code === 'ArrowLeft') player.move(-settings.playerSpeed);
if (e.code === 'ArrowRight') player.move(settings.playerSpeed);
});
canvas.addEventListener('mousedown', (e) => {
if (gameOver) return;
const currentTime = Date.now();
if (currentTime - lastShotTime > settings.bulletInterval) {
bullets.push(new Bullet(e.offsetX, e.offsetY));
lastShotTime = currentTime;
}
});
gameLoop();
</script>
代码说明
1. HTML结构:
- `
- `
2. CSS样式:
- 设置了画布的边框和页面居中对齐。
- 游戏背景为黑色,玩家飞船为蓝色,子弹为绿色,敌人为红色。
3. JavaScript逻辑:
- 设置对象:集中管理游戏的各种参数,如尺寸、速度、得分等。
- 类定义:
- `Player`:表示玩家飞船,包含移动方法。
- `Bullet`:表示子弹,包含绘制和更新位置的方法。
- `Enemy`:表示敌人,包含绘制和更新位置的方法。
- 游戏循环:
- `draw()`函数负责绘制所有游戏元素。
- `update()`函数负责更新所有游戏元素的位置,并进行碰撞检测。
- `gameLoop()`函数通过`requestAnimationFrame`实现流畅的动画效果。
- 敌人生成:使用`setInterval`每隔一定时间生成一个敌人。
- 事件监听:
- 键盘事件控制玩家飞船左右移动。
- 鼠标点击事件控制射击,限制射击频率以避免子弹过多。
4. 游戏结束机制:
- 当得分降到或低于`gameOverScore`时,游戏结束并显示“游戏结束”字样。
如何运行
1. 将上述代码复制并粘贴到一个新的文本文件中。
2. 将文件保存为`shooting_game.html`。
3. 双击打开该HTML文件,或在浏览器中右键选择“使用浏览器打开”。
4. 使用左右箭头键控制飞船移动,点击鼠标左键发射子弹。
5. 尽量击落敌人以获得分数,避免敌人到达底部导致扣分。
扩展建议
- 增加不同类型的敌人:不同速度、大小或移动模式的敌人。
- 添加道具系统:如增加生命、提升子弹威力等。
- 优化碰撞检测:使用更高效的算法或库(如Phaser)来处理复杂的游戏逻辑。
- 音效和背景音乐:提升游戏的沉浸感。
- 响应式设计:使游戏在不同设备和屏幕尺寸上都能良好运行。
希望这个示例能帮助你创建一个有趣的网页射击游戏!如果有任何问题或需要进一步的功能扩展,欢迎随时提问。
运行如图:
hunyuan T1
#game-container {
width: 800px;
height: 600px;
border: 1px solid black;
position: relative;
background-color: #f0f0f0;
overflow: hidden;
}
.player {
width: 50px;
height: 50px;
background-color: blue;
position: absolute;
bottom: 20px;
left: 370px;
border-radius: 25px;
}
.enemy {
width: 40px;
height: 40px;
background-color: red;
position: absolute;
top: -100px;
animation: fall 2s linear infinite;
}
.bullet {
width: 10px;
height: 20px;
background-color: green;
position: absolute;
left: 20px;
bottom: -5px;
border-radius: 5px;
animation: shoot 0.5s linear;
}
.score {
position: absolute;
top: 10px;
right: 10px;
font-size: 24px;
color: white;
}
@keyframes fall {
0% { top: -100px; }
100% { top: 600px; }
}
@keyframes shoot {
0% { transform: scale(1); }
100% { transform: scale(0); }
}
<script>
class GameObject {
constructor(x, y, speedX, speedY) {
this.x = x;
this.y = y;
this.speedX = speedX || 0;
this.speedY = speedY || 0;
}
update() {
this.x += this.speedX;
this.y += this.speedY;
}
}
class Player extends GameObject {
constructor() {
super(370, 550, 0, 0);
this.speed = 5;
}
move(direction) {
if (direction === 'left') this.speedX = -this.speed;
else if (direction === 'right') this.speedX = this.speed;
}
}
class Enemy extends GameObject {
constructor() {
super(Math.random() * 700, -100, 0, 3);
this.speedY = Math.random() * 2 + 2;
}
}
class Bullet extends GameObject {
constructor(player) {
super(player.x - 20, player.y - 5, 10, 0);
this.speedX = 10;
}
}
let gameContainer = document.getElementById('game-container');
let scoreDisplay = document.querySelector('.score');
let score = 0;
const player = new Player();
const enemies = [];
const bullets = [];
// 键盘事件监听
document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowLeft') player.move('left');
if (e.key === 'ArrowRight') player.move('right');
});
// 鼠标事件监听
gameContainer.addEventListener('mousedown', () => {
bullets.push(new Bullet(player));
});
// 游戏循环
function gameLoop() {
// 移动玩家
player.update();
// 确保玩家不越界
if (player.x < 25) player.speedX = 0;
if (player.x > 725) player.speedX = 0;
// 更新子弹位置
bullets.forEach(bullet => {
bullet.update();
// 子弹消失条件
if (bullet.y < -10 bullet.x> 725) {
bullets.splice(bullets.indexOf(bullet), 1);
}
});
// 生成新敌人
if (Math.random() < 0.02) enemies.push(new Enemy());
// 更新敌人位置
enemies.forEach(enemy => {
enemy.update();
// 敌人消失条件
if (enemy.y > 600) {
enemies.splice(enemies.indexOf(enemy), 1);
score += 1;
scoreDisplay.textContent = score;
}
});
// 碰撞检测
bullets.forEach(bullet => {
enemies.forEach(enemy => {
if (
bullet.x < enemy.x + 40 &&
bullet.x + 10 > enemy.x &&
bullet.y < enemy.y + 40 &&
bullet.y + 20 > enemy.y
) {
bullets.splice(bullets.indexOf(bullet), 1);
enemies.splice(enemies.indexOf(enemy), 1);
score += 1;
scoreDisplay.textContent = score;
}
});
});
// 绘制所有对象
gameContainer.innerHTML = ''; // 清空容器
gameContainer.appendChild(player);
enemies.forEach(enemy => gameContainer.appendChild(enemy));
bullets.forEach(bullet => gameContainer.appendChild(bullet));
requestAnimationFrame(gameLoop);
}
gameLoop();
</script>
运行结果白屏
腾讯元宝DEEPSEEP R1
嗯,用户之前已经让我写过一个射击小游戏的代码,现在又重复了同样的请求。我需要先确认用户的需求是否有变化,或者他们可能遇到了什么问题。可能的情况是,用户可能没有正确运行之前的代码,或者希望得到改进的版本。
首先,我需要回顾之前的回答,看看是否存在问题。之前的代码使用了类继承,但可能在游戏循环中直接操作DOM元素,比如清空容器并重新添加元素,这可能导致性能问题。此外,碰撞检测可能在循环中嵌套遍历子弹和敌人,效率不高,尤其是当对象很多时。
用户这次的需求仍然是键盘控制左右,鼠标射击和记分。可能需要更稳定的代码结构,或者更清晰的注释。另外,之前的代码中玩家移动后可能没有限制边界,或者动画效果不够流畅。
接下来,我应该考虑如何优化代码。比如,使用Canvas代替DOM元素来提高性能,或者优化碰撞检测算法。但用户可能希望保持简单,使用HTML和CSS,所以可能需要调整之前的代码结构,使其更健壮。
另外,之前的代码中,玩家移动是通过直接修改speedX,但在游戏循环中可能没有正确处理按键释放,导致玩家一直移动。需要添加keyup事件来停止移动。同时,子弹的生成和移动可能需要调整,比如从玩家位置正确发射,并且限制子弹数量,避免过多影响性能。
记分系统在之前的代码中可能有问题,比如敌人到达底部时加分,而击中敌人时也加分,需要明确分数如何计算。此外,游戏结束条件可能没有处理,比如敌人碰到玩家时游戏结束。
现在,我需要确保新的代码解决这些问题。使用Canvas会更高效,但可能需要用户对Canvas有一定了解。保持使用DOM元素的话,需要优化绘制方式,避免频繁操作DOM。比如,使用绝对定位的元素,只更新位置而不是重新创建。
碰撞检测部分,可以使用更高效的算法,比如边界矩形检测,但之前的实现已经足够简单。需要确保检测条件正确,比如子弹和敌人的位置计算准确。
最后,确保代码结构清晰,注释明确,方便用户理解和修改。可能还需要添加游戏结束的逻辑和重新开始的功能,但用户没有明确要求,所以可能暂时不需要。
以下是一个优化后的网页版射击游戏代码,使用Canvas实现更流畅的性能和更好的游戏体验:
html
canvas {
border: 2px solid 333;
background: 000;
}
body {
display: flex;
flex-direction: column;
align-items: center;
background: 1a1a1a;
color: white;
}
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreElement = document.getElementById('score');
// 游戏对象
const player = {
x: canvas.width/2 - 25,
y: canvas.height - 60,
width: 50,
height: 50,
speed: 7,
isMovingLeft: false,
isMovingRight: false
};
let bullets = ;
let enemies = ;
let score = 0;
let gameOver = false;
// 键盘控制
document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowLeft') player.isMovingLeft = true;
if (e.key === 'ArrowRight') player.isMovingRight = true;
});
document.addEventListener('keyup', (e) => {
if (e.key === 'ArrowLeft') player.isMovingLeft = false;
if (e.key === 'ArrowRight') player.isMovingRight = false;
});
// 鼠标射击
canvas.addEventListener('mousedown', shoot);
function shoot() {
bullets.push({
x: player.x + player.width/2 - 2.5,
y: player.y,
width: 5,
height: 15,
speed: 10
});
}
function createEnemy() {
return {
x: Math.random() * (canvas.width - 40),
y: 0,
width: 40,
height: 40,
speed: 3
};
}
function checkCollision(rect1, rect2) {
return rect1.x < rect2.x + rect2.width &&
rect1.x + rect1.width > rect2.x &&
rect1.y < rect2.y + rect2.height &&
rect1.y + rect1.height > rect2.y;
}
function update() {
if (gameOver) return;
// 移动玩家
if (player.isMovingLeft && player.x > 0) {
player.x -= player.speed;
}
if (player.isMovingRight && player.x < canvas.width - player.width) {
player.x += player.speed;
}
// 更新子弹
bullets = bullets.filter(bullet => {
bullet.y -= bullet.speed;
return bullet.y > -bullet.height;
});
// 更新敌人
if (Math.random() < 0.02) {
enemies.push(createEnemy());
}
enemies.forEach(enemy => enemy.y += enemy.speed);
// 碰撞检测
enemies = enemies.filter(enemy => {
// 敌人到达底部
if (enemy.y > canvas.height) {
score -= 10;
return false;
}
// 子弹击中敌人
const hit = bullets.some(bullet => checkCollision(bullet, enemy));
if (hit) {
score += 20;
return false;
}
// 玩家碰撞检测
if (checkCollision(player, enemy)) {
gameOver = true;
}
return true;
});
scoreElement.textContent = `得分: ${Math.max(0, score)}`;
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制玩家
ctx.fillStyle = '00f';
ctx.fillRect(player.x, player.y, player.width, player.height);
// 绘制子弹
ctx.fillStyle = '0f0';
bullets.forEach(bullet => {
ctx.fillRect(bullet.x, bullet.y, bullet.width, bullet.height);
});
// 绘制敌人
ctx.fillStyle = 'f00';
enemies.forEach(enemy => {
ctx.fillRect(enemy.x, enemy.y, enemy.width, enemy.height);
});
// 游戏结束显示
if (gameOver) {
ctx.fillStyle = 'fff';
ctx.font = '48px Arial';
ctx.fillText('游戏结束!', canvas.width/2 - 120, canvas.height/2);
}
}
function gameLoop() {
update();
draw();
requestAnimationFrame(gameLoop);
}
// 启动游戏
gameLoop();
</script>
主要功能特点:
1. 使用Canvas实现流畅的动画效果
2. 键盘左右箭头控制飞船移动
3. 鼠标点击发射激光
4. 自动生成的红色敌人从顶部下落
5. 实时计分系统(击中+20分,漏掉-10分)
6. 碰撞检测系统
7. 游戏结束机制
8. 边界限制
游戏规则:
- 用左右方向键控制蓝色飞船移动
- 点击鼠标左键发射绿色激光
- 击中红色敌人得20分
- 每个到达屏幕底部的敌人扣10分
- 碰撞到敌人游戏结束
优化改进:
1. 使用Canvas代替DOM操作,性能更好
2. 添加了更完善的碰撞检测系统
3. 增加了游戏结束机制
4. 改进计分规则(有奖有罚)
5. 添加了玩家移动边界限制
6. 优化了敌人生成算法
7. 使用更高效的动画帧请求
你可以将此代码保存为.html文件,用现代浏览器打开即可游玩。可以通过调整以下参数自定义游戏:
- 修改player.speed调整移动速度
- 调整enemy.speed改变敌人下落速度
- 修改子弹生成频率(目前每次点击发射一发)
- 调整计分规则中的数值
- 修改各元素的颜色和尺寸
- 上一篇: Fabric.js 自由绘制椭圆 - 掘金
- 下一篇: 总结100+前端优质库,让你成为前端百事通
猜你喜欢
- 2025-03-10 创造等轴视角世界:游戏开发初心者指南
- 2025-03-10 自从买了双肩包 请个年假都有底气了!
- 2025-03-10 七步完美解决问题python爬虫极验滑动验证码问题
- 2025-03-10 安卓自定义 View 进阶:贝塞尔曲线(上)
- 2025-03-10 打造一个 Compose 版的俄罗斯方块
- 2025-03-10 Fabric.js 拖放元素进画布 - 掘金
- 2025-03-10 总结100+前端优质库,让你成为前端百事通
- 2025-03-10 Fabric.js 自由绘制椭圆 - 掘金
- 2025-03-10 PS如何精确绘制矩形并对齐
- 2025-03-10 如何在PyQt5中嵌入Matplotlib生成的图像