undefined / index.html
2gfg's picture
continue
9f1410d verified
<!DOCTYPE html>
<html lang="en" class="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SkyFlap Odyssey: Aerial Avian Adventure</title>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<script src="https://unpkg.com/feather-icons"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/3.60.0/phaser.min.js"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Poppins', sans-serif;
background: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #334155 100%);
color: #f8fafc;
overflow-x: hidden;
}
.game-container {
position: relative;
max-width: 1200px;
margin: 0 auto;
border-radius: 20px;
overflow: hidden;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
}
#gameCanvas {
display: block;
margin: 0 auto;
border: 3px solid #475569;
border-radius: 15px;
background: linear-gradient(180deg, #1e40af 0%, #3b82f6 100%);
}
.stats-overlay {
position: absolute;
top: 20px;
left: 20px;
z-index: 10;
background: rgba(15, 23, 42, 0.8);
padding: 15px;
border-radius: 12px;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
}
.score-animation {
animation: scorePop 0.6s ease-out;
}
@keyframes scorePop {
0% { transform: scale(1); }
50% { transform: scale(1.3); }
100% { transform: scale(1); }
}
.power-up-indicator {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { opacity: 1; }
50% { opacity: 0.6; }
100% { opacity: 1; }
}
.menu-transition {
transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}
.parallax-bg {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: -1;
}
.bg-layer-1 { animation: scrollBg 60s linear infinite; }
.bg-layer-2 { animation: scrollBg 40s linear infinite; }
.bg-layer-3 { animation: scrollBg 20s linear infinite; }
@keyframes scrollBg {
from { transform: translateX(0); }
to { transform: translateX(-100%); }
}
</style>
</head>
<body class="min-h-screen flex items-center justify-center p-4">
<!-- Parallax Background Elements -->
<div class="parallax-bg">
<div class="bg-layer-1 absolute inset-0 opacity-20">
<div class="flex">
<div class="w-64 h-64 bg-gradient-to-br from-blue-400 to-purple-500 rounded-full blur-3xl"></div>
<div class="w-48 h-48 bg-gradient-to-br from-green-400 to-blue-500 rounded-full blur-2xl ml-32"></div>
</div>
</div>
<div class="bg-layer-2 absolute inset-0 opacity-15">
<div class="flex mt-32">
<div class="w-32 h-32 bg-gradient-to-br from-yellow-400 to-red-500 rounded-full blur-2xl"></div>
<div class="w-56 h-56 bg-gradient-to-br from-pink-400 to-red-500 rounded-full blur-3xl ml-64"></div>
</div>
</div>
<div class="bg-layer-3 absolute inset-0 opacity-10">
<div class="flex mt-64">
<div class="w-40 h-40 bg-gradient-to-br from-purple-400 to-pink-500 rounded-full blur-2xl ml-96"></div>
</div>
</div>
</div>
<div class="game-container">
<!-- Game Stats Overlay -->
<div class="stats-overlay">
<div class="flex items-center space-x-6">
<div class="text-center">
<div class="text-sm text-gray-400">SCORE</div>
<div id="currentScore" class="text-2xl font-bold text-white score-animation">0</div>
</div>
<div class="text-center">
<div class="text-sm text-gray-400">BEST</div>
<div id="bestScore" class="text-xl font-semibold text-yellow-400">0</div>
</div>
<div id="powerUpDisplay" class="hidden">
<div class="text-center">
<div class="text-sm text-gray-400">POWER</div>
<div class="text-lg font-semibold text-green-400 power-up-indicator">ACTIVE</div>
</div>
</div>
</div>
</div>
<!-- Game Canvas -->
<div id="gameCanvas" class="w-full h-auto"></div>
<!-- Start Menu -->
<div id="startMenu" class="absolute inset-0 flex flex-col items-center justify-center bg-gradient-to-br from-black/80 to-blue-900/80 backdrop-blur-sm">
<div class="text-center space-y-6">
<h1 class="text-5xl font-bold bg-gradient-to-r from-blue-400 to-purple-500 bg-clip-text text-transparent">
SkyFlap Odyssey
</h1>
<p class="text-xl text-gray-300">Aerial Avian Adventure</p>
<div class="space-y-4 mt-8">
<button onclick="startGame()" class="w-64 bg-gradient-to-r from-blue-500 to-purple-600 hover:from-blue-600 hover:to-purple-700 text-white font-semibold py-3 px-6 rounded-xl transition-all duration-300 transform hover:scale-105">
<i data-feather="play" class="inline mr-2"></i>
Start Flight
</button>
<button onclick="showSettings()" class="w-64 bg-gray-700 hover:bg-gray-600 text-white font-semibold py-3 px-6 rounded-xl transition-all duration-300">
<i data-feather="settings" class="inline mr-2"></i>
Game Settings
</button>
</div>
<div class="mt-6 text-sm text-gray-400">
<p>Tap, Click, or Press SPACE to flap</p>
<p>Gamepad supported</p>
</div>
</div>
</div>
<!-- Game Over Menu -->
<div id="gameOverMenu" class="absolute inset-0 flex flex-col items-center justify-center bg-gradient-to-br from-red-900/80 to-black/80 backdrop-blur-sm hidden">
<div class="text-center space-y-6">
<h2 class="text-4xl font-bold text-red-400">Flight Terminated</h2>
<div class="bg-black/50 p-6 rounded-2xl space-y-4">
<div class="text-2xl font-semibold">Final Score: <span id="finalScore" class="text-yellow-400">0</span></div>
<div class="text-lg">Best Score: <span id="finalBestScore" class="text-green-400">0</span></div>
<div class="space-y-3">
<button onclick="restartGame()" class="w-64 bg-gradient-to-r from-green-500 to-blue-600 hover:from-green-600 hover:to-blue-700 text-white font-semibold py-3 px-6 rounded-xl transition-all duration-300">
<i data-feather="refresh-cw" class="inline mr-2"></i>
Fly Again
</button>
<button onclick="showStartMenu()" class="w-64 bg-gray-700 hover:bg-gray-600 text-white font-semibold py-3 px-6 rounded-xl transition-all duration-300">
<i data-feather="home" class="inline mr-2"></i>
Main Menu
</button>
</div>
</div>
</div>
<!-- Settings Menu -->
<div id="settingsMenu" class="absolute inset-0 flex flex-col items-center justify-center bg-gradient-to-br from-gray-900/80 to-black/80 backdrop-blur-sm hidden">
<div class="bg-black/70 p-8 rounded-2xl max-w-md w-full space-y-6">
<h2 class="text-3xl font-bold text-center text-white">Settings</h2>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-300 mb-2">Music Volume</label>
<input type="range" min="0" max="100" value="50" class="w-full h-2 bg-gray-600 rounded-lg appearance-none cursor-pointer slider">
</div>
<div>
<label class="block text-sm font-medium text-gray-300 mb-2">SFX Volume</label>
<input type="range" min="0" max="100" value="70" class="w-full h-2 bg-gray-600 rounded-lg appearance-none cursor-pointer slider">
</div>
<div class="flex items-center justify-between">
<span class="text-sm font-medium text-gray-300">Visual Effects</span>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" checked class="sr-only peer">
<div class="w-11 h-6 bg-gray-700 peer-focus:outline-none rounded-full peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-500"></div>
</label>
</div>
</div>
<div class="flex space-x-4 pt-4">
<button onclick="saveSettings()" class="flex-1 bg-gradient-to-r from-blue-500 to-purple-600 hover:from-blue-600 hover:to-purple-700 text-white font-semibold py-2 px-4 rounded-xl transition-all duration-300">
Save
</button>
<button onclick="showStartMenu()" class="flex-1 bg-gray-700 hover:bg-gray-600 text-white font-semibold py-2 px-4 rounded-xl transition-all duration-300">
Cancel
</button>
</div>
</div>
</div>
</div>
<!-- Control Instructions -->
<div class="mt-8 text-center space-y-2">
<div class="flex justify-center space-x-8 text-sm text-gray-400">
<div class="flex items-center space-x-2">
<i data-feather="mouse-pointer"></i>
<span>Click/Tap</span>
</div>
<div class="flex items-center space-x-2">
<i data-feather="square"></i>
<span>Space Bar</span>
</div>
<div class="flex items-center space-x-2">
<i data-feather="gamepad"></i>
<span>Gamepad A</span>
</div>
</div>
</div>
<script>
// Initialize game variables
let game;
let currentScore = 0;
let bestScore = 0;
let isGameRunning = false;
// Load best score from localStorage
if (localStorage.getItem('skyflapBestScore')) {
bestScore = parseInt(localStorage.getItem('skyflapBestScore'));
document.getElementById('bestScore').textContent = bestScore;
}
// Game configuration
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'gameCanvas',
physics: {
default: 'arcade',
arcade: {
gravity: { y: 800 },
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
},
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH
}
};
function preload() {
// Load placeholder assets - in real implementation, these would be actual game assets
this.load.image('bird', 'http://static.photos/nature/64x64/1');
this.load.image('pipe', 'http://static.photos/green/128x512/2');
this.load.image('background', 'http://static.photos/blue/800x600/3');
}
function create() {
// Create background
this.add.image(400, 300, 'background');
// Create bird
this.bird = this.physics.add.sprite(100, 300, 'bird');
this.bird.setCollideWorldBounds(true);
// Create pipe group
this.pipes = this.physics.add.group();
// Input handlers
this.input.on('pointerdown', flap, this);
this.input.keyboard.on('keydown-SPACE', flap, this);
// Timer for pipe generation
this.pipeTimer = this.time.addEvent({
delay: 1500,
callback: generatePipe,
callbackScope: this,
loop: true
});
// Collision detection
this.physics.add.collider(this.bird, this.pipes, gameOver, null, this);
// Score text
this.scoreText = this.add.text(400, 50, '0', {
fontSize: '32px',
fill: '#ffffff',
stroke: '#000000',
strokeThickness: 4
}).setOrigin(0.5);
}
function update() {
if (!isGameRunning) return;
// Rotate bird based on velocity
this.bird.rotation = Phaser.Math.Clamp(this.bird.body.velocity.y * 0.01, -0.5, 0.5);
}
function flap() {
if (!isGameRunning) return;
this.bird.setVelocityY(-300);
}
function generatePipe() {
if (!isGameRunning) return;
const gap = 200;
const pipeX = 800;
const pipeY = Phaser.Math.Between(100, 500);
// Top pipe
const topPipe = this.pipes.create(pipeX, pipeY - gap / 2, 'pipe');
topPipe.setScale(1, -1);
topPipe.setVelocityX(-200);
// Bottom pipe
const bottomPipe = this.pipes.create(pipeX, pipeY + gap / 2, 'pipe');
bottomPipe.setVelocityX(-200);
// Remove pipes when they go off screen
this.time.delayedCall(4000, () => {
topPipe.destroy();
bottomPipe.destroy();
});
// Increment score when passing pipes
this.time.delayedCall(2000, () => {
currentScore++;
updateScore();
});
}
function gameOver() {
isGameRunning = false;
// Update best score
if (currentScore > bestScore) {
bestScore = currentScore;
localStorage.setItem('skyflapBestScore', bestScore);
// Show game over menu
document.getElementById('finalScore').textContent = currentScore;
document.getElementById('finalBestScore').textContent = bestScore;
document.getElementById('gameOverMenu').classList.remove('hidden');
}
function updateScore() {
document.getElementById('currentScore').textContent = currentScore;
document.getElementById('bestScore').textContent = bestScore;
// Add animation
document.getElementById('currentScore').classList.add('score-animation');
setTimeout(() => {
document.getElementById('currentScore').classList.remove('score-animation');
}, 600);
}
// UI Control Functions
function startGame() {
document.getElementById('startMenu').classList.add('hidden');
document.getElementById('gameOverMenu').classList.add('hidden');
isGameRunning = true;
currentScore = 0;
updateScore();
// Initialize game if not already created
if (!game) {
game = new Phaser.Game(config);
} else {
// Reset game state
game.scene.restart();
}
}
function restartGame() {
document.getElementById('gameOverMenu').classList.add('hidden');
isGameRunning = true;
currentScore = 0;
updateScore();
game.scene.restart();
}
function showStartMenu() {
document.getElementById('startMenu').classList.remove('hidden');
document.getElementById('settingsMenu').classList.add('hidden');
document.getElementById('gameOverMenu').classList.add('hidden');
isGameRunning = false;
}
function showSettings() {
document.getElementById('startMenu').classList.add('hidden');
document.getElementById('settingsMenu').classList.remove('hidden');
}
function saveSettings() {
// Save settings logic would go here
showStartMenu();
}
// Gamepad support
window.addEventListener("gamepadconnected", (e) => {
console.log("Gamepad connected:", e.gamepad.id);
});
window.addEventListener("gamepaddisconnected", (e) => {
console.log("Gamepad disconnected:", e.gamepad.id);
});
// Initialize Feather Icons
document.addEventListener('DOMContentLoaded', function() {
feather.replace();
});
// Responsive adjustments
function handleResize() {
const container = document.querySelector('.game-container');
const canvas = document.getElementById('gameCanvas');
if (window.innerWidth < 768) {
container.style.maxWidth = '100%';
if (game) {
game.scale.setGameSize(400, 300);
}
} else {
container.style.maxWidth = '1200px';
if (game) {
game.scale.setGameSize(800, 600);
}
}
}
window.addEventListener('resize', handleResize);
handleResize();
</script>
</body>
</html>