awacke1 commited on
Commit
45f7f6d
·
verified ·
1 Parent(s): c83e1a9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +97 -53
app.py CHANGED
@@ -1,7 +1,7 @@
1
  import streamlit as st
2
  from streamlit.components.v1 import html
3
 
4
- # Define the p5.js sketch code as a string
5
  p5js_code = """
6
  let gridSize = 40;
7
  let grid = [];
@@ -10,6 +10,7 @@ let train = { x: 0, y: 0, dir: 1 };
10
  let monsterMode = false;
11
  let currentMonster = 'Godzilla';
12
  let monsterX, monsterY;
 
13
 
14
  function setup() {
15
  createCanvas(800, 600);
@@ -41,15 +42,15 @@ function drawGrid() {
41
  for (let j = 0; j < grid[i].length; j++) {
42
  let x = i * gridSize;
43
  let y = j * gridSize;
44
- if (grid[i][j] === 'track') {
45
- fill(100);
46
- rect(x, y, gridSize, gridSize);
47
- } else {
48
- fill(150, 200, 150);
49
- rect(x, y, gridSize, gridSize);
50
- }
51
  stroke(0);
52
- rect(x, y, gridSize, gridSize);
 
 
 
 
 
53
  }
54
  }
55
  }
@@ -58,49 +59,68 @@ function drawBuildings() {
58
  buildings.forEach(b => {
59
  let x = b.x * gridSize;
60
  let y = b.y * gridSize;
 
61
  fill(b.color);
62
  noStroke();
63
  beginShape();
64
- if (b.type === 'Residential') {
65
- vertex(x + 10, y + 30); vertex(x + 20, y + 10); vertex(x + 30, y + 30);
66
- vertex(x + 25, y + 30); vertex(x + 25, y + 35); vertex(x + 15, y + 35);
67
- vertex(x + 15, y + 30);
68
- } else if (b.type === 'Commercial') {
69
- vertex(x + 10, y + 35); vertex(x + 15, y + 15); vertex(x + 25, y + 15);
70
- vertex(x + 30, y + 35);
71
- } else if (b.type === 'Industrial') {
72
- vertex(x + 5, y + 35); vertex(x + 15, y + 20); vertex(x + 25, y + 20);
73
- vertex(x + 35, y + 35);
 
 
 
 
 
 
 
 
 
 
74
  }
75
  endShape(CLOSE);
76
  });
77
  }
78
 
79
  function drawTrain() {
 
 
 
80
  fill(150, 50, 50);
81
  noStroke();
82
  beginShape();
83
- let tx = train.x;
84
- let ty = train.y;
85
- vertex(tx + 10, ty + 10); vertex(tx + 30, ty + 10); vertex(tx + 35, ty + 20);
86
- vertex(tx + 30, ty + 30); vertex(tx + 10, ty + 30); vertex(tx + 5, ty + 20);
87
  endShape(CLOSE);
88
  train.x += train.dir * 2;
89
  if (train.x > width || train.x < 0) train.dir *= -1;
90
  }
91
 
92
  function drawMonster() {
93
- fill(monsterMode ? 255 : 0, 0, 0);
 
94
  noStroke();
95
  beginShape();
96
- if (currentMonster === 'Godzilla') {
97
- vertex(monsterX, monsterY + 40); vertex(monsterX + 20, monsterY);
98
- vertex(monsterX + 40, monsterY + 40); vertex(monsterX + 30, monsterY + 50);
99
- vertex(monsterX + 10, monsterY + 50);
100
- } else if (currentMonster === 'GiantRobot') {
101
- vertex(monsterX, monsterY + 40); vertex(monsterX + 10, monsterY);
102
- vertex(monsterX + 30, monsterY); vertex(monsterX + 40, monsterY + 40);
103
- vertex(monsterX + 20, monsterY + 50);
 
 
 
 
104
  }
105
  endShape(CLOSE);
106
  monsterX += random(-5, 5);
@@ -113,21 +133,24 @@ function mousePressed() {
113
  let i = floor(mouseX / gridSize);
114
  let j = floor(mouseY / gridSize);
115
  if (grid[i][j] === 'empty' && !monsterMode) {
116
- let types = ['Residential', 'Commercial', 'Industrial'];
117
- let colors = [[0, 200, 0], [0, 0, 200], [200, 200, 0]];
118
- let idx = floor(random(3));
119
  buildings.push({ x: i, y: j, type: types[idx], color: colors[idx] });
120
  grid[i][j] = 'building';
121
  }
122
  }
123
 
124
- window.toggleMonsterMode = function() {
125
- monsterMode = !monsterMode;
126
- };
 
 
 
127
 
128
- window.setMonster = function(monster) {
129
- currentMonster = monster;
130
- };
131
  """
132
 
133
  # Full HTML content with embedded p5.js
@@ -146,30 +169,51 @@ html_content = f"""
146
  </head>
147
  <body>
148
  <div id="controls">
149
- <button onclick="toggleMonster()">Toggle Monster Mode</button>
150
  <select onchange="setMonster(this.value)">
151
- <option value="Godzilla">Godzilla</option>
152
- <option value="GiantRobot">Giant Robot</option>
153
  </select>
 
154
  </div>
155
  <div id="sketch-holder"></div>
156
 
157
  <script>
158
  {p5js_code}
159
 
160
- function toggleMonster() {{
161
- window.toggleMonsterMode();
162
- }}
163
-
164
- function setMonster(monster) {{
165
- window.setMonster(monster);
166
- }}
167
  </script>
168
  </body>
169
  </html>
170
  """
171
 
172
- # Streamlit app
173
  st.title("SimCity 2000 with Monster Mode")
174
- st.write("Build your city and unleash a monster! Click to place buildings.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  html(html_content, height=700)
 
1
  import streamlit as st
2
  from streamlit.components.v1 import html
3
 
4
+ # Define the enhanced p5.js sketch code as a string
5
  p5js_code = """
6
  let gridSize = 40;
7
  let grid = [];
 
10
  let monsterMode = false;
11
  let currentMonster = 'Godzilla';
12
  let monsterX, monsterY;
13
+ let angle = PI / 6; // 3D perspective angle
14
 
15
  function setup() {
16
  createCanvas(800, 600);
 
42
  for (let j = 0; j < grid[i].length; j++) {
43
  let x = i * gridSize;
44
  let y = j * gridSize;
45
+ let z = j * gridSize * sin(angle); // 3D depth effect
46
+ fill(grid[i][j] === 'track' ? 100 : 150, 200, 150);
 
 
 
 
 
47
  stroke(0);
48
+ beginShape();
49
+ vertex(x, y - z);
50
+ vertex(x + gridSize, y - z);
51
+ vertex(x + gridSize * cos(angle), y + gridSize * sin(angle) - z);
52
+ vertex(x + gridSize * (1 - cos(angle)), y + gridSize * sin(angle) - z);
53
+ endShape(CLOSE);
54
  }
55
  }
56
  }
 
59
  buildings.forEach(b => {
60
  let x = b.x * gridSize;
61
  let y = b.y * gridSize;
62
+ let z = b.y * gridSize * sin(angle);
63
  fill(b.color);
64
  noStroke();
65
  beginShape();
66
+ if (b.type === 'Residential') { // House with chimney
67
+ vertex(x + 10, y + 30 - z); vertex(x + 20, y + 10 - z); vertex(x + 30, y + 30 - z);
68
+ vertex(x + 25, y + 30 - z); vertex(x + 25, y + 35 - z); vertex(x + 15, y + 35 - z);
69
+ vertex(x + 15, y + 30 - z); vertex(x + 17, y + 25 - z); vertex(x + 23, y + 25 - z);
70
+ } else if (b.type === 'Commercial') { // Skyscraper with windows
71
+ vertex(x + 10, y + 35 - z); vertex(x + 15, y + 15 - z); vertex(x + 25, y + 15 - z);
72
+ vertex(x + 30, y + 35 - z); vertex(x + 27, y + 35 - z); vertex(x + 27, y + 20 - z);
73
+ vertex(x + 13, y + 20 - z); vertex(x + 13, y + 35 - z);
74
+ } else if (b.type === 'Industrial') { // Factory with smokestack
75
+ vertex(x + 5, y + 35 - z); vertex(x + 15, y + 20 - z); vertex(x + 25, y + 20 - z);
76
+ vertex(x + 35, y + 35 - z); vertex(x + 30, y + 35 - z); vertex(x + 30, y + 15 - z);
77
+ vertex(x + 33, y + 15 - z); vertex(x + 33, y + 35 - z);
78
+ } else if (b.type === 'School') { // School with flagpole
79
+ vertex(x + 5, y + 35 - z); vertex(x + 10, y + 20 - z); vertex(x + 30, y + 20 - z);
80
+ vertex(x + 35, y + 35 - z); vertex(x + 25, y + 35 - z); vertex(x + 25, y + 10 - z);
81
+ vertex(x + 27, y + 10 - z); vertex(x + 27, y + 35 - z);
82
+ } else if (b.type === 'PowerPlant') { // Power plant with turbines
83
+ vertex(x + 5, y + 35 - z); vertex(x + 15, y + 15 - z); vertex(x + 25, y + 15 - z);
84
+ vertex(x + 35, y + 35 - z); vertex(x + 30, y + 35 - z); vertex(x + 30, y + 25 - z);
85
+ vertex(x + 20, y + 25 - z); vertex(x + 20, y + 35 - z);
86
  }
87
  endShape(CLOSE);
88
  });
89
  }
90
 
91
  function drawTrain() {
92
+ let tx = train.x;
93
+ let ty = train.y;
94
+ let tz = train.y * sin(angle);
95
  fill(150, 50, 50);
96
  noStroke();
97
  beginShape();
98
+ vertex(tx + 10, ty + 10 - tz); vertex(tx + 30, ty + 10 - tz); vertex(tx + 35, ty + 20 - tz);
99
+ vertex(tx + 30, ty + 30 - tz); vertex(tx + 10, ty + 30 - tz); vertex(tx + 5, ty + 20 - tz);
100
+ vertex(tx + 15, ty + 20 - tz); vertex(tx + 15, ty + 15 - tz); vertex(tx + 25, ty + 15 - tz);
101
+ vertex(tx + 25, ty + 20 - tz);
102
  endShape(CLOSE);
103
  train.x += train.dir * 2;
104
  if (train.x > width || train.x < 0) train.dir *= -1;
105
  }
106
 
107
  function drawMonster() {
108
+ let mz = monsterY * sin(angle);
109
+ fill(255, 0, 0);
110
  noStroke();
111
  beginShape();
112
+ if (currentMonster === 'Godzilla') { // Detailed Godzilla with spines
113
+ vertex(monsterX, monsterY + 40 - mz); vertex(monsterX + 10, monsterY + 20 - mz);
114
+ vertex(monsterX + 20, monsterY - mz); vertex(monsterX + 30, monsterY + 20 - mz);
115
+ vertex(monsterX + 40, monsterY + 40 - mz); vertex(monsterX + 35, monsterY + 50 - mz);
116
+ vertex(monsterX + 25, monsterY + 60 - mz); vertex(monsterX + 15, monsterY + 50 - mz);
117
+ vertex(monsterX + 20, monsterY + 40 - mz); vertex(monsterX + 25, monsterY + 30 - mz);
118
+ } else if (currentMonster === 'GiantRobot') { // Detailed Robot with joints
119
+ vertex(monsterX, monsterY + 40 - mz); vertex(monsterX + 10, monsterY + 20 - mz);
120
+ vertex(monsterX + 15, monsterY - mz); vertex(monsterX + 25, monsterY - mz);
121
+ vertex(monsterX + 30, monsterY + 20 - mz); vertex(monsterX + 40, monsterY + 40 - mz);
122
+ vertex(monsterX + 35, monsterY + 50 - mz); vertex(monsterX + 20, monsterY + 60 - mz);
123
+ vertex(monsterX + 5, monsterY + 50 - mz); vertex(monsterX + 15, monsterY + 30 - mz);
124
  }
125
  endShape(CLOSE);
126
  monsterX += random(-5, 5);
 
133
  let i = floor(mouseX / gridSize);
134
  let j = floor(mouseY / gridSize);
135
  if (grid[i][j] === 'empty' && !monsterMode) {
136
+ let types = ['Residential', 'Commercial', 'Industrial', 'School', 'PowerPlant'];
137
+ let colors = [[0, 200, 0], [0, 0, 200], [200, 200, 0], [200, 0, 200], [100, 100, 100]];
138
+ let idx = floor(random(5));
139
  buildings.push({ x: i, y: j, type: types[idx], color: colors[idx] });
140
  grid[i][j] = 'building';
141
  }
142
  }
143
 
144
+ function keyPressed() {
145
+ if (key === 'm' || key === 'M') monsterMode = !monsterMode;
146
+ if (key === 'g' || key === 'G') currentMonster = 'Godzilla';
147
+ if (key === 'r' || key === 'R') currentMonster = 'GiantRobot';
148
+ if (key === 't' || key === 'T') train.dir *= -1;
149
+ }
150
 
151
+ window.toggleMonsterMode = function() { monsterMode = !monsterMode; };
152
+ window.setMonster = function(monster) { currentMonster = monster; };
153
+ window.reverseTrain = function() { train.dir *= -1; };
154
  """
155
 
156
  # Full HTML content with embedded p5.js
 
169
  </head>
170
  <body>
171
  <div id="controls">
172
+ <button onclick="toggleMonster()">Toggle Monster Mode (M)</button>
173
  <select onchange="setMonster(this.value)">
174
+ <option value="Godzilla">Godzilla (G)</option>
175
+ <option value="GiantRobot">Giant Robot (R)</option>
176
  </select>
177
+ <button onclick="reverseTrain()">Reverse Train (T)</button>
178
  </div>
179
  <div id="sketch-holder"></div>
180
 
181
  <script>
182
  {p5js_code}
183
 
184
+ function toggleMonster() {{ window.toggleMonsterMode(); }}
185
+ function setMonster(monster) {{ window.setMonster(monster); }}
186
+ function reverseTrain() {{ window.reverseTrain(); }}
 
 
 
 
187
  </script>
188
  </body>
189
  </html>
190
  """
191
 
192
+ # Streamlit app with sidebar
193
  st.title("SimCity 2000 with Monster Mode")
194
+ st.write("Click to place buildings. Use keys: M (monster), G (Godzilla), R (Robot), T (train reverse).")
195
+
196
+ # Sidebar with emoji-grouped controls
197
+ with st.sidebar:
198
+ st.header("Controls")
199
+
200
+ # Building Controls
201
+ st.subheader("🏡 Buildings")
202
+ st.write("Click on the grid to randomly place buildings (Residential, Commercial, Industrial, School, Power Plant).")
203
+
204
+ # Monster Controls
205
+ st.subheader("👾 Monsters")
206
+ if st.button("Toggle Monster Mode (M)", key="monster_toggle"):
207
+ st.markdown('<script>toggleMonster()</script>', unsafe_allow_html=True)
208
+ monster_choice = st.selectbox("Choose Monster", ["Godzilla (G)", "Giant Robot (R)"], index=0)
209
+ if monster_choice.startswith("Godzilla"):
210
+ st.markdown('<script>setMonster("Godzilla")</script>', unsafe_allow_html=True)
211
+ else:
212
+ st.markdown('<script>setMonster("GiantRobot")</script>', unsafe_allow_html=True)
213
+
214
+ # Train Controls
215
+ st.subheader("🚂 Train")
216
+ if st.button("Reverse Train (T)", key="train_reverse"):
217
+ st.markdown('<script>reverseTrain()</script>', unsafe_allow_html=True)
218
+
219
  html(html_content, height=700)