diff options
Diffstat (limited to 'html')
-rw-r--r-- | html/fps/game.js | 99 |
1 files changed, 81 insertions, 18 deletions
diff --git a/html/fps/game.js b/html/fps/game.js index ad4d8bf..db8cde2 100644 --- a/html/fps/game.js +++ b/html/fps/game.js @@ -28,7 +28,8 @@ const GameState = { isStarted: false, gradients: {}, // Cache for wall gradients lastGradientUpdate: 0, - particles: [] + particles: [], + damageFlash: 0 }; // Level generation using a simple maze algorithm @@ -158,20 +159,24 @@ const handlePlayerMovement = (keys) => { const rotateSpeed = 0.05; if (keys.w) { + // Move forward in the direction the player is facing GameState.player.x += Math.sin(GameState.player.angle) * moveSpeed; - GameState.player.y += Math.cos(GameState.player.angle) * moveSpeed; + GameState.player.y -= Math.cos(GameState.player.angle) * moveSpeed; } if (keys.s) { + // Move backward GameState.player.x -= Math.sin(GameState.player.angle) * moveSpeed; - GameState.player.y -= Math.cos(GameState.player.angle) * moveSpeed; + GameState.player.y += Math.cos(GameState.player.angle) * moveSpeed; } if (keys.a) { + // Strafe left GameState.player.x -= Math.cos(GameState.player.angle) * moveSpeed; - GameState.player.y += Math.sin(GameState.player.angle) * moveSpeed; + GameState.player.y -= Math.sin(GameState.player.angle) * moveSpeed; } if (keys.d) { + // Strafe right GameState.player.x += Math.cos(GameState.player.angle) * moveSpeed; - GameState.player.y -= Math.sin(GameState.player.angle) * moveSpeed; + GameState.player.y += Math.sin(GameState.player.angle) * moveSpeed; } // Add arrow key rotation @@ -194,6 +199,7 @@ const updateEnemies = () => { if (dist < 0.5) { GameState.player.health -= 10; + GameState.damageFlash = 1.0; // Trigger full flash if (GameState.player.health <= 0) { GameState.isGameOver = true; } @@ -475,6 +481,40 @@ const render = (ctx) => { ctx.fillText(`Ammo: ${GameState.player.ammo}`, 80, 80); ctx.fillText(`Score: ${GameState.player.score}`, 80, 115); + // Draw compass + const compassSize = 100; + const compassX = width/2 - compassSize/2; + const compassY = 20; + + // Draw compass background + ctx.fillStyle = 'rgba(0, 0, 0, 0.7)'; + ctx.fillRect(compassX, compassY, compassSize, 30); + ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)'; + ctx.lineWidth = 2; + ctx.strokeRect(compassX, compassY, compassSize, 30); + + // Draw compass directions + ctx.fillStyle = '#fff'; + ctx.font = '16px monospace'; + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + + // Draw N, E, S, W + ctx.fillText('N', compassX + compassSize/2, compassY + 15); + ctx.fillText('E', compassX + compassSize - 10, compassY + 15); + ctx.fillText('S', compassX + compassSize/2, compassY + 30); + ctx.fillText('W', compassX + 10, compassY + 15); + + // Draw direction indicator - use the angle directly + const angle = GameState.player.angle; + const indicatorX = compassX + compassSize/2 + Math.sin(angle) * (compassSize/2 - 10); + const indicatorY = compassY + 15 - Math.cos(angle) * (compassSize/2 - 10); + + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.arc(indicatorX, indicatorY, 4, 0, Math.PI * 2); + ctx.fill(); + // Draw sprites const drawSprite = (x, y, distance, type) => { // Calculate screen position @@ -651,11 +691,11 @@ const render = (ctx) => { ctx.arc(playerX + cellSize/2, playerY + cellSize/2, size/2 + 2, 0, Math.PI * 2); ctx.stroke(); - // Draw player triangle with direction indicator + // Draw player triangle with direction indicator - use the angle directly ctx.fillStyle = '#00f'; ctx.save(); ctx.translate(playerX + cellSize/2, playerY + cellSize/2); - ctx.rotate(GameState.player.angle); + ctx.rotate(GameState.player.angle); // Use the angle directly // Draw main triangle ctx.beginPath(); @@ -680,6 +720,22 @@ const render = (ctx) => { ctx.fill(); ctx.restore(); + + // Draw damage flash effect + if (GameState.damageFlash > 0) { + // Create a radial gradient that's transparent in the center and red at the edges + const gradient = ctx.createRadialGradient( + width/2, height/2, 0, // Inner circle (center) + width/2, height/2, Math.max(width, height)/2 // Outer circle (edges) + ); + gradient.addColorStop(0, `rgba(255, 0, 0, 0)`); // Transparent center + gradient.addColorStop(0.7, `rgba(255, 0, 0, 0)`); // Start red at 70% of radius + gradient.addColorStop(1, `rgba(255, 0, 0, ${GameState.damageFlash})`); // Full red at edges + + ctx.fillStyle = gradient; + ctx.fillRect(0, 0, width, height); + GameState.damageFlash -= 0.05; // Fade out over time + } }; // Game loop @@ -739,9 +795,10 @@ const gameLoop = (ctx) => { // Create more particles with more colors const colors = [ '#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff', - '#ff8800', '#88ff00', '#00ff88', '#0088ff', '#8800ff', '#ff0088' + '#ff8800', '#88ff00', '#00ff88', '#0088ff', '#8800ff', '#ff0088', + '#ff4444', '#44ff44', '#4444ff', '#ffff44', '#ff44ff', '#44ffff' ]; - for (let i = 0; i < 50; i++) { // More particles + for (let i = 0; i < 80; i++) { // More particles const color = colors[Math.floor(Math.random() * colors.length)]; GameState.particles.push(new Particle(hitEnemy.x, hitEnemy.y, color)); } @@ -876,9 +933,10 @@ document.addEventListener('click', (e) => { // Create more particles with more colors const colors = [ '#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff', - '#ff8800', '#88ff00', '#00ff88', '#0088ff', '#8800ff', '#ff0088' + '#ff8800', '#88ff00', '#00ff88', '#0088ff', '#8800ff', '#ff0088', + '#ff4444', '#44ff44', '#4444ff', '#ffff44', '#ff44ff', '#44ffff' ]; - for (let i = 0; i < 50; i++) { // More particles + for (let i = 0; i < 80; i++) { // More particles const color = colors[Math.floor(Math.random() * colors.length)]; GameState.particles.push(new Particle(hitEnemy.x, hitEnemy.y, color)); } @@ -905,20 +963,25 @@ class Particle { this.x = x; this.y = y; this.color = color; - this.size = Math.random() * 4 + 2; // Larger size range - this.speedX = (Math.random() - 0.5) * 12; // Faster spread - this.speedY = (Math.random() - 0.5) * 12; // Faster spread + this.size = Math.random() * 8 + 4; // Larger size range (4-12) + + // Random direction in all directions (360 degrees) + const angle = Math.random() * Math.PI * 2; + const speed = Math.random() * 15 + 5; // Faster spread (5-20) + this.speedX = Math.sin(angle) * speed; + this.speedY = Math.cos(angle) * speed; + this.life = 1.0; this.decay = Math.random() * 0.005 + 0.002; // Slower decay - this.rotation = Math.random() * Math.PI * 2; // Random starting rotation - this.rotationSpeed = (Math.random() - 0.5) * 0.2; // Random rotation speed - this.gravity = Math.random() * 0.15 + 0.05; // Random gravity effect + this.rotation = Math.random() * Math.PI * 2; + this.rotationSpeed = (Math.random() - 0.5) * 0.2; + this.gravity = Math.random() * 0.15 + 0.05; } update() { this.x += this.speedX; this.y += this.speedY; - this.speedY += this.gravity; // Variable gravity + this.speedY += this.gravity; this.life -= this.decay; this.rotation += this.rotationSpeed; return this.life > 0; |