mycosoftgame / index.html
mycosoft's picture
undefined - Initial Deployment
5b3a2de verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cosmic Defender - Space Shooter Game</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
body {
font-family: 'Press Start 2P', cursive;
overflow: hidden;
background: linear-gradient(135deg, #0f0c29, #302b63, #24243e);
}
#gameCanvas {
background-color: #000;
border-radius: 8px;
box-shadow: 0 0 30px rgba(0, 255, 255, 0.3);
}
.particle {
position: absolute;
width: 2px;
height: 2px;
background-color: white;
border-radius: 50%;
pointer-events: none;
}
.explosion {
position: absolute;
width: 30px;
height: 30px;
background: radial-gradient(circle, rgba(255,255,255,1) 0%, rgba(255,215,0,1) 30%, rgba(255,69,0,1) 70%, rgba(0,0,0,0) 100%);
border-radius: 50%;
pointer-events: none;
animation: explode 0.5s forwards;
}
@keyframes explode {
0% { transform: scale(0.1); opacity: 1; }
100% { transform: scale(3); opacity: 0; }
}
.powerup {
position: absolute;
width: 20px;
height: 20px;
background: radial-gradient(circle, rgba(0,255,255,1) 0%, rgba(0,100,255,1) 100%);
border-radius: 50%;
box-shadow: 0 0 10px cyan;
animation: pulse 1s infinite alternate;
}
@keyframes pulse {
0% { transform: scale(1); }
100% { transform: scale(1.2); }
}
.game-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.star {
position: absolute;
width: 2px;
height: 2px;
background-color: white;
border-radius: 50%;
animation: twinkle 2s infinite alternate;
}
@keyframes twinkle {
0% { opacity: 0.2; }
100% { opacity: 1; }
}
</style>
</head>
<body class="min-h-screen flex flex-col items-center justify-center text-white p-4">
<div class="relative w-full max-w-4xl">
<!-- Game Title -->
<h1 class="text-4xl md:text-5xl text-center mb-4 text-cyan-400 drop-shadow-lg">COSMIC DEFENDER</h1>
<!-- Game Stats -->
<div class="flex justify-between mb-4 text-sm md:text-base">
<div class="bg-black bg-opacity-50 p-2 rounded">
<span class="text-green-400">SCORE:</span> <span id="score">0</span>
</div>
<div class="bg-black bg-opacity-50 p-2 rounded">
<span class="text-red-400">LIVES:</span> <span id="lives">3</span>
</div>
<div class="bg-black bg-opacity-50 p-2 rounded">
<span class="text-yellow-400">LEVEL:</span> <span id="level">1</span>
</div>
<div class="bg-black bg-opacity-50 p-2 rounded">
<span class="text-blue-400">POWER:</span> <span id="power">NORMAL</span>
</div>
</div>
<!-- Game Canvas -->
<div class="relative">
<canvas id="gameCanvas" width="800" height="500" class="w-full h-auto border-4 border-cyan-500"></canvas>
<!-- Game Overlay (stars, particles, etc) -->
<div id="gameOverlay" class="game-overlay"></div>
<!-- Start Screen -->
<div id="startScreen" class="absolute inset-0 flex flex-col items-center justify-center bg-black bg-opacity-80">
<h2 class="text-3xl md:text-4xl mb-6 text-cyan-400">COSMIC DEFENDER</h2>
<p class="mb-8 text-center px-4">Defend Earth from alien invaders!</p>
<button id="startButton" class="bg-cyan-600 hover:bg-cyan-500 text-white font-bold py-3 px-8 rounded-full transition-all duration-300 transform hover:scale-105 pointer-events-auto">
START MISSION
</button>
<div class="mt-8 text-xs text-gray-400">
<p>CONTROLS: Arrow Keys to Move | Space to Shoot</p>
<p class="mt-2">Collect power-ups for special abilities</p>
</div>
</div>
<!-- Game Over Screen -->
<div id="gameOverScreen" class="absolute inset-0 flex flex-col items-center justify-center bg-black bg-opacity-80 hidden">
<h2 class="text-3xl md:text-4xl mb-6 text-red-400">MISSION FAILED</h2>
<p class="mb-4">Final Score: <span id="finalScore" class="text-yellow-400">0</span></p>
<p class="mb-8">Level Reached: <span id="finalLevel" class="text-blue-400">1</span></p>
<button id="restartButton" class="bg-red-600 hover:bg-red-500 text-white font-bold py-3 px-8 rounded-full transition-all duration-300 transform hover:scale-105 pointer-events-auto">
TRY AGAIN
</button>
</div>
<!-- Level Complete Screen -->
<div id="levelCompleteScreen" class="absolute inset-0 flex flex-col items-center justify-center bg-black bg-opacity-80 hidden">
<h2 class="text-3xl md:text-4xl mb-6 text-green-400">LEVEL COMPLETE!</h2>
<p class="mb-8 text-xl">Preparing for level <span id="nextLevel" class="text-yellow-400">2</span></p>
<div class="w-3/4 h-2 bg-gray-800 rounded-full overflow-hidden">
<div id="levelProgress" class="h-full bg-green-500 rounded-full" style="width: 0%"></div>
</div>
</div>
</div>
<!-- Mobile Controls (visible only on mobile) -->
<div id="mobileControls" class="mt-4 w-full max-w-md hidden">
<div class="grid grid-cols-3 gap-2">
<button id="leftBtn" class="bg-gray-800 hover:bg-gray-700 text-white p-4 rounded-lg col-start-1"></button>
<button id="shootBtn" class="bg-red-600 hover:bg-red-500 text-white p-4 rounded-lg col-start-2">FIRE</button>
<button id="rightBtn" class="bg-gray-800 hover:bg-gray-700 text-white p-4 rounded-lg col-start-3"></button>
</div>
</div>
</div>
<!-- Audio Elements -->
<audio id="shootSound" src="https://assets.mixkit.co/sfx/preview/mixkit-laser-weapon-shot-1681.mp3" preload="auto"></audio>
<audio id="explosionSound" src="https://assets.mixkit.co/sfx/preview/mixkit-explosion-impact-1684.mp3" preload="auto"></audio>
<audio id="powerupSound" src="https://assets.mixkit.co/sfx/preview/mixkit-achievement-bell-600.mp3" preload="auto"></audio>
<audio id="gameOverSound" src="https://assets.mixkit.co/sfx/preview/mixkit-retro-arcade-lose-2027.mp3" preload="auto"></audio>
<audio id="levelCompleteSound" src="https://assets.mixkit.co/sfx/preview/mixkit-unlock-game-notification-253.mp3" preload="auto"></audio>
<script>
// Game variables
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const startScreen = document.getElementById('startScreen');
const gameOverScreen = document.getElementById('gameOverScreen');
const levelCompleteScreen = document.getElementById('levelCompleteScreen');
const startButton = document.getElementById('startButton');
const restartButton = document.getElementById('restartButton');
const scoreElement = document.getElementById('score');
const livesElement = document.getElementById('lives');
const levelElement = document.getElementById('level');
const powerElement = document.getElementById('power');
const finalScoreElement = document.getElementById('finalScore');
const finalLevelElement = document.getElementById('finalLevel');
const nextLevelElement = document.getElementById('nextLevel');
const levelProgressElement = document.getElementById('levelProgress');
const mobileControls = document.getElementById('mobileControls');
const gameOverlay = document.getElementById('gameOverlay');
// Audio elements
const shootSound = document.getElementById('shootSound');
const explosionSound = document.getElementById('explosionSound');
const powerupSound = document.getElementById('powerupSound');
const gameOverSound = document.getElementById('gameOverSound');
const levelCompleteSound = document.getElementById('levelCompleteSound');
// Game state
let gameRunning = false;
let score = 0;
let lives = 3;
let level = 1;
let powerMode = 'NORMAL';
let powerTimer = 0;
let enemySpeed = 1;
let enemySpawnRate = 120;
let powerupSpawnRate = 500;
let frameCount = 0;
// Player
const player = {
x: canvas.width / 2 - 25,
y: canvas.height - 60,
width: 50,
height: 30,
speed: 5,
color: '#00FFFF',
bullets: [],
lastShot: 0,
shootDelay: 300,
isShooting: false
};
// Enemies
let enemies = [];
// Powerups
let powerups = [];
// Explosions
let explosions = [];
// Stars for background
let stars = [];
// Create stars
function createStars() {
stars = [];
for (let i = 0; i < 100; i++) {
stars.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
size: Math.random() * 2 + 1,
opacity: Math.random()
});
}
}
// Draw stars
function drawStars() {
ctx.save();
stars.forEach(star => {
ctx.globalAlpha = star.opacity;
ctx.fillStyle = 'white';
ctx.fillRect(star.x, star.y, star.size, star.size);
});
ctx.restore();
}
// Create a star DOM element for the overlay
function createStarElement() {
const star = document.createElement('div');
star.className = 'star';
star.style.left = `${Math.random() * 100}%`;
star.style.top = `${Math.random() * 100}%`;
star.style.animationDelay = `${Math.random() * 2}s`;
star.style.width = `${Math.random() * 3 + 1}px`;
star.style.height = star.style.width;
gameOverlay.appendChild(star);
// Remove star after animation completes
setTimeout(() => {
star.remove();
}, 2000);
}
// Create star elements for overlay
function createStarElements() {
setInterval(createStarElement, 100);
}
// Player bullet
function createBullet() {
const now = Date.now();
if (now - player.lastShot < player.shootDelay) return;
player.bullets.push({
x: player.x + player.width / 2 - 2.5,
y: player.y,
width: 5,
height: 15,
speed: 7,
color: '#00FF00'
});
player.lastShot = now;
// Play shoot sound
shootSound.currentTime = 0;
shootSound.play();
}
// Enemy
function createEnemy() {
const size = Math.random() * 30 + 20;
enemies.push({
x: Math.random() * (canvas.width - size),
y: -size,
width: size,
height: size,
speed: Math.random() * enemySpeed + 1,
color: `hsl(${Math.random() * 60 + 300}, 100%, 50%)`,
health: Math.floor(size / 10)
});
}
// Powerup
function createPowerup() {
powerups.push({
x: Math.random() * (canvas.width - 20),
y: -20,
width: 20,
height: 20,
speed: 2,
type: Math.random() > 0.5 ? 'rapid' : 'shield'
});
}
// Explosion
function createExplosion(x, y) {
explosions.push({
x: x,
y: y,
radius: 5,
maxRadius: 30,
alpha: 1
});
// Play explosion sound
explosionSound.currentTime = 0;
explosionSound.play();
}
// Draw player
function drawPlayer() {
ctx.fillStyle = player.color;
// Ship body
ctx.beginPath();
ctx.moveTo(player.x + player.width / 2, player.y);
ctx.lineTo(player.x + player.width, player.y + player.height);
ctx.lineTo(player.x, player.y + player.height);
ctx.closePath();
ctx.fill();
// Ship cockpit
ctx.fillStyle = '#FFFFFF';
ctx.beginPath();
ctx.arc(player.x + player.width / 2, player.y + player.height / 2, 5, 0, Math.PI * 2);
ctx.fill();
// Draw shield if in power mode
if (powerMode === 'SHIELD') {
ctx.strokeStyle = 'rgba(0, 255, 255, 0.5)';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(player.x + player.width / 2, player.y + player.height / 2, 35, 0, Math.PI * 2);
ctx.stroke();
}
}
// Draw bullets
function drawBullets() {
player.bullets.forEach(bullet => {
ctx.fillStyle = bullet.color;
ctx.fillRect(bullet.x, bullet.y, bullet.width, bullet.height);
});
}
// Draw enemies
function drawEnemies() {
enemies.forEach(enemy => {
ctx.fillStyle = enemy.color;
ctx.beginPath();
ctx.arc(enemy.x + enemy.width / 2, enemy.y + enemy.height / 2, enemy.width / 2, 0, Math.PI * 2);
ctx.fill();
// Draw health indicator
if (enemy.health > 1) {
ctx.fillStyle = 'white';
ctx.font = '10px Arial';
ctx.textAlign = 'center';
ctx.fillText(enemy.health, enemy.x + enemy.width / 2, enemy.y + enemy.height / 2 + 3);
}
});
}
// Draw powerups
function drawPowerups() {
powerups.forEach(powerup => {
ctx.fillStyle = powerup.type === 'rapid' ? '#FF00FF' : '#00FFFF';
ctx.beginPath();
ctx.arc(powerup.x + powerup.width / 2, powerup.y + powerup.height / 2, powerup.width / 2, 0, Math.PI * 2);
ctx.fill();
// Draw icon
ctx.fillStyle = 'white';
ctx.font = '12px Arial';
ctx.textAlign = 'center';
ctx.fillText(powerup.type === 'rapid' ? 'R' : 'S', powerup.x + powerup.width / 2, powerup.y + powerup.height / 2 + 4);
});
}
// Draw explosions
function drawExplosions() {
explosions.forEach((explosion, index) => {
if (explosion.radius < explosion.maxRadius) {
explosion.radius += 2;
explosion.alpha -= 0.02;
} else {
explosions.splice(index, 1);
return;
}
const gradient = ctx.createRadialGradient(
explosion.x, explosion.y, 0,
explosion.x, explosion.y, explosion.radius
);
gradient.addColorStop(0, 'rgba(255, 255, 255, ' + explosion.alpha + ')');
gradient.addColorStop(0.3, 'rgba(255, 215, 0, ' + explosion.alpha + ')');
gradient.addColorStop(0.6, 'rgba(255, 69, 0, ' + explosion.alpha * 0.7 + ')');
gradient.addColorStop(1, 'rgba(0, 0, 0, 0)');
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(explosion.x, explosion.y, explosion.radius, 0, Math.PI * 2);
ctx.fill();
});
}
// Update bullets
function updateBullets() {
player.bullets.forEach((bullet, index) => {
bullet.y -= bullet.speed;
// Remove bullets that are off screen
if (bullet.y + bullet.height < 0) {
player.bullets.splice(index, 1);
}
});
}
// Update enemies
function updateEnemies() {
enemies.forEach((enemy, index) => {
enemy.y += enemy.speed;
// Remove enemies that are off screen
if (enemy.y > canvas.height) {
enemies.splice(index, 1);
loseLife();
}
});
}
// Update powerups
function updatePowerups() {
powerups.forEach((powerup, index) => {
powerup.y += powerup.speed;
// Remove powerups that are off screen
if (powerup.y > canvas.height) {
powerups.splice(index, 1);
}
});
}
// Check collisions
function checkCollisions() {
// Bullet-enemy collisions
player.bullets.forEach((bullet, bulletIndex) => {
enemies.forEach((enemy, enemyIndex) => {
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
) {
// Hit enemy
enemy.health--;
// Remove bullet
player.bullets.splice(bulletIndex, 1);
// Create explosion
createExplosion(enemy.x + enemy.width / 2, enemy.y + enemy.height / 2);
// If enemy health is 0, remove it and add score
if (enemy.health <= 0) {
enemies.splice(enemyIndex, 1);
addScore(Math.floor(enemy.width));
}
return;
}
});
});
// Player-enemy collisions
enemies.forEach((enemy, index) => {
if (
player.x < enemy.x + enemy.width &&
player.x + player.width > enemy.x &&
player.y < enemy.y + enemy.height &&
player.y + player.height > enemy.y
) {
// Only lose life if not in SHIELD mode
if (powerMode !== 'SHIELD') {
enemies.splice(index, 1);
loseLife();
createExplosion(enemy.x + enemy.width / 2, enemy.y + enemy.height / 2);
} else {
// Just destroy the enemy if in SHIELD mode
enemies.splice(index, 1);
addScore(Math.floor(enemy.width));
createExplosion(enemy.x + enemy.width / 2, enemy.y + enemy.height / 2);
}
}
});
// Player-powerup collisions
powerups.forEach((powerup, index) => {
if (
player.x < powerup.x + powerup.width &&
player.x + player.width > powerup.x &&
player.y < powerup.y + powerup.height &&
player.y + player.height > powerup.y
) {
// Apply powerup
if (powerup.type === 'rapid') {
activatePowerMode('RAPID');
} else {
activatePowerMode('SHIELD');
}
// Remove powerup
powerups.splice(index, 1);
// Play powerup sound
powerupSound.currentTime = 0;
powerupSound.play();
}
});
}
// Add score
function addScore(points) {
score += points;
scoreElement.textContent = score;
}
// Lose life
function loseLife() {
lives--;
livesElement.textContent = lives;
if (lives <= 0) {
gameOver();
} else {
// Reset player position
player.x = canvas.width / 2 - 25;
player.y = canvas.height - 60;
}
}
// Activate power mode
function activatePowerMode(type) {
powerMode = type;
powerTimer = 500; // 5 seconds at 60fps
if (type === 'RAPID') {
player.shootDelay = 100;
powerElement.textContent = 'RAPID FIRE';
powerElement.className = 'text-purple-400';
} else {
powerElement.textContent = 'SHIELD';
powerElement.className = 'text-cyan-400';
}
}
// Update power mode timer
function updatePowerMode() {
if (powerTimer > 0) {
powerTimer--;
if (powerTimer === 0) {
powerMode = 'NORMAL';
player.shootDelay = 300;
powerElement.textContent = 'NORMAL';
powerElement.className = 'text-white';
}
}
}
// Level up
function levelUp() {
level++;
levelElement.textContent = level;
// Increase difficulty
enemySpeed += 0.2;
if (enemySpawnRate > 30) enemySpawnRate -= 10;
// Show level complete screen
showLevelComplete();
}
// Show level complete screen
function showLevelComplete() {
gameRunning = false;
levelCompleteScreen.classList.remove('hidden');
nextLevelElement.textContent = level;
// Play level complete sound
levelCompleteSound.currentTime = 0;
levelCompleteSound.play();
// Animate progress bar
let progress = 0;
const interval = setInterval(() => {
progress += 2;
levelProgressElement.style.width = `${progress}%`;
if (progress >= 100) {
clearInterval(interval);
setTimeout(() => {
levelCompleteScreen.classList.add('hidden');
gameRunning = true;
}, 500);
}
}, 50);
}
// Game over
function gameOver() {
gameRunning = false;
gameOverScreen.classList.remove('hidden');
finalScoreElement.textContent = score;
finalLevelElement.textContent = level - 1;
// Play game over sound
gameOverSound.currentTime = 0;
gameOverSound.play();
}
// Reset game
function resetGame() {
score = 0;
lives = 3;
level = 1;
powerMode = 'NORMAL';
powerTimer = 0;
enemySpeed = 1;
enemySpawnRate = 120;
player.x = canvas.width / 2 - 25;
player.y = canvas.height - 60;
player.bullets = [];
player.lastShot = 0;
player.shootDelay = 300;
enemies = [];
powerups = [];
explosions = [];
scoreElement.textContent = score;
livesElement.textContent = lives;
levelElement.textContent = level;
powerElement.textContent = powerMode;
powerElement.className = 'text-white';
gameOverScreen.classList.add('hidden');
startScreen.classList.add('hidden');
gameRunning = true;
}
// Game loop
function gameLoop() {
if (!gameRunning) return;
// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw background
drawStars();
// Spawn enemies
if (frameCount % enemySpawnRate === 0) {
createEnemy();
}
// Spawn powerups
if (frameCount % powerupSpawnRate === 0) {
createPowerup();
}
// Auto-shoot if in rapid fire mode and player is shooting
if (powerMode === 'RAPID' && player.isShooting && frameCount % 10 === 0) {
createBullet();
}
// Update game objects
updateBullets();
updateEnemies();
updatePowerups();
updatePowerMode();
checkCollisions();
// Draw game objects
drawBullets();
drawEnemies();
drawPowerups();
drawExplosions();
drawPlayer();
// Check for level up (every 10 enemies destroyed)
if (score >= level * 1000) {
levelUp();
}
frameCount++;
requestAnimationFrame(gameLoop);
}
// Event listeners
startButton.addEventListener('click', () => {
startScreen.classList.add('hidden');
resetGame();
gameLoop();
});
restartButton.addEventListener('click', resetGame);
// Keyboard controls
document.addEventListener('keydown', (e) => {
if (!gameRunning) return;
switch (e.key) {
case 'ArrowLeft':
player.x = Math.max(0, player.x - player.speed);
break;
case 'ArrowRight':
player.x = Math.min(canvas.width - player.width, player.x + player.speed);
break;
case ' ':
player.isShooting = true;
createBullet();
break;
}
});
document.addEventListener('keyup', (e) => {
if (e.key === ' ') {
player.isShooting = false;
}
});
// Touch controls for mobile
let touchStartX = 0;
let touchEndX = 0;
canvas.addEventListener('touchstart', (e) => {
e.preventDefault();
touchStartX = e.touches[0].clientX;
player.isShooting = true;
createBullet();
});
canvas.addEventListener('touchmove', (e) => {
e.preventDefault();
touchEndX = e.touches[0].clientX;
if (touchEndX < touchStartX - 10) {
// Swipe left
player.x = Math.max(0, player.x - player.speed * 2);
touchStartX = touchEndX;
} else if (touchEndX > touchStartX + 10) {
// Swipe right
player.x = Math.min(canvas.width - player.width, player.x + player.speed * 2);
touchStartX = touchEndX;
}
});
canvas.addEventListener('touchend', (e) => {
e.preventDefault();
player.isShooting = false;
});
// Mobile button controls
leftBtn.addEventListener('touchstart', () => {
player.x = Math.max(0, player.x - player.speed);
});
rightBtn.addEventListener('touchstart', () => {
player.x = Math.min(canvas.width - player.width, player.x + player.speed);
});
shootBtn.addEventListener('touchstart', () => {
player.isShooting = true;
createBullet();
});
shootBtn.addEventListener('touchend', () => {
player.isShooting = false;
});
// Check if mobile device
function isMobile() {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
}
// Initialize game
function init() {
createStars();
createStarElements();
if (isMobile()) {
mobileControls.classList.remove('hidden');
}
}
// Start the game
init();
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=mycosoft/mycosoftgame" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>