Spaces:
Sleeping
Sleeping
import streamlit as st | |
from streamlit.components.v1 import html | |
# Define the p5.js sketch code as a string | |
p5js_code = """ | |
let gridSize = 40; | |
let grid = []; | |
let buildings = []; | |
let train = { x: 0, y: 0, dir: 1 }; | |
let monsterMode = false; | |
let currentMonster = 'Godzilla'; | |
let monsterX, monsterY; | |
function setup() { | |
createCanvas(800, 600); | |
for (let i = 0; i < width / gridSize; i++) { | |
grid[i] = []; | |
for (let j = 0; j < height / gridSize; j++) { | |
grid[i][j] = 'empty'; | |
} | |
} | |
for (let i = 0; i < width / gridSize; i++) { | |
grid[i][5] = 'track'; | |
} | |
train.x = 0; | |
train.y = 5 * gridSize; | |
monsterX = width / 2; | |
monsterY = height / 2; | |
} | |
function draw() { | |
background(220); | |
drawGrid(); | |
drawBuildings(); | |
drawTrain(); | |
if (monsterMode) drawMonster(); | |
} | |
function drawGrid() { | |
for (let i = 0; i < grid.length; i++) { | |
for (let j = 0; j < grid[i].length; j++) { | |
let x = i * gridSize; | |
let y = j * gridSize; | |
if (grid[i][j] === 'track') { | |
fill(100); | |
rect(x, y, gridSize, gridSize); | |
} else { | |
fill(150, 200, 150); | |
rect(x, y, gridSize, gridSize); | |
} | |
stroke(0); | |
rect(x, y, gridSize, gridSize); | |
} | |
} | |
} | |
function drawBuildings() { | |
buildings.forEach(b => { | |
let x = b.x * gridSize; | |
let y = b.y * gridSize; | |
fill(b.color); | |
noStroke(); | |
beginShape(); | |
if (b.type === 'Residential') { | |
vertex(x + 10, y + 30); vertex(x + 20, y + 10); vertex(x + 30, y + 30); | |
vertex(x + 25, y + 30); vertex(x + 25, y + 35); vertex(x + 15, y + 35); | |
vertex(x + 15, y + 30); | |
} else if (b.type === 'Commercial') { | |
vertex(x + 10, y + 35); vertex(x + 15, y + 15); vertex(x + 25, y + 15); | |
vertex(x + 30, y + 35); | |
} else if (b.type === 'Industrial') { | |
vertex(x + 5, y + 35); vertex(x + 15, y + 20); vertex(x + 25, y + 20); | |
vertex(x + 35, y + 35); | |
} | |
endShape(CLOSE); | |
}); | |
} | |
function drawTrain() { | |
fill(150, 50, 50); | |
noStroke(); | |
beginShape(); | |
let tx = train.x; | |
let ty = train.y; | |
vertex(tx + 10, ty + 10); vertex(tx + 30, ty + 10); vertex(tx + 35, ty + 20); | |
vertex(tx + 30, ty + 30); vertex(tx + 10, ty + 30); vertex(tx + 5, ty + 20); | |
endShape(CLOSE); | |
train.x += train.dir * 2; | |
if (train.x > width || train.x < 0) train.dir *= -1; | |
} | |
function drawMonster() { | |
fill(monsterMode ? 255 : 0, 0, 0); | |
noStroke(); | |
beginShape(); | |
if (currentMonster === 'Godzilla') { | |
vertex(monsterX, monsterY + 40); vertex(monsterX + 20, monsterY); | |
vertex(monsterX + 40, monsterY + 40); vertex(monsterX + 30, monsterY + 50); | |
vertex(monsterX + 10, monsterY + 50); | |
} else if (currentMonster === 'GiantRobot') { | |
vertex(monsterX, monsterY + 40); vertex(monsterX + 10, monsterY); | |
vertex(monsterX + 30, monsterY); vertex(monsterX + 40, monsterY + 40); | |
vertex(monsterX + 20, monsterY + 50); | |
} | |
endShape(CLOSE); | |
monsterX += random(-5, 5); | |
monsterY += random(-5, 5); | |
monsterX = constrain(monsterX, 0, width); | |
monsterY = constrain(monsterY, 0, height); | |
} | |
function mousePressed() { | |
let i = floor(mouseX / gridSize); | |
let j = floor(mouseY / gridSize); | |
if (grid[i][j] === 'empty' && !monsterMode) { | |
let types = ['Residential', 'Commercial', 'Industrial']; | |
let colors = [[0, 200, 0], [0, 0, 200], [200, 200, 0]]; | |
let idx = floor(random(3)); | |
buildings.push({ x: i, y: j, type: types[idx], color: colors[idx] }); | |
grid[i][j] = 'building'; | |
} | |
} | |
window.toggleMonsterMode = function() { | |
monsterMode = !monsterMode; | |
}; | |
window.setMonster = function(monster) { | |
currentMonster = monster; | |
}; | |
""" | |
# Full HTML content with embedded p5.js | |
html_content = f""" | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.2/p5.min.js"></script> | |
<style> | |
body {{ font-family: Arial, sans-serif; margin: 0; padding: 20px; background: #f0f0f0; }} | |
#controls {{ margin-bottom: 20px; }} | |
button {{ padding: 10px 20px; margin: 5px; background: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer; }} | |
button:hover {{ background: #45a049; }} | |
select {{ padding: 10px; margin: 5px; border-radius: 5px; }} | |
</style> | |
</head> | |
<body> | |
<div id="controls"> | |
<button onclick="toggleMonster()">Toggle Monster Mode</button> | |
<select onchange="setMonster(this.value)"> | |
<option value="Godzilla">Godzilla</option> | |
<option value="GiantRobot">Giant Robot</option> | |
</select> | |
</div> | |
<div id="sketch-holder"></div> | |
<script> | |
{p5js_code} | |
function toggleMonster() {{ | |
window.toggleMonsterMode(); | |
}} | |
function setMonster(monster) {{ | |
window.setMonster(monster); | |
}} | |
</script> | |
</body> | |
</html> | |
""" | |
# Streamlit app | |
st.title("SimCity 2000 with Monster Mode") | |
st.write("Build your city and unleash a monster! Click to place buildings.") | |
html(html_content, height=700) |