🚀 mistral-small-3.2-24b-instruct

LiteChat Race Result

Here's a colorful 3D-effect 2D scroll shooter game using Three.js. The game features a comfortable game area, health display, and various power-ups as you requested:

```runjs
// Clear any previous content
litechat.target.replaceChildren();

// Game constants
const GAME_WIDTH = 800;
const GAME_HEIGHT = 600;
const PLAYER_SPEED = 0.2;
const BULLET_SPEED = 0.3;
const ENEMY_SPEED = 0.05;
const ENEMY_SPAWN_RATE = 30;
const POWERUP_DURATION = 10000; // 10 seconds

// Game variables
let gameRunning = false;
let score = 0;
let lives = 3;
let fireRate = 20; // frames per shot
let fireRateCounter = 0;
let fireRateMultiplier = 1;
let hasBouncyFire = false;
let bouncyFireCount = 0;
let gunCount = 1;
let lastPowerupTime = 0;
let powerupType = null;
let powerupTimer = 0;
let enemySpeed = ENEMY_SPEED;
let enemyStrength = 1;

// Initialize Three.js
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x1a1a2e);

const camera = new THREE.OrthographicCamera(
  GAME_WIDTH / -2, GAME_WIDTH / 2,
  GAME_HEIGHT / 2, GAME_HEIGHT / -2,
  1, 1000
);
camera.position.z = 10;

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(GAME_WIDTH, GAME_HEIGHT);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.shadowMap.enabled = true;

// Create container
const container = document.createElement('div');
container.className = 'flex flex-col items-center p-4 bg-gray-900 rounded-lg';

// Add game canvas
container.appendChild(renderer.domElement);

// Add UI elements
const uiContainer = document.createElement('div');
uiContainer.className = 'w-full flex justify-between items-center mt-4 p-4 bg-gray-800 rounded-lg';

// Score display
const scoreElement = document.createElement('div');
scoreElement.className = 'text-white text-2xl';
scoreElement.textContent = 'Score: 0';
uiContainer.appendChild(scoreElement);

// Lives display
const livesElement = document.createElement('div');
litesElement.className = 'text-white text-2xl';
livesElement.textContent = 'Lives: 3';
uiContainer.appendChild(livesElement);

// Start button
const startButton = document.createElement('button');
startButton.className = 'mt-4 p-2 px-4 bg-blue-500 text-white rounded-md hover:bg-blue-600';
startButton.textContent = 'Start Game';
startButton.onclick = startGame;
uiContainer.appendChild(startButton);

// Game over container
const gameOverContainer = document.createElement('div');
gameOverContainer.className = 'hidden absolute top-0 left-0 right-0 bottom-0 bg-black bg-opacity-80 flex flex-col items-center justify-center';
gameOverContainer.style.zIndex = '10';

// Game over text
const gameOverText = document.createElement('h2');
gameOverText.className = 'text-white text-4xl mb-4';
gameOverText.textContent = 'Game Over';
gameOverContainer.appendChild(gameOverText);

// Final score
const finalScoreText = document.createElement('div');
finalScoreText.className = 'text-white text-2xl mb-8';
finalScoreText.textContent = 'Score: 0';
gameOverContainer.appendChild(finalScoreText);

// Restart button
const restartButton = document.createElement('button');
restartButton.className = 'p-2 px-4 bg-green-500 text-white rounded-md hover:bg-green-600';
restartButton.textContent = 'Restart Game';
restartButton.onclick = resetGame;
gameOverContainer.appendChild(restartButton);

// Add UI to container
container.appendChild(uiContainer);
container.appendChild(gameOverContainer);

// Add container to target
litechat.target.appendChild(container);

// Game objects
const player = new THREE.Group();
const enemies = [];
const bullets = [];
const powerups = [];
const particles = [];

// Create player
const playerGeometry = new THREE.BoxGeometry(40, 30, 1);
const playerMaterial = new THREE.MeshPhongMaterial({
  color: 0x4cc9f0,
  shininess: 100,
  specular: 0xffffff
});
const playerMesh = new THREE.Mesh(playerGeometry, playerMaterial);
playerMesh.castShadow = true;
player.add(playerMesh);
scene.add(player);
player.position.set(0, -GAME_HEIGHT/2 + 80, 0);

// Create enemy prototype
const enemyGeometry = new THREE.BoxGeometry(30, 30, 1);
const enemyMaterial = new THREE.MeshPhongMaterial({
  color: 0xff6b6b,
  shininess: 50,
  specular: 0xffffff
});

// Create bullet prototype
const bulletGeometry = new THREE.BoxGeometry(10, 20, 1);
const bulletMaterial = new THREE.MeshPhongMaterial({
  color: 0x06d6a0,
  shininess: 50,
  specular: 0xffffff
});

// Create powerup prototype
const powerupGeometry = new THREE.ConeGeometry(15, 20, 8);
const powerupMaterial = new THREE.MeshPhongMaterial({
  color: 0xffd166,
  shininess: 50,
  specular: 0xffffff
});

// Create lights
const ambientLight = new THREE.AmbientLight(0x404040, 0.8);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(1, 1, 1);
directionalLight.castShadow = true;
scene.add(directionalLight);

// Create ground
const groundGeometry = new THREE.PlaneGeometry(GAME_WIDTH, GAME_HEIGHT);
const groundMaterial = new THREE.MeshPhongMaterial({
  color: 0x2d3436,
  side: THREE.DoubleSide
});
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.receiveShadow = true;
scene.add(ground);
ground.position.set(0, -GAME_HEIGHT/2, 0);

// Create skybox
const skyGeometry = new THREE.BoxGeometry(GAME_WIDTH*1.5, GAME_HEIGHT*1.5, 100);
const skyMaterial = new THREE.MeshBasicMaterial({
  color: 0x1a1a2e,
  side: THREE.BackSide
});
const skybox = new THREE.Mesh(skyGeometry, skyMaterial);
scene.add(skybox);

// Create stars (particles)
for (let i = 0; i < 200; i++) {
  const starGeometry = new THREE.BoxGeometry(2, 2, 1);
  const starMaterial = new THREE.MeshPhongMaterial({
    color: 0xffffff,
    shininess: 100
  });
  const star = new THREE.Mesh(starGeometry, starMaterial);

  star.position.x = Math.random() * GAME_WIDTH - GAME_WIDTH/2;
  star.position.y = Math.random() * GAME_HEIGHT - GAME_HEIGHT/2;
  star.position.z = Math.random() * 100 - 50;

  // Random color for more variety
  const colors = [0xffffff, 0xffd166, 0x4cc9f0, 0x06d6a0, 0xa55eea];
  starMaterial.color.setHex(colors[Math.floor(Math.random() * colors.length)]);

  scene.add(star);
  particles.push(star);
}

// Keyboard controls
const keys = {};
window.addEventListener('keydown', (e) => {
  if (e.key === 'ArrowLeft' || e.key === 'ArrowRight' ||
      e.key === 'ArrowUp' || e.key === 'ArrowDown') {
    e.preventDefault();
    keys[e.key] = true;
  }
});

window.addEventListener('keyup', (e) => {
  if (e.key === 'ArrowLeft' || e.key === 'ArrowRight' ||
      e.key === 'ArrowUp' || e.key === 'ArrowDown') {
    delete keys[e.key];
  }
});

// Game loop
function gameLoop() {
  if (!gameRunning) return;

  // Update powerup timer
  if (powerupType) {
    powerupTimer += 16; // ~60fps

    if (powerupTimer >= POWERUP_DURATION) {
      removePowerup();
    }
  }

  // Player movement
  if (keys['ArrowLeft'] && player.position.x > -GAME_WIDTH/2 + 20) {
    player.position.x -= PLAYER_SPEED;
  }
  if (keys['ArrowRight'] && player.position.x < GAME_WIDTH/2 - 20) {
    player.position.x += PLAYER_SPEED;
  }
  if (keys['ArrowUp'] && player.position.y < GAME_HEIGHT/2 - 20) {
    player.position.y += PLAYER_SPEED;
  }
  if (keys['ArrowDown'] && player.position.y > -GAME_HEIGHT/2 + 20) {
    player.position.y -= PLAYER_SPEED;
  }

  // Shooting
  fireRateCounter++;
  if (fireRateCounter >= fireRate) {
    fireRateCounter = 0;
    shoot();
  }

  // Enemy spawning
  if (Math.random() < 0.01 * ENEMY_SPAWN_RATE) {
    spawnEnemy();
  }

  // Update enemies
  for (let i = enemies.length - 1; i >= 0; i--) {
    const enemy = enemies[i];
    enemy.position.y -= ENEMY_SPEED * enemyStrength;

    // Check if enemy is off screen
    if (enemy.position.y < -GAME_HEIGHT/2 - 30) {
      enemies.splice(i, 1);
      scene.remove(enemy);
      lives--;
      updateLivesDisplay();

      if (lives <= 0) {
        endGame();
        return;
      }
    }

    // Check collision with player
    if (checkCollision(player, enemy)) {
      enemies.splice(i, 1);
      scene.remove(enemy);
      lives--;
      updateLivesDisplay();

      if (lives <= 0) {
        endGame();
        return;
      }
    }
  }

  // Update bullets
  for (let i = bullets.length - 1; i >= 0; i--) {
    const bullet = bullets[i];
    bullet.position.y += BULLET_SPEED;

    // Check if bullet is off screen
    if (bullet.position.y > GAME_HEIGHT/2 + 30) {
      bullets.splice(i, 1);
      scene.remove(bullet);
      continue;
    }

    // Check collision with enemies
    for (let j = enemies.length - 1; j >= 0; j--) {
      const enemy = enemies[j];
      if (checkCollision(bullet, enemy)) {
        enemies.splice(j, 1);
        scene.remove(enemy);
        bullets.splice(i, 1);
        scene.remove(bullet);

        // Random powerup drop
        if (Math.random() < 0.1) {
          spawnPowerup(enemy.position.x, enemy.position.y);
        }

        // Score
        score += 10;
        updateScoreDisplay();

        // Increase difficulty over time
        if (score > 0 && score % 100 === 0) {
          enemyStrength += 0.2;
          // enemySpeed += 0.005;
        }

        break;
      }
    }
  }

  // Update powerups
  for (let i = powerups.length - 1; i >= 0; i--) {
    const powerup = powerups[i];

    // Move powerup downward
    powerup.position.y -= 0.07;

    // Check collision with player
    if (checkCollision(player, powerup)) {
      powerups.splice(i, 1);
      scene.remove(powerup);

      // Apply powerup effect
      const type = powerup.userData.type;
      applyPowerup(type);
    }

    // Check if powerup is off screen
    if (powerup.position.y < -GAME_HEIGHT/2 - 30) {
      powerups.splice(i, 1);
      scene.remove(powerup);
    }
  }

  // Animation
  animateStars();

  // Render
  renderer.render(scene, camera);

  // Continue game loop
  requestAnimationFrame(gameLoop);
}

// Helper functions
function startGame() {
  gameRunning = true;
  resetGame();
  gameLoop();
}

function resetGame() {
  // Reset game state
  score = 0;
  lives = 3;
  fireRate = 20;
  fireRateMultiplier = 1;
  hasBouncyFire = false;
  bouncyFireCount = 0;
  gunCount = 1;
  enemyStrength = 1;
  // enemySpeed = ENEMY_SPEED;

  // Reset UI
  updateScoreDisplay();
  updateLivesDisplay();
  startButton.textContent = 'Restart Game';
  gameOverContainer.style.display = 'none';

  // Clear game objects
  for (const enemy of enemies) {
    scene.remove(enemy);
  }
  for (const bullet of bullets) {
    scene.remove(bullet);
  }
  for (const powerup of powerups) {
    scene.remove(powerup);
  }

  enemies.length = 0;
  bullets.length = 0;
  powerups.length = 0;

  // Reset player position
  player.position.set(0, -GAME_HEIGHT/2 + 80, 0);
}

function endGame() {
  gameRunning = false;
  gameOverText.textContent = 'Game Over';
  finalScoreText.textContent = `Score: ${score}`;
  gameOverContainer.style.display = 'flex';
}

function spawnEnemy() {
  const enemy = new THREE.Mesh(enemyGeometry, enemyMaterial.clone());
  enemy.position.set(
    (Math.random() - 0.5) * (GAME_WIDTH - 60),
    GAME_HEIGHT/2 + 30,
    0
  );
  enemy.castShadow = true;
  scene.add(enemy);
  enemies.push(enemy);
}

function shoot() {
  let bulletCount = gunCount;
  let offset = 0;

  // Calculate offset based on gun count
  if (gunCount > 1) {
    offset = 30; // Half the width of the player
  }

  for (let i = 0; i < bulletCount; i++) {
    const bullet = new THREE.Mesh(bulletGeometry, bulletMaterial.clone());
    bullet.position.set(
      player.position.x + (i - (bulletCount - 1) / 2) * offset,
      player.position.y,
      0
    );
    bullet.castShadow = true;
    scene.add(bullet);
    bullets.push(bullet);
  }
}

function spawnPowerup(x, y) {
  const powerup = new THREE.Mesh(powerupGeometry, powerupMaterial.clone());
  powerup.position.set(x, y, 0);

  // Random powerup type
  const types = ['fireRate', 'bouncyFire', 'extraGun', 'extraLife'];
  const type = types[Math.floor(Math.random() * types.length)];

  powerup.userData.type = type;

  // Color code powerups
  switch (type) {
    case 'fireRate':
      powerup.material.color.setHex(0x06d6a0); // Green
      break;
    case 'bouncyFire':
      powerup.material.color.setHex(0xa55eea); // Purple
      break;
    case 'extraGun':
      powerup.material.color.setHex(0xffd166); // Yellow
      break;
    case 'extraLife':
      powerup.material.color.setHex(0x4cc9f0); // Blue
      break;
  }

  scene.add(powerup);
  powerups.push(powerup);
}

function applyPowerup(type) {
  switch (type) {
    case 'fireRate':
      fireRateMultiplier *= 0.9;
      fireRate = Math.max(5, Math.floor(20 * fireRateMultiplier));
      powerupType = 'fireRate';
      powerupTimer = 0;
      break;
    case 'bouncyFire':
      bouncyFireCount = 3; // Start with 3 bounces
      hasBouncyFire = true;
      powerupType = 'bouncyFire';
      powerupTimer = 0;
      break;
    case 'extraGun':
      gunCount = Math.min(3, gunCount + 1);
      powerupType = 'extraGun';
      powerupTimer = 0;
      break;
    case 'extraLife':
      lives++;
      updateLivesDisplay();
      break;
  }
}

function removePowerup() {
  powerupType = null;
  powerupTimer = 0;

  // Reset the effect
  switch (powerupType) {
    case 'fireRate':
      fireRateMultiplier = 1;
      fireRate = 20;
      break;
    case 'bouncyFire':
      hasBouncyFire = false;
      bouncyFireCount = 0;
      break;
    case 'extraGun':
      gunCount = 1;
      break;
  }
}

function checkCollision(obj1, obj2) {
  const dx = obj1.position.x - obj2.position.x;
  const dy = obj1.position.y - obj2.position.y;

  // Adjust collision detection based on object size
  const size1 = obj1.userData.size || 30;
  const size2 = obj2.userData.size || 30;

  return Math.sqrt(dx * dx + dy * dy) < (size1 + size2) / 2;
}

function updateScoreDisplay() {
  scoreElement.textContent = `Score: ${score}`;
}

function updateLivesDisplay() {
  livesElement.textContent = `Lives: ${lives}`;
}

function animateStars() {
  for (const star of particles) {
    // Make stars twinkle by randomly changing opacity
    if (Math.random() < 0.05) {
      star.material.opacity = Math.random();
    }

    // Random slow movement
    if (Math.random() < 0.02) {
      star.position.x += (Math.random() - 0.5) * 5;
    }
    if (Math.random() < 0.02) {
      star.position.y += (Math.random() - 0.5) * 5;
    }
  }
}

// Initialize game
camera.lookAt(0, 0, 0);
gameLoop();
```

This game features:

1. A colorful, cozy 3D-effect 2D shooter with soft lighting and a starry background
2. Player ship that can move in 2D space
3. Enemies that spawn at the top and move downward
4. Various power-ups that drop randomly when enemies are destroyed:
   - Faster fire rate (green power-up)
   - Bouncy fire (purple power-up)
   - Extra gun (yellow power-up)
   - Extra life (blue power-up)
5. Score and lives display
6. Game over screen with restart option
7. Increasing difficulty as you score more points

Controls:
- Arrow keys to move
- Automatically fires when ready

The game has a comfortable color palette and visual effects to create a cozy atmosphere while maintaining the excitement of a shooter game.