LiteChat Model Race Result (RUNJS)
```runjs
// Clear previous content
litechat.target.replaceChildren();
async function create2DScrollShooter() {
try {
litechat.utils.log('info', '🚀 Starting 2D scroll shooter with 3D effects...');
// Load Three.js
const modules = await litechat.utils.loadModules([
{
url: 'https://unpkg.com/three@0.170.0/build/three.module.js',
name: 'THREE',
globalKey: 'THREE',
importMap: {
"three": "https://unpkg.com/three@0.170.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.170.0/examples/jsm/"
}
}
]);
const { THREE } = modules;
// Create game container
const container = document.createElement('div');
container.className = 'p-4 bg-gradient-to-br from-purple-900 via-blue-900 to-indigo-900 rounded-lg';
const canvas = document.createElement('canvas');
canvas.width = 800;
canvas.height = 600;
canvas.className = 'border-2 border-pink-400 rounded-lg shadow-2xl';
container.appendChild(canvas);
// Game UI
const ui = document.createElement('div');
ui.className = 'mt-4 flex justify-between text-white font-bold';
const livesDisplay = document.createElement('div');
livesDisplay.textContent = 'Lives: 3';
const scoreDisplay = document.createElement('div');
scoreDisplay.textContent = 'Score: 0';
const bonusDisplay = document.createElement('div');
bonusDisplay.textContent = 'Fire Rate: 100% | Bounces: 0 | Guns: 1';
ui.appendChild(livesDisplay);
ui.appendChild(scoreDisplay);
ui.appendChild(bonusDisplay);
container.appendChild(ui);
litechat.target.appendChild(container);
// Three.js setup
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x111111);
const camera = new THREE.PerspectiveCamera(75, canvas.width / canvas.height, 0.1, 1000);
camera.position.set(0, 0, 10);
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
renderer.setSize(canvas.width, canvas.height);
// Game state
const gameState = {
lives: 3,
score: 0,
fireRate: 1,
bounces: 0,
gunLevel: 1,
enemySpeed: 1,
enemyHealth: 1
};
// Player
const playerGeometry = new THREE.BoxGeometry(1, 0.5, 0.2);
const playerMaterial = new THREE.MeshLambertMaterial({ color: 0x00ff00 });
const player = new THREE.Mesh(playerGeometry, playerMaterial);
player.position.set(0, -4, 0);
scene.add(player);
// Bullets
const bullets = [];
const bulletGeometry = new THREE.SphereGeometry(0.1, 8, 8);
// Enemies
const enemies = [];
const enemyGeometry = new THREE.BoxGeometry(0.5, 0.5, 0.5);
// Particles for explosions
const particles = [];
// Power-ups
const powerUps = [];
const powerUpGeometry = new THREE.SphereGeometry(0.3, 8, 8);
const powerUpColors = {
fireRate: 0xff00ff,
bouncy: 0x00ffff,
guns: 0xffff00,
life: 0xff4444
};
// Lighting
const ambientLight = new THREE.AmbientLight(0x404040, 0.6);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(0, 10, 5);
scene.add(directionalLight);
// Stars background
const stars = [];
for (let i = 0; i < 100; i++) {
const starGeometry = new THREE.SphereGeometry(0.02, 4, 4);
const starMaterial = new THREE.MeshBasicMaterial({
color: new THREE.Color().setHSL(Math.random(), 1, 0.5)
});
const star = new THREE.Mesh(starGeometry, starMaterial);
star.position.set(
(Math.random() - 0.5) * 20,
(Math.random() - 0.5) * 15,
-5 - Math.random() * 5
);
scene.add(star);
stars.push(star);
}
// Game functions
function createBullet(x, y, direction, bounces = 0) {
const bulletMaterial = new THREE.MeshLambertMaterial({
color: new THREE.Color().setHSL((Date.now() * 0.01) % 1, 1, 0.5)
});
const bullet = new THREE.Mesh(bulletGeometry, bulletMaterial);
bullet.position.set(x, y, 0);
bullet.userData = {
velocity: { x: direction.x, y: direction.y },
bounces: bounces
};
scene.add(bullet);
bullets.push(bullet);
}
function createEnemy() {
const enemyMaterial = new THREE.MeshLambertMaterial({
color: new THREE.Color().setHSL(Math.random(), 1, 0.5)
});
const enemy = new THREE.Mesh(enemyGeometry, enemyMaterial);
const x = (Math.random() - 0.5) * 8;
enemy.position.set(x, 6, 0);
enemy.userData = { health: gameState.enemyHealth };
scene.add(enemy);
enemies.push(enemy);
}
function createPowerUp(type, x, y) {
const color = powerUpColors[type];
const material = new THREE.MeshLambertMaterial({
color,
emissive: color,
emissiveIntensity: 0.5
});
const powerUp = new THREE.Mesh(powerUpGeometry, material);
powerUp.position.set(x, y, 0);
powerUp.userData = { type };
scene.add(powerUp);
powerUps.push(powerUp);
}
function createExplosion(x, y, z) {
for (let i = 0; i < 10; i++) {
const particleGeometry = new THREE.SphereGeometry(0.05, 4, 4);
const particleMaterial = new THREE.MeshBasicMaterial({
color: new THREE.Color().setHSL(Math.random(), 1, 0.5)
});
const particle = new THREE.Mesh(particleGeometry, particleMaterial);
particle.position.set(x, y, z);
particle.userData = {
velocity: {
x: (Math.random() - 0.5) * 0.3,
y: (Math.random() - 0.5) * 0.3,
z: (Math.random() - 0.5) * 0.3
},
life: 30
};
scene.add(particle);
particles.push(particle);
}
}
function updateGame() {
// Update stars
stars.forEach(star => {
star.position.y -= 0.02;
if (star.position.y < -8) {
star.position.y = 8;
star.position.x = (Math.random() - 0.5) * 20;
}
});
// Player movement
const speed = 0.15;
if (keys.ArrowLeft && player.position.x > -4) player.position.x -= speed;
if (keys.ArrowRight && player.position.x < 4) player.position.x += speed;
if (keys.ArrowUp && player.position.y < 4) player.position.y += speed;
if (keys.ArrowDown && player.position.y > -4) player.position.y -= speed;
// Shooting
if (keys.Space && Math.random() < 0.3 * gameState.fireRate) {
const directions = [{ x: 0, y: 0.5 }];
if (gameState.gunLevel >= 2) {
directions.push({ x: -0.3, y: 0.5 });
directions.push({ x: 0.3, y: 0.5 });
}
if (gameState.gunLevel >= 3) {
directions.push({ x: -0.5, y: 0.3 });
directions.push({ x: 0.5, y: 0.3 });
}
directions.forEach(dir => {
createBullet(player.position.x, player.position.y + 0.3, dir, gameState.bounces);
});
}
// Update bullets
bullets.forEach((bullet, index) => {
bullet.position.x += bullet.userData.velocity.x;
bullet.position.y += bullet.userData.velocity.y;
if (bullet.position.y > 6 || bullet.position.x < -5 || bullet.position.x > 5) {
scene.remove(bullet);
bullets.splice(index, 1);
}
});
// Update enemies
enemies.forEach((enemy, enemyIndex) => {
enemy.position.y -= 0.02 * gameState.enemySpeed;
enemy.rotation.x += 0.02;
enemy.rotation.y += 0.02;
if (enemy.position.y < -6) {
scene.remove(enemy);
enemies.splice(enemyIndex, 1);
gameState.lives--;
updateUI();
}
// Check bullet collisions
bullets.forEach((bullet, bulletIndex) => {
const distance = enemy.position.distanceTo(bullet.position);
if (distance < 0.4) {
createExplosion(enemy.position.x, enemy.position.y, enemy.position.z);
scene.remove(bullet);
bullets.splice(bulletIndex, 1);
enemy.userData.health--;
if (enemy.userData.health <= 0) {
scene.remove(enemy);
enemies.splice(enemyIndex, 1);
gameState.score += 10;
// Random power-up drop
if (Math.random() < 0.1) {
const types = Object.keys(powerUpColors);
const type = types[Math.floor(Math.random() * types.length)];
createPowerUp(type, enemy.position.x, enemy.position.y);
}
// Bouncy bullets
if (bullet.userData.bounces > 0 && enemies.length > 0) {
const nearestEnemy = enemies.reduce((nearest, e) => {
const dist = e.position.distanceTo(enemy.position);
return dist < nearest.dist ? { enemy: e, dist } : nearest;
}, { enemy: null, dist: Infinity });
if (nearestEnemy.enemy) {
const dir = nearestEnemy.enemy.position.clone().sub(enemy.position).normalize();
createBullet(enemy.position.x, enemy.position.y, { x: dir.x * 0.5, y: dir.y * 0.5 }, bullet.userData.bounces - 1);
}
}
}
updateUI();
}
});
});
// Update power-ups
powerUps.forEach((powerUp, index) => {
powerUp.position.y -= 0.01;
powerUp.rotation.y += 0.05;
if (powerUp.position.y < -6) {
scene.remove(powerUp);
powerUps.splice(index, 1);
}
const distance = player.position.distanceTo(powerUp.position);
if (distance < 0.8) {
applyPowerUp(powerUp.userData.type);
scene.remove(powerUp);
powerUps.splice(index, 1);
}
});
// Update particles
particles.forEach((particle, index) => {
particle.position.add(particle.userData.velocity);
particle.userData.life--;
if (particle.userData.life <= 0) {
scene.remove(particle);
particles.splice(index, 1);
}
});
// Spawn enemies
if (Math.random() < 0.02) {
createEnemy();
}
// Increase difficulty
if (gameState.score > 0 && gameState.score % 100 === 0) {
gameState.enemySpeed += 0.1;
gameState.enemyHealth += 0.1;
}
renderer.render(scene, camera);
if (gameState.lives > 0) {
requestAnimationFrame(updateGame);
} else {
const gameOver = document.createElement('div');
gameOver.className = 'absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 text-white text-4xl font-bold';
gameOver.textContent = 'GAME OVER!';
container.appendChild(gameOver);
}
}
function applyPowerUp(type) {
switch(type) {
case 'fireRate':
gameState.fireRate *= 1.1;
break;
case 'bouncy':
gameState.bounces++;
break;
case 'guns':
gameState.gunLevel = Math.min(3, gameState.gunLevel + 1);
break;
case 'life':
gameState.lives++;
break;
}
updateUI();
}
function updateUI() {
livesDisplay.textContent = `Lives: ${gameState.lives}`;
scoreDisplay.textContent = `Score: ${gameState.score}`;
bonusDisplay.textContent = `Fire Rate: ${Math.round(gameState.fireRate * 100)}% | Bounces: ${gameState.bounces} | Guns: ${gameState.gunLevel}`;
}
// Controls
const keys = {};
window.addEventListener('keydown', (e) => keys[e.code] = true);
window.addEventListener('keyup', (e) => keys[e.code] = false);
// Instructions
const instructions = document.createElement('div');
instructions.className = 'mt-4 text-center text-white';
instructions.innerHTML = `
<p class="text-lg font-bold">🎮 CONTROLS 🎮</p>
<p>Arrow Keys: Move | Space: Shoot</p>
<p>💜 Pink: Faster Fire | 💙 Cyan: Bouncy Bullets | 💛 Yellow: More Guns | ❤️ Red: Extra Life</p>
`;
container.appendChild(instructions);
// Start game
updateGame();
litechat.utils.log('info', '🎮 SUCCESS! Colorful 2D scroll shooter is running!');
} catch (error) {
litechat.utils.log('error', '❌ FAILED to create game:', error);
const errorDiv = document.createElement('div');
errorDiv.className = 'p-4 text-red-600 bg-red-100 border border-red-200 rounded-md';
errorDiv.textContent = `Error: ${error.message}`;
litechat.target.appendChild(errorDiv);
}
}
create2DScrollShooter();
```