<!
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>長尾山雀 Fireball Game</title>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
overflow: hidden;
background-color: #87ceeb; /* Sky blue */
}
canvas {
display: block;
background: #cce7ff; /* Lighter sky blue */
margin: 0 auto;
}
#controls, #upgradeMenu {
display: flex;
justify-content: center;
gap: 20px;
margin: 10px 0;
}
button {
padding: 10px 20px;
font-size: 1.2rem;
border: none;
border-radius: 5px;
background-color: #ff6f61;
color: white;
cursor: pointer;
}
button:active {
background-color: #ff4c3f;
}
#upgradeMenu {
display: none;
}
</style>
</head>
<body>
<div id="controls">
<button id="moveLeft">← Left</button>
🔥
<button id="moveRight">→ Right</button>
<button id="shoot"> Fireball</button>
</div>
<div id="upgradeMenu">
<button id="upgradeSize">Increase Fireball Size</button>
<button id="upgradeShield">Add Fire Shield</button>
<button id="upgradeBounce">Fireball Bounce</button>
<button id="upgradePierce">Fireball Pierce</button>
</div>
<canvas id="gameCanvas"></canvas>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Game variables
const bird = {
x: canvas.width / 2,
y: canvas.height - 150,
width: 50,
height: 50,
bodyColor: 'white',
eyeColor: 'black',
beakColor: 'orange',
speed: 5,
shield: false,
};
const enemies = [];
const fireballs = [];
let boss = null;
let score = 0;
let level = 1;
let fireballSize = 10;
let fireballSpeed = 8;
let fireballCount = 1;
let fireballBounce = false;
let fireballPierce = false;
let enemySpawnInterval = 1000;
let isBossLevel = false;
// Utility functions
function drawBird() {
ctx.fillStyle = bird.bodyColor;
ctx.fillRect(bird.x, bird.y, bird.width, bird.height);
// Draw eyes
ctx.fillStyle = bird.eyeColor;
ctx.beginPath();
ctx.arc(bird.x + 15, bird.y + 15, 5, 0, Math.PI * 2);
ctx.arc(bird.x + 35, bird.y + 15, 5, 0, Math.PI * 2);
ctx.fill();
// Draw beak
ctx.fillStyle = bird.beakColor;
ctx.beginPath();
ctx.moveTo(bird.x + 25, bird.y + 25);
ctx.lineTo(bird.x + 20, bird.y + 35);
ctx.lineTo(bird.x + 30, bird.y + 35);
ctx.closePath();
ctx.fill();
// Draw shield if active
if (bird.shield) {
ctx.strokeStyle = 'orange';
ctx.lineWidth = 5;
ctx.beginPath();
ctx.arc(bird.x + bird.width / 2, bird.y + bird.height / 2, 40, 0, Math.PI * 2);
ctx.stroke();
}
}
function drawEmoji(x, y, size, emoji) {
ctx.font = `${size}px Arial`;
ctx.fillText(emoji, x, y);
}
function spawnEnemy() {
const size = 40;
const x = Math.random() * (canvas.width - size);
const color = `hsl(${level * 36}, 70%, 50%)`; // Different colors for each level
enemies.push({
x: x,
y: -size,
size: size,
speed: Math.random() * 2 + level,
color: color,
hitsNeeded: 1,
});
}
function spawnBoss() {
boss = {
x: canvas.width / 2 - 100,
y: 50,
size: 200,
speed: 1,
color: 'purple',
hitsNeeded: level * 5, // Boss gets stronger with each level
};
}
function moveEnemies() {
enemies.forEach((enemy, index) => {
enemy.y += enemy.speed;
if (enemy.y > canvas.height) {
enemies.splice(index, 1);
}
});
}
function moveFireballs() {
fireballs.forEach((fireball, index) => {
fireball.y -= fireball.speed;
// Bounce off walls if bounce is enabled
if (fireballBounce) {
if (fireball.x <= 0 || fireball.x + fireball.width >= canvas.width) {
fireball.dx *= -1;
}
fireball.x += fireball.dx;
}
if (fireball.y < 0) {
fireballs.splice(index, 1);
}
});
}
function detectCollisions() {
fireballs.forEach((fireball, fIndex) => {
enemies.forEach((enemy, eIndex) => {
if (
fireball.x < enemy.x + enemy.size &&
fireball.x + fireball.width > enemy.x &&
fireball.y < enemy.y + enemy.size &&
fireball.y + fireball.height > enemy.y
){
if (!fireballPierce) {
fireballs.splice(fIndex, 1);
}
enemy.hitsNeeded -= 1;
if (enemy.hitsNeeded <= 0) {
enemies.splice(eIndex, 1);
score += 10;
}
}
});
if (boss && fireball.y < boss.y + boss.size && fireball.y + fireball.height > boss.y &&
fireball.x < boss.x + boss.size && fireball.x + fireball.width > boss.x) {
boss.hitsNeeded -= 1;
if (!fireballPierce) {
fireballs.splice(fIndex, 1);
}
if (boss.hitsNeeded <= 0) {
boss = null;
isBossLevel = false;
levelUp();
}
}
});
}
function levelUp() {
level++;
fireballCount++;
fireballSpeed++;
fireballSize += 5;
enemySpawnInterval = Math.max(500, enemySpawnInterval - 100); // Faster spawning
clearInterval(enemySpawner);
enemySpawner = setInterval(spawnEnemy, enemySpawnInterval);
document.getElementById('upgradeMenu').style.display = 'flex';
}
// Game loop
function gameLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBird();
if (boss) {
ctx.fillStyle = boss.color;
ctx.fillRect(boss.x, boss.y, boss.size, boss.size);
}
enemies.forEach(enemy => {
ctx.fillStyle = enemy.color;
ctx.fillRect(enemy.x, enemy.y, enemy.size, enemy.size);
});
fireballs.forEach(fireball => {
ctx.fillStyle = fireball.color;
ctx.fillRect(fireball.x, fireball.y, fireball.width, fireball.height);
});
moveEnemies();
moveFireballs();
detectCollisions();
ctx.fillStyle = 'black';
ctx.font = '30px Arial';
ctx.fillText(`Score: ${score}`, 20, 40);
ctx.fillText(`Level: ${level}`, 20, 80);
if (score >= 100 && !isBossLevel) {
isBossLevel = true;
spawnBoss();
}
requestAnimationFrame(gameLoop);
}
// Controls
document.getElementById('moveLeft').addEventListener('click', () => {
bird.x = Math.max(0, bird.x - bird.speed * 10);
});
document.getElementById('moveRight').addEventListener('click', () => {
bird.x = Math.min(canvas.width - bird.width, bird.x + bird.speed * 10);
});
document.getElementById('shoot').addEventListener('click', () => {
for (let i = 0; i < fireballCount; i++) {
fireballs.push({
x: bird.x + bird.width / 2 - fireballSize / 2 + i * 15 - (fireballCount - 1) * 7.5,
y: bird.y,
width: fireballSize,
height: fireballSize * 2,
color: 'orange',
speed: fireballSpeed,
dx: fireballBounce ? Math.random() * 4 - 2 : 0,
});
}
});
// Upgrades
document.getElementById('upgradeSize').addEventListener('click', () => {
fireballSize *= 1.5;
document.getElementById('upgradeMenu').style.display = 'none';
});
document.getElementById('upgradeShield').addEventListener('click', () => {
bird.shield = true;
document.getElementById('upgradeMenu').style.display = 'none';
});
document.getElementById('upgradeBounce').addEventListener('click', () => {
fireballBounce = true;
document.getElementById('upgradeMenu').style.display = 'none';
});
document.getElementById('upgradePierce').addEventListener('click', () => {
fireballPierce = true;
document.getElementById('upgradeMenu').style.display = 'none';
});
// Spawn enemies at intervals
let enemySpawner = setInterval(spawnEnemy, enemySpawnInterval);
// Start the game loop
gameLoop();
</script>
</body>
</html>