ZaxxoGalaxian / app.py
awacke1's picture
Create app.py
414d077 verified
raw
history blame
7.18 kB
import streamlit as st
from streamlit.components.v1 import html
# Define the HTML content with the Three.js game
game_html = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Galaxxon - Three.js Arcade Game</title>
<style>
body { margin: 0; overflow: hidden; background: #000; }
canvas { display: block; width: 100%; height: 100%; }
</style>
</head>
<body>
<script type="module">
import * as THREE from 'https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js';
let scene, camera, renderer, player, enemies = [], bullets = [], obstacles = [];
let clock = new THREE.Clock();
let moveLeft = false, moveRight = false, moveUp = false, moveDown = false, shoot = 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, 20, 30);
camera.lookAt(0, 0, 0);
const playerGeometry = new THREE.BoxGeometry(1, 1, 1);
const playerMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
player = new THREE.Mesh(playerGeometry, playerMaterial);
player.position.y = -10;
scene.add(player);
spawnEnemies();
spawnObstacles();
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
window.addEventListener('keydown', onKeyDown);
window.addEventListener('keyup', onKeyUp);
window.addEventListener('resize', onWindowResize);
animate();
}
function spawnEnemies() {
const enemyGeometry = new THREE.BoxGeometry(0.8, 0.8, 0.8);
const enemyMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 3; j++) {
const enemy = new THREE.Mesh(enemyGeometry, enemyMaterial);
enemy.position.set(i * 2 - 4, j * 2 + 5, 0);
enemies.push(enemy);
scene.add(enemy);
}
}
}
function spawnObstacles() {
const obstacleGeometry = new THREE.BoxGeometry(2, 2, 2);
const obstacleMaterial = new THREE.MeshBasicMaterial({ color: 0x808080 });
for (let i = 0; i < 3; i++) {
const obstacle = new THREE.Mesh(obstacleGeometry, obstacleMaterial);
obstacle.position.set(Math.random() * 20 - 10, Math.random() * 10, 0);
obstacles.push(obstacle);
scene.add(obstacle);
}
}
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) {
const speed = 10;
if (moveLeft && player.position.x > -15) player.position.x -= speed * delta;
if (moveRight && player.position.x < 15) player.position.x += speed * delta;
if (moveUp && player.position.y < 0) player.position.y += speed * delta;
if (moveDown && player.position.y > -15) 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.y += 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.y += bulletSpeed * delta;
if (bullets[i].position.y > 20) {
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);
break;
}
}
}
function updateEnemies(delta) {
const enemySpeed = 2;
enemies.forEach(enemy => {
enemy.position.y -= enemySpeed * delta;
if (enemy.position.y < -15) enemy.position.y = 15;
});
}
function updateObstacles(delta) {
const obstacleSpeed = 1;
obstacles.forEach(obstacle => {
obstacle.position.y -= obstacleSpeed * delta;
if (obstacle.position.y < -15) obstacle.position.y = 15;
});
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
updatePlayer(delta);
updateBullets(delta);
updateEnemies(delta);
updateObstacles(delta);
renderer.render(scene, camera);
}
init();
</script>
</body>
</html>
"""
# Streamlit app
st.title("Galaxxon - A Three.js Arcade Game")
st.write("Use WASD or Arrow Keys to move, Spacebar to shoot. Destroy red enemies and avoid gray obstacles!")
# 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.")