利用ai写的坦克大战源码
本帖最后由 bdcpc 于 2024-8-31 22:40 编辑<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>坦克大战小游戏</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background: #f0f0f0;
}
canvas {
display: block;
margin: 0 auto;
background: #eee;
border: 2px solid #333;
}
.controls {
text-align: center;
margin: 10px;
}
.controls p {
margin: 0;
padding: 5px;
font-size: 18px;
}
.controls button {
padding: 10px;
font-size: 16px;
margin: 5px;
cursor: pointer;
}
.controls #nextLevelBtn {
display: none;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
transition: background-color 0.3s;
}
.controls #nextLevelBtn:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<canvas id="gameCanvas" width="800" height="600"></canvas>
<div class="controls">
<p>操作说明:</p>
<p>↑:向上移动</p>
<p>↓:向下移动</p>
<p>←:向左移动</p>
<p>→:向右移动</p>
<p>空格键:开火</p>
<p>游戏说明:消灭所有敌方坦克,完成关卡。</p>
<button id="nextLevelBtn">下一关</button>
</div>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const tankSize = 30;
const bulletSize = 5;
let tanks = [];
let bullets = [];
let level = 1;
let keys = {};
let shootingCooldown = 500; // milliseconds
let lastShotTime = 0;
let enemyFireCooldown = 2000; // milliseconds
let lastEnemyShotTime = 0;
let isGameOver = false; // 游戏状态标志
let gameInterval;
// 加载坦克图片
const playerTankImg = new Image();
playerTankImg.src = 'playerTank.png'; // 请将此路径替换为实际的玩家坦克图片路径
const enemyTankImg = new Image();
enemyTankImg.src = 'enemyTank.png'; // 请将此路径替换为实际的敌方坦克图片路径
// 玩家坦克初始化
let playerTank = {
x: canvas.width / 2,
y: canvas.height / 2,
direction: 'up',
image: playerTankImg
};
let playerSpeed = 3;
let bulletSpeed = 5;
let enemySpeed = 2;
function Tank(x, y, image) {
this.x = x;
this.y = y;
this.image = image;
this.direction = 'down';
this.cooldown = 2000;
this.lastShot = 0;
}
function Bullet(x, y, direction, color) {
this.x = x;
this.y = y;
this.direction = direction;
this.color = color;
}
function drawTank(tank) {
ctx.save();
ctx.translate(tank.x + tankSize / 2, tank.y + tankSize / 2); // 将画布原点移到坦克中心
switch (tank.direction) {
case 'up':
ctx.rotate(0);
break;
case 'down':
ctx.rotate(Math.PI);
break;
case 'left':
ctx.rotate(-Math.PI / 2);
break;
case 'right':
ctx.rotate(Math.PI / 2);
break;
}
ctx.drawImage(tank.image, -tankSize / 2, -tankSize / 2, tankSize, tankSize);
ctx.restore();
}
function drawBullet(bullet) {
ctx.fillStyle = bullet.color;
ctx.fillRect(bullet.x, bullet.y, bulletSize, bulletSize);
}
function movePlayerTank() {
if (keys['ArrowUp']) {
playerTank.y -= playerSpeed;
playerTank.direction = 'up';
}
if (keys['ArrowDown']) {
playerTank.y += playerSpeed;
playerTank.direction = 'down';
}
if (keys['ArrowLeft']) {
playerTank.x -= playerSpeed;
playerTank.direction = 'left';
}
if (keys['ArrowRight']) {
playerTank.x += playerSpeed;
playerTank.direction = 'right';
}
// 确保坦克在画布范围内
playerTank.x = Math.max(0, Math.min(canvas.width - tankSize, playerTank.x));
playerTank.y = Math.max(0, Math.min(canvas.height - tankSize, playerTank.y));
}
function moveBullets() {
bullets = bullets.filter(bullet => {
switch (bullet.direction) {
case 'up':
bullet.y -= bulletSpeed;
break;
case 'down':
bullet.y += bulletSpeed;
break;
case 'left':
bullet.x -= bulletSpeed;
break;
case 'right':
bullet.x += bulletSpeed;
break;
}
return bullet.x >= 0 && bullet.x <= canvas.width &&
bullet.y >= 0 && bullet.y <= canvas.height;
});
}
function moveEnemyTanks() {
tanks.forEach(tank => {
// Randomly change direction
const directions = ['up', 'down', 'left', 'right'];
if (Math.random() < 0.05) {
tank.direction = directions;
}
// Move based on direction
switch (tank.direction) {
case 'up':
tank.y -= enemySpeed;
break;
case 'down':
tank.y += enemySpeed;
break;
case 'left':
tank.x -= enemySpeed;
break;
case 'right':
tank.x += enemySpeed;
break;
}
// Ensure tanks stay within the canvas bounds
tank.x = Math.max(0, Math.min(canvas.width - tankSize, tank.x));
tank.y = Math.max(0, Math.min(canvas.height - tankSize, tank.y));
});
}
function fireBullet(tank) {
const now = Date.now();
if (now - lastShotTime < shootingCooldown) return;
let bulletX = tank.x;
let bulletY = tank.y;
// 根据方向调整子弹的初始位置
switch (tank.direction) {
case 'up':
bulletX += tankSize / 2 - bulletSize / 2;
bulletY -= bulletSize;
break;
case 'down':
bulletX += tankSize / 2 - bulletSize / 2;
bulletY += tankSize;
break;
case 'left':
bulletX -= bulletSize;
bulletY += tankSize / 2 - bulletSize / 2;
break;
case 'right':
bulletX += tankSize;
bulletY += tankSize / 2 - bulletSize / 2;
break;
}
const bullet = new Bullet(bulletX, bulletY, tank.direction, 'red');
bullets.push(bullet);
lastShotTime = now;
}
function enemyFire() {
const now = Date.now();
tanks.forEach(tank => {
if (now - tank.lastShot > tank.cooldown) {
const bullet = new Bullet(tank.x + tankSize / 2 - bulletSize / 2,
tank.y + tankSize / 2 - bulletSize / 2,
tank.direction, 'green');
bullets.push(bullet);
tank.lastShot = now;
}
});
lastEnemyShotTime = now;
}
function checkCollision() {
bullets.forEach(bullet => {
if (bullet.color === 'red') {
tanks.forEach(tank => {
if (bullet.x < tank.x + tankSize &&
bullet.x + bulletSize > tank.x &&
bullet.y < tank.y + tankSize &&
bullet.y + bulletSize > tank.y) {
// Remove tank and bullet
tanks = tanks.filter(t => t !== tank);
bullets = bullets.filter(b => b !== bullet);
if (tanks.length === 0) {
document.getElementById('nextLevelBtn').style.display = 'block';
}
}
});
} else if (bullet.color === 'green') {
if (bullet.x < playerTank.x + tankSize &&
bullet.x + bulletSize > playerTank.x &&
bullet.y < playerTank.y + tankSize &&
bullet.y + bulletSize > playerTank.y) {
// 游戏结束
if (!isGameOver) {
isGameOver = true; // 设置游戏结束标志
clearInterval(gameInterval); // 停止游戏循环
alert('游戏结束!');
document.location.reload();
}
}
}
});
}
function update() {
if (isGameOver) return; // 如果游戏结束,停止更新
ctx.clearRect(0, 0, canvas.width, canvas.height);
movePlayerTank();
moveBullets();
moveEnemyTanks();
enemyFire();
checkCollision();
drawTank(playerTank);
tanks.forEach(tank => drawTank(tank));
bullets.forEach(bullet => drawBullet(bullet));
}
function setupGame() {
playerTank = {
x: canvas.width / 2,
y: canvas.height / 2,
direction: 'up',
image: playerTankImg
};
tanks = [];
bullets = [];
isGameOver = false; // 重置游戏状态标志
for (let i = 0; i < level + 1; i++) {
tanks.push(new Tank(Math.random() * (canvas.width - tankSize),
Math.random() * (canvas.height - tankSize),
enemyTankImg));
}
document.getElementById('nextLevelBtn').style.display = 'none';
gameInterval = setInterval(update, 1000 / 60); // 重新启动游戏循环
update(); // 立即更新一次以初始化游戏画面
}
function nextLevel() {
level++;
setupGame();
}
document.addEventListener('keydown', (e) => {
if (!isGameOver) {
keys = true;
if (e.code === 'Space') fireBullet(playerTank);
}
});
document.addEventListener('keyup', (e) => {
if (!isGameOver) {
keys = false;
}
});
setupGame();
</script>
</body>
</html>
展示地址:aHR0cHM6Ly93d3cuc3J6eGtqLmNvbS9nYW1lLzE3Lw== 地址被加密了吗{:1_900:} Base64 加密:aHR0cHM6Ly93d3cuc3J6eGtqLmNvbS9nYW1lLzE4Lw== 地址看不懂,能告诉我怎么解密地址吗,用什么工具 俄罗斯方块? 打怪升级呢? 解密出来时俄罗斯方块啊?? 若白 发表于 2024-8-31 22:38
解密出来时俄罗斯方块啊??
搞错了,把后面的/18/改成17就是了
bdcpc 发表于 2024-8-31 22:40
搞错了,把后面的/18/改成17就是了
还有实用小工具啊{:301_997:} 哇哦,好厉害,学习了