lineages / app.py
ewebspace's picture
Create app.py
bf05a7d verified
import gradio as gr
import json
import random
import math
import numpy as np
# ================== ГЛОБАЛЬНЫЕ НАСТРОЙКИ ==================
UNIVERSE_SEED = 42
RESOURCE_TYPES = ['Iron', 'Copper', 'Gold', 'Water', 'Oxygen', 'Hydrogen', 'Silicon', 'Titanium']
CIVILIZATION_STAGES = [
{"title": "I. Биологический", "color": "#00cc44", "desc": "Углеродно-водные формы жизни..."},
{"title": "II. Техногенный", "color": "#00aaff", "desc": "Промышленная и цифровая революция..."},
{"title": "III. Постбиологический", "color": "#ff7700", "desc": "Переход к цифровому существованию..."},
{"title": "IV. Космический", "color": "#aa55ff", "desc": "Межзвездные путешествия..."},
{"title": "V. Универсальный", "color": "#ffff00", "desc": "Слияние с космическим разумом..."}
]
# ================== ГЕНЕРАТОР ВСЕЛЕННОЙ ==================
class UniverseGenerator:
def __init__(self, seed=UNIVERSE_SEED):
self.rng = random.Random(seed)
self.planet_types = ['Lava', 'Ocean', 'Desert', 'Ice', 'Jungle']
def generate_planet(self, index):
return {
'name': f"Planet-{chr(65 + index)}",
'type': self.rng.choice(self.planet_types),
'resources': self.rng.sample(RESOURCE_TYPES, self.rng.randint(2, 5)),
'size': self.rng.uniform(0.8, 1.5),
'habitability': round(self.rng.uniform(0.1, 0.9), 2)
}
def generate_system(self, index):
return {
'name': f"System-{index}",
'planets': [self.generate_planet(i) for i in range(self.rng.randint(3, 6))]
}
def generate_universe(self):
return {
'systems': [self.generate_system(i) for i in range(3)],
'civilization_stages': CIVILIZATION_STAGES
}
# ================== THREE.JS ШАБЛОНЫ ==================
CIVILIZATION_TEMPLATE = """
<!DOCTYPE html>
<html>
<head>
<title>Эволюция Цивилизаций</title>
<style>
body {{
margin: 0;
overflow: hidden;
background: #001133;
color: white;
font-family: Arial, sans-serif;
}}
#infoBox {{
position: absolute;
top: 20px;
left: 20px;
max-width: 350px;
background: rgba(0, 0, 20, 0.85);
padding: 20px;
border-radius: 15px;
border: 1px solid #4a6fff;
display: none;
}}
#title {{
position: absolute;
top: 20px;
width: 100%;
text-align: center;
font-size: 24px;
color: #4fc3f7;
text-shadow: 0 0 15px rgba(79, 195, 247, 0.8);
pointer-events: none;
}}
</style>
</head>
<body>
<div id="title">ЭВОЛЮЦИЯ ЦИВИЛИЗАЦИЙ ВО ВСЕЛЕННОЙ</div>
<div id="infoBox">
<h2 id="stageTitle"></h2>
<p id="stageDesc"></p>
</div>
<script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.132.2/examples/js/controls/OrbitControls.min.js"></script>
<script>
// Инициализация сцены
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x001122);
const camera = new THREE.PerspectiveCamera(60, window.innerWidth/window.innerHeight, 0.1, 2000);
const renderer = new THREE.WebGLRenderer({{ antialias: true }});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Настройка камеры и освещения
camera.position.set(0, 15, 50);
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
// Создание звездного поля
const starGeometry = new THREE.BufferGeometry();
const starPositions = new Float32Array(5000 * 3);
for (let i = 0; i < 5000; i++) {{
starPositions[i*3] = (Math.random() - 0.5) * 2000;
starPositions[i*3+1] = (Math.random() - 0.5) * 2000;
starPositions[i*3+2] = (Math.random() - 0.5) * 2000;
}}
starGeometry.setAttribute('position', new THREE.BufferAttribute(starPositions, 3));
const stars = new THREE.Points(starGeometry, new THREE.PointsMaterial({{ color: 0xffffff, size: 1.5 }}));
scene.add(stars);
// Создание сфер цивилизаций
const stages = {civilization_stages};
const spheres = [];
stages.forEach((stage, i) => {{
const geometry = new THREE.SphereGeometry(4, 32, 32);
const material = new THREE.MeshStandardMaterial({{
color: new THREE.Color(stage.color),
emissive: new THREE.Color(stage.color),
metalness: 0.7,
roughness: 0.2
}});
const sphere = new THREE.Mesh(geometry, material);
sphere.position.x = (i - stages.length/2) * 15;
sphere.userData = stage;
scene.add(sphere);
spheres.push(sphere);
}});
// Интерактивность
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
const infoBox = document.getElementById("infoBox");
window.addEventListener("click", (event) => {{
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(spheres);
if (intersects.length > 0) {{
const stage = intersects[0].object.userData;
document.getElementById("stageTitle").textContent = stage.title;
document.getElementById("stageDesc").textContent = stage.desc;
infoBox.style.display = "block";
}}
}});
// Анимация
function animate() {{
requestAnimationFrame(animate);
spheres.forEach((sphere, i) => {{
sphere.rotation.y += 0.01;
sphere.rotation.x += 0.005;
}});
controls.update();
renderer.render(scene, camera);
}}
animate();
// Адаптация под размер окна
window.addEventListener("resize", () => {{
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}});
</script>
</body>
</html>
"""
SPACE_EXPLORER_TEMPLATE = """
<!DOCTYPE html>
<html>
<head>
<title>Космический Исследователь</title>
<style>
body {{
margin: 0;
overflow: hidden;
background: #000;
font-family: Arial, sans-serif;
}}
#ui {{
position: absolute;
top: 20px;
left: 20px;
color: white;
background: rgba(0, 0, 0, 0.7);
padding: 15px;
border-radius: 10px;
width: 300px;
}}
.bar-container {{ width: 100%; background: #333; border-radius: 5px; margin: 5px 0; }}
.bar {{ height: 20px; border-radius: 5px; text-align: center; color: white; }}
.health-bar {{ background: linear-gradient(to right, #ff0000, #00ff00); }}
.fuel-bar {{ background: linear-gradient(to right, #0000ff, #00ffff); }}
#planet-info {{
position: absolute;
top: 20px;
right: 20px;
background: rgba(0, 0, 0, 0.7);
padding: 15px;
border-radius: 10px;
color: white;
display: none;
}}
</style>
</head>
<body>
<div id="ui">
<h3>Космический Корабль</h3>
<div>Здоровье: <span id="health-value">100</span>/100</div>
<div class="bar-container"><div id="health-bar" class="bar health-bar" style="width: 100%"></div></div>
<div>Топливо: <span id="fuel-value">100</span>/100</div>
<div class="bar-container"><div id="fuel-bar" class="bar fuel-bar" style="width: 100%"></div></div>
</div>
<div id="planet-info">
<h3 id="planet-name"></h3>
<div>Тип: <span id="planet-type"></span></div>
<div>Ресурсы: <span id="planet-resources"></span></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.132.2/examples/js/controls/OrbitControls.min.js"></script>
<script>
// Инициализация сцены
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x000010);
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({{ antialias: true }});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Освещение
const ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(1, 1, 1);
scene.add(directionalLight);
// Корабль игрока
const shipGeometry = new THREE.ConeGeometry(1, 3, 8);
const shipMaterial = new THREE.MeshPhongMaterial({{ color: 0x00aaff }});
const ship = new THREE.Mesh(shipGeometry, shipMaterial);
ship.rotation.x = Math.PI / 2;
scene.add(ship);
// Планеты
const planets = [];
const universeData = {universe_data};
universeData.systems[0].planets.forEach((planet, i) => {{
const geometry = new THREE.SphereGeometry(planet.size, 32, 32);
const material = new THREE.MeshStandardMaterial({{
color: new THREE.Color(
planet.type === 'Lava' ? 0xff3300 :
planet.type === 'Ocean' ? 0x0066ff :
planet.type === 'Desert' ? 0xffcc00 :
0x888888
),
roughness: 0.8,
metalness: 0.2
}});
const planetMesh = new THREE.Mesh(geometry, material);
planetMesh.position.x = i * 15 - 30;
planetMesh.userData = planet;
scene.add(planetMesh);
planets.push(planetMesh);
}});
// Управление кораблем
const keys = {{}};
window.addEventListener('keydown', (e) => keys[e.key.toLowerCase()] = true);
window.addEventListener('keyup', (e) => keys[e.key.toLowerCase()] = false);
// Анимация
function animate() {{
requestAnimationFrame(animate);
// Движение корабля
if (keys['w']) ship.position.z -= 0.1;
if (keys['s']) ship.position.z += 0.1;
if (keys['a']) ship.position.x -= 0.1;
if (keys['d']) ship.position.x += 0.1;
// Обновление камеры
camera.position.x = ship.position.x;
camera.position.y = ship.position.y + 5;
camera.position.z = ship.position.z + 15;
camera.lookAt(ship.position);
renderer.render(scene, camera);
}}
animate();
// Адаптация под размер окна
window.addEventListener('resize', () => {{
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}});
</script>
</body>
</html>
"""
# ================== GRADIO ИНТЕРФЕЙС ==================
def create_civilization_demo():
universe = UniverseGenerator().generate_universe()
template = CIVILIZATION_TEMPLATE.replace("{civilization_stages}", json.dumps(universe["civilization_stages"]))
return template
def create_space_explorer_demo():
universe = UniverseGenerator().generate_universe()
template = SPACE_EXPLORER_TEMPLATE.replace("{universe_data}", json.dumps(universe))
return template
with gr.Blocks(title="Космические Игры", css=".gradio-container {background: #000033;}") as demo:
gr.Markdown("# 🌌 Две Космические Игры")
gr.Markdown("### Исследуйте эволюцию цивилизаций и космические просторы")
with gr.Tabs():
with gr.TabItem("Эволюция Цивилизаций"):
civ_html = gr.HTML(create_civilization_demo())
gr.Markdown("""
**Инструкции:**
- Кликните на сферы, чтобы узнать о стадиях развития цивилизаций
- Используйте мышь для вращения камеры
""")
with gr.TabItem("Космический Исследователь"):
space_html = gr.HTML(create_space_explorer_demo())
gr.Markdown("""
**Управление:**
- W/S: Движение вперед/назад
- A/D: Движение влево/вправо
- Мышь: Управление камерой
""")
gr.Markdown("### Общие игровые системы:")
with gr.Accordion("Технические детали", open=False):
gr.Markdown("""
**Общие компоненты:**
1. **Генерация вселенной**: Процедурное создание планет и систем
2. **Three.js рендеринг**: Реалистичное 3D отображение космоса
3. **Интерактивные элементы**: Взаимодействие с объектами через UI
4. **Физика движения**: Реалистичное управление космическим кораблем
""")
if __name__ == "__main__":
demo.launch()