ZaxxoGalaxian / bak1.app.py
awacke1's picture
Rename app.py to bak1.app.py
3ecf58b verified
import streamlit as st
from streamlit.components.v1 import html
import random
import string
# Define the enhanced HTML content with Three.js game
game_html = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Galaxxon - Enhanced Arcade Game</title>
<style>
body { margin: 0; overflow: hidden; background: #000; font-family: Arial; }
canvas { display: block; width: 100%; height: 100%; }
#ui { position: absolute; top: 10px; left: 10px; color: white; }
#sidebar { position: absolute; top: 10px; right: 10px; color: white; width: 200px; background: rgba(0,0,0,0.7); padding: 10px; }
#lives { position: absolute; top: 40px; left: 10px; color: white; }
</style>
</head>
<body>
<div id="ui">Score: <span id="score">0</span> | Multiplier: <span id="multiplier">1</span>x | Time: <span id="timer">0</span>s</div>
<div id="lives">Lives: <span id="livesCount">5</span></div>
<div id="sidebar">
<h3>High Scores</h3>
<div id="highScores"></div>
<button onclick="saveScore()">Save Score</button>
</div>
<script type="module">
import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js';
let scene, camera, renderer, player, enemies = [], bullets = [], buildings = [];
let clock = new THREE.Clock();
let moveLeft = false, moveRight = false, moveUp = false, moveDown = false, shoot = false;
let score = 0, multiplier = 1, gameTime = 0, lastHitTime = 0, lives = 5;
let highScores = JSON.parse(localStorage.getItem('highScores')) || [];
let exploding = false;
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.set(0, 5, 15);
camera.lookAt(0, 0, -50);
const playerGeometry = new THREE.BoxGeometry(1, 1, 1);
const playerMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
player = new THREE.Mesh(playerGeometry, playerMaterial);
player.position.set(0, 0, 0);
scene.add(player);
spawnBuildings();
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
window.addEventListener('keydown', onKeyDown);
window.addEventListener('keyup', onKeyUp);
window.addEventListener('resize', onWindowResize);
updateHighScoresUI();
animate();
}
function spawnBuildings() {
const primitives = [
new THREE.BoxGeometry(2, 2, 2),
new THREE.CylinderGeometry(1, 1, 3, 8),
new THREE.ConeGeometry(1.5, 2, 8)
];
const material = new THREE.MeshBasicMaterial({ color: 0x808080 });
for (let i = 0; i < 10; i++) {
const building = new THREE.Group();
const height = Math.random() * 5 + 2;
for (let j = 0; j < height; j++) {
const primitive = primitives[Math.floor(Math.random() * primitives.length)].clone();
const segment = new THREE.Mesh(primitive, material);
segment.position.y = j * 2 - height;
building.add(segment);
}
building.position.set(Math.random() * 40 - 20, height / 2, -50 - Math.random() * 50);
building.spawnTimer = 0;
buildings.push(building);
scene.add(building);
}
}
function spawnEnemyFromBuilding(building) {
const enemyGeometry = new THREE.BoxGeometry(0.8, 0.8, 0.8);
const enemyMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const enemy = new THREE.Mesh(enemyGeometry, enemyMaterial);
enemy.position.copy(building.position);
enemy.position.y += building.children.length * 2;
enemy.velocity = new THREE.Vector3(Math.random() - 0.5, Math.random() - 0.5, 1).normalize();
enemies.push(enemy);
scene.add(enemy);
}
function onKeyDown(event) {
switch (event.code) {
case 'ArrowLeft': case 'KeyA': moveLeft = true; break;
case 'ArrowRight': case 'KeyD': moveRight = true; break;
case 'ArrowUp': case 'KeyW': moveUp = true; break;
case 'ArrowDown': case 'KeyS': moveDown = true; break;
case 'Space': shoot = true; break;
}
}
function onKeyUp(event) {
switch (event.code) {
case 'ArrowLeft': case 'KeyA': moveLeft = false; break;
case 'ArrowRight': case 'KeyD': moveRight = false; break;
case 'ArrowUp': case 'KeyW': moveUp = false; break;
case 'ArrowDown': case 'KeyS': moveDown = false; break;
case 'Space': shoot = false; break;
}
}
function updatePlayer(delta) {
if (exploding) return;
const speed = 10;
if (moveLeft && player.position.x > -20) player.position.x -= speed * delta;
if (moveRight && player.position.x < 20) player.position.x += speed * delta;
if (moveUp && player.position.y < 10) player.position.y += speed * delta;
if (moveDown && player.position.y > -5) player.position.y -= speed * delta;
if (shoot && clock.getElapsedTime() > 0.2) {
shootBullet();
clock = new THREE.Clock();
}
}
function shootBullet() {
const bulletGeometry = new THREE.SphereGeometry(0.2, 8, 8);
const bulletMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });
const bullet = new THREE.Mesh(bulletGeometry, bulletMaterial);
bullet.position.copy(player.position);
bullet.position.z -= 1;
bullets.push(bullet);
scene.add(bullet);
}
function updateBullets(delta) {
const bulletSpeed = 20;
for (let i = bullets.length - 1; i >= 0; i--) {
bullets[i].position.z -= bulletSpeed * delta;
if (bullets[i].position.z < -100) {
scene.remove(bullets[i]);
bullets.splice(i, 1);
} else {
checkCollisions(bullets[i], i);
}
}
}
function checkCollisions(bullet, bulletIndex) {
for (let i = enemies.length - 1; i >= 0; i--) {
if (bullet.position.distanceTo(enemies[i].position) < 1) {
scene.remove(enemies[i]);
enemies.splice(i, 1);
scene.remove(bullet);
bullets.splice(bulletIndex, 1);
score += 10 * multiplier;
if (clock.getElapsedTime() - lastHitTime < 2) multiplier += 0.5;
lastHitTime = clock.getElapsedTime();
updateUI();
break;
}
}
}
function updateFlockingEnemies(delta) {
const speed = 3;
enemies.forEach(enemy => {
enemy.position.add(enemy.velocity.clone().multiplyScalar(delta * speed));
if (enemy.position.z > 10) {
scene.remove(enemy);
enemies.splice(enemies.indexOf(enemy), 1);
}
});
}
function updateBuildings(delta) {
const buildingSpeed = 5;
buildings.forEach(building => {
building.position.z += buildingSpeed * delta;
if (building.position.z > 20) {
building.position.z = -50 - Math.random() * 50;
building.position.x = Math.random() * 40 - 20;
}
const distToPlayer = building.position.distanceTo(player.position);
if (distToPlayer < 10 && building.spawnTimer <= 0) {
spawnEnemyFromBuilding(building);
building.spawnTimer = 2;
}
building.spawnTimer -= delta;
if (!exploding && player.position.distanceTo(building.position) < 3) {
explodePlayer();
}
});
}
function explodePlayer() {
exploding = true;
lives--;
updateUI();
const particleGeometry = new THREE.SphereGeometry(0.1, 8, 8);
const particleMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
for (let i = 0; i < 20; i++) {
const particle = new THREE.Mesh(particleGeometry, particleMaterial);
particle.position.copy(player.position);
particle.velocity = new THREE.Vector3(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).multiplyScalar(5);
scene.add(particle);
setTimeout(() => scene.remove(particle), 500);
}
player.visible = false;
setTimeout(() => {
player.visible = true;
exploding = false;
player.position.set(0, 0, 0);
if (lives === 1) alert("Last life remaining!");
if (lives <= 0) {
alert("Game Over! Final Score: " + score);
saveScore();
lives = 5;
score = 0;
multiplier = 1;
updateUI();
}
}, 1000);
}
function updateUI() {
document.getElementById('score').innerText = score;
document.getElementById('multiplier').innerText = multiplier.toFixed(1);
document.getElementById('timer').innerText = Math.floor(gameTime);
document.getElementById('livesCount').innerText = lives;
if (clock.getElapsedTime() - lastHitTime > 5) multiplier = 1;
}
function updateHighScoresUI() {
const scoresDiv = document.getElementById('highScores');
scoresDiv.innerHTML = highScores.map(s => `${s.name}: ${s.score} (${s.time}s)`).join('<br>');
}
window.saveScore = function() {
const name = prompt("Enter 3-letter name:", generateRandomName());
if (name && name.length === 3) {
highScores.push({ name, score, time: Math.floor(gameTime) });
highScores.sort((a, b) => b.score - a.score);
highScores = highScores.slice(0, 5);
localStorage.setItem('highScores', JSON.stringify(highScores));
updateHighScoresUI();
}
}
function generateRandomName() {
const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
return Array(3).fill().map(() => letters[Math.floor(Math.random() * letters.length)]).join('');
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
gameTime += delta;
updatePlayer(delta);
updateBullets(delta);
updateFlockingEnemies(delta);
updateBuildings(delta);
updateUI();
renderer.render(scene, camera);
}
init();
</script>
</body>
</html>
"""
# Streamlit app
st.title("Galaxxon - Enhanced Arcade Game")
st.write("Use WASD or Arrow Keys to move, Spacebar to shoot. Avoid buildings and destroy enemies launching from them!")
# Render the HTML game
html(game_html, height=600, scrolling=False)
st.write("Note: The game runs in your browser. Ensure you have an internet connection for Three.js to load.")