awacke1's picture
Create app.py
c83e1a9 verified
raw
history blame
4.86 kB
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)