joaomaia commited on
Commit
6314965
·
1 Parent(s): 0cb21bd

Add game files and setup for Streamlit deployment

Browse files
Files changed (7) hide show
  1. app.py +13 -0
  2. assets/beep.WAV +0 -0
  3. assets/high_scores.txt +10 -0
  4. assets/img0.PNG +0 -0
  5. assets/questions.xlsx +0 -0
  6. game.py +433 -0
  7. requirements.txt +4 -0
app.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import subprocess
3
+
4
+ def main():
5
+ st.title('A Jornada do Discípulo')
6
+
7
+ if st.button('Iniciar Jogo'):
8
+ st.write("O jogo será iniciado em uma nova janela.")
9
+ process = subprocess.Popen(["python", "game_huggingface.py"])
10
+ process.communicate()
11
+
12
+ if __name__ == "__main__":
13
+ main()
assets/beep.WAV ADDED
Binary file (336 kB). View file
 
assets/high_scores.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ 300,2024-07-25 00:51:28
2
+ 281,2024-07-25 01:32:56
3
+ 265,2024-07-25 01:27:30
4
+ 250,2024-07-25 01:20:13
5
+ 92,2024-07-25 02:01:36
6
+ 33,2024-07-25 01:48:32
7
+ 31,2024-07-25 00:01:11
8
+ 29,2024-07-24 23:51:36
9
+ 25,2024-07-24 23:45:54
10
+ 25,2024-07-25 01:12:04
assets/img0.PNG ADDED
assets/questions.xlsx ADDED
Binary file (16.8 kB). View file
 
game.py ADDED
@@ -0,0 +1,433 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pygame
2
+ import random
3
+ import time
4
+ import pandas as pd
5
+
6
+ # Inicializa o Pygame
7
+ pygame.init()
8
+
9
+ # Configurações da tela
10
+ screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
11
+ screen_width, screen_height = screen.get_size()
12
+ pygame.display.set_caption("A Jornada do Discípulo")
13
+
14
+ # Cores
15
+ white = (255, 255, 255)
16
+ black = (0, 0, 0)
17
+ green = (0, 255, 0)
18
+ red = (255, 0, 0)
19
+ yellow = (255, 255, 0)
20
+
21
+ # Configurações do jogo
22
+ high_scores = []
23
+ score_file = "high_scores.txt"
24
+ question_file = "questions.xlsx"
25
+ beep_sound = "beep.wav"
26
+ congratulations_image_file = "img0.png" # Caminho para a imagem de parabéns
27
+ score_decrement_interval = 5 # Intervalo de tempo em segundos para subtrair pontos do score
28
+ player_base_speed = 5 # Velocidade base do jogador
29
+ player_speed_increment = 0.5 # Incremento de velocidade do jogador
30
+ player_speed = player_base_speed # Velocidade atual do jogador
31
+ player_radius = 25 # Raio inicial do jogador
32
+ correct_answers_streak = 0 # Contador de perguntas corretas consecutivas
33
+ correct_answers = 0 # Contador total de perguntas corretas
34
+ player_velocity = pygame.math.Vector2(0, 0) # Velocidade inicial do jogador
35
+ game_start_time = 0 # Tempo inicial da partida
36
+ start_time = 0 # Tempo inicial para o cronômetro de score
37
+ questions = [] # Lista de perguntas
38
+ answered_questions = set() # Perguntas já respondidas corretamente
39
+ collision_count = 0 # Contador de colisões com obstáculos
40
+
41
+ # Carregar som de beep
42
+ pygame.mixer.init()
43
+ beep = pygame.mixer.Sound(beep_sound)
44
+
45
+ # Carregar a imagem de parabéns
46
+ congratulations_image = pygame.image.load(congratulations_image_file)
47
+ congratulations_image = pygame.transform.scale(congratulations_image, (screen_width, screen_height))
48
+
49
+ # Semente aleatória para garantir aleatoriedade
50
+ random.seed(time.time())
51
+
52
+ def load_high_scores():
53
+ try:
54
+ with open(score_file, "r", encoding="utf-8") as f:
55
+ return [line.strip().split(",") for line in f.readlines() if line.strip()]
56
+ except FileNotFoundError:
57
+ return []
58
+
59
+ def save_high_scores(scores):
60
+ with open(score_file, "w", encoding="utf-8") as f:
61
+ for score, date in scores:
62
+ f.write(f"{score},{date}\n")
63
+
64
+ def load_questions():
65
+ global questions
66
+ try:
67
+ df = pd.read_excel(question_file)
68
+ questions = df.to_dict(orient="records")
69
+ except FileNotFoundError:
70
+ questions = [
71
+ {"pergunta": "Qual é o maior mandamento?", "opcao_1": "Amar a Deus sobre todas as coisas", "opcao_2": "Não matar", "opcao_3": "Guardar o sábado", "opcao_4": "Não roubar", "resposta": "1"}
72
+ ]
73
+
74
+ def draw_text(screen, text, size, x, y, align="center", max_width=None):
75
+ font = pygame.font.Font(pygame.font.match_font('arial'), size)
76
+ if max_width:
77
+ words = text.split(' ')
78
+ lines = []
79
+ current_line = words[0]
80
+ for word in words[1:]:
81
+ if font.size(current_line + ' ' + word)[0] <= max_width:
82
+ current_line += ' ' + word
83
+ else:
84
+ lines.append(current_line)
85
+ current_line = word
86
+ lines.append(current_line)
87
+ for i, line in enumerate(lines):
88
+ text_surface = font.render(line, True, white)
89
+ text_rect = text_surface.get_rect()
90
+ if align == "center":
91
+ text_rect.midtop = (x, y + i * size)
92
+ elif align == "left":
93
+ text_rect.topleft = (x, y + i * size)
94
+ elif align == "right":
95
+ text_rect.topright = (x, y + i * size)
96
+ screen.blit(text_surface, text_rect)
97
+ else:
98
+ text_surface = font.render(text, True, white)
99
+ text_rect = text_surface.get_rect()
100
+ if align == "center":
101
+ text_rect.midtop = (x, y)
102
+ elif align == "left":
103
+ text_rect.topleft = (x, y)
104
+ elif align == "right":
105
+ text_rect.topright = (x, y)
106
+ screen.blit(text_surface, text_rect)
107
+
108
+ def move_player(player, speed):
109
+ global player_velocity, game_start_time
110
+ keys = pygame.key.get_pressed()
111
+ if keys[pygame.K_LEFT]:
112
+ player_velocity.x = -speed
113
+ elif keys[pygame.K_RIGHT]:
114
+ player_velocity.x = speed
115
+ else:
116
+ player_velocity.x = 0 # Parar se não estiver pressionando esquerda ou direita
117
+
118
+ if keys[pygame.K_UP]:
119
+ player_velocity.y = -speed
120
+ elif keys[pygame.K_DOWN]:
121
+ player_velocity.y = speed
122
+ else:
123
+ player_velocity.y = 0 # Parar se não estiver pressionando cima ou baixo
124
+
125
+ # Inicia o cronômetro do jogo quando o jogador se move pela primeira vez
126
+ if player_velocity.x != 0 or player_velocity.y != 0:
127
+ if game_start_time == 0:
128
+ game_start_time = time.time()
129
+
130
+ # Atualiza a posição do jogador com base na velocidade
131
+ player.x += player_velocity.x
132
+ player.y += player_velocity.y
133
+
134
+ # Limita o jogador aos limites da tela
135
+ if player.left < 0:
136
+ player.left = 0
137
+ player_velocity.x = 0
138
+ if player.right > screen_width:
139
+ player.right = screen_width
140
+ player_velocity.x = 0
141
+ if player.top < 100: # Espaço reservado para o texto da pergunta
142
+ player.top = 100
143
+ player_velocity.y = 0
144
+ if player.bottom > screen_height - 100: # Espaço reservado para o texto captado
145
+ player.bottom = screen_height - 100
146
+ player_velocity.y = 0
147
+
148
+ def create_level(level_num):
149
+ num_obstacles = 5 + level_num # Incrementa a quantidade de obstáculos com o nível
150
+ items = [pygame.Rect(random.randint(0, screen_width - 20), random.randint(100, screen_height - 120), 20, 20) for _ in range(5)]
151
+ obstacles = [pygame.Rect(random.randint(0, screen_width - 20), random.randint(100, screen_height - 120), 20, 20) for _ in range(num_obstacles)]
152
+ item_speeds = [random.uniform(1.0, 2.0) + 0.5 * level_num for _ in range(len(items))] # Velocidade inicial mais aleatória e aumentada com o nível
153
+ obstacle_speeds = [random.uniform(1.0, 2.0) + 0.5 * level_num for _ in range(len(obstacles))] # Velocidade inicial mais aleatória e aumentada com o nível
154
+ item_directions = [pygame.math.Vector2(random.choice([-1, 1]), random.choice([-1, 1])) for _ in range(len(items))] # Direção inicial aleatória
155
+ obstacle_directions = [pygame.math.Vector2(random.choice([-1, 1]), random.choice([-1, 1])) for _ in range(len(obstacles))] # Direção inicial aleatória
156
+ health_items = [] # Inicialmente, sem itens de saúde
157
+ message = f"Bem-vindo ao Nível {level_num}!"
158
+ return items, obstacles, item_speeds, obstacle_speeds, item_directions, obstacle_directions, health_items, message
159
+
160
+ def move_objects(objects, speeds, directions):
161
+ for i, obj in enumerate(objects):
162
+ # Atualiza a posição com base na velocidade e direção
163
+ obj.x += speeds[i] * directions[i].x
164
+ obj.y += speeds[i] * directions[i].y
165
+
166
+ # Altera a direção se atingir as bordas
167
+ if obj.left < 0 or obj.right > screen_width:
168
+ directions[i].x *= -1
169
+ if obj.top < 100 or obj.bottom > screen_height - 100: # Limita o movimento na área de jogo
170
+ directions[i].y *= -1
171
+
172
+ # Verifica colisão com outros objetos
173
+ for j in range(i + 1, len(objects)):
174
+ if obj.colliderect(objects[j]):
175
+ directions[i].x *= -1
176
+ directions[i].y *= -1
177
+ directions[j].x *= -1
178
+ directions[j].y *= -1
179
+
180
+ return objects, speeds, directions
181
+
182
+ def handle_collisions(items, obstacles, item_speeds, obstacle_speeds, item_directions, obstacle_directions):
183
+ for i, item in enumerate(items):
184
+ for j, obstacle in enumerate(obstacles):
185
+ if item.colliderect(obstacle):
186
+ item_directions[i].x *= -1
187
+ item_directions[i].y *= -1
188
+ obstacle_directions[j].x *= -1
189
+ obstacle_directions[j].y *= -1
190
+
191
+ def show_start_screen():
192
+ start_time = time.time()
193
+ countdown = 5
194
+ font = pygame.font.Font(pygame.font.match_font('arial'), 36)
195
+ while True:
196
+ screen.fill(black)
197
+ current_time = time.time()
198
+ elapsed_time = current_time - start_time
199
+ remaining_time = max(0, countdown - int(elapsed_time))
200
+
201
+ if remaining_time == 0:
202
+ break
203
+
204
+ draw_text(screen, f"Preparando para começar! ({remaining_time})", 36, screen_width // 2, screen_height // 2 - 50, align="center")
205
+
206
+ pygame.display.flip()
207
+ pygame.time.Clock().tick(30)
208
+
209
+ def show_question(question):
210
+ draw_text(screen, question["pergunta"], 24, screen_width // 2, 70, align="center", max_width=screen_width - 40)
211
+ draw_text(screen, f"1. {question['opcao_1']}", 24, screen_width // 2, 110, align="center", max_width=screen_width - 40)
212
+ draw_text(screen, f"2. {question['opcao_2']}", 24, screen_width // 2, 150, align="center", max_width=screen_width - 40)
213
+ draw_text(screen, f"3. {question['opcao_3']}", 24, screen_width // 2, 190, align="center", max_width=screen_width - 40)
214
+ draw_text(screen, f"4. {question['opcao_4']}", 24, screen_width // 2, 230, align="center", max_width=screen_width - 40)
215
+
216
+ def check_answer(question, answer):
217
+ correct_answer = str(question["resposta"]).strip()
218
+ received_answer = str(answer).strip()
219
+ print(f"Verificando resposta... Esperado: {correct_answer}, Recebido: {received_answer}") # Mensagem de depuração
220
+ return correct_answer == received_answer
221
+
222
+ def get_random_question():
223
+ global questions, answered_questions
224
+ if not questions:
225
+ load_questions()
226
+ available_questions = [q for q in questions if q["pergunta"] not in answered_questions]
227
+ if not available_questions:
228
+ return None
229
+ question = random.choice(available_questions)
230
+ return question
231
+
232
+ def show_congratulations_screen():
233
+ screen.blit(congratulations_image, (0, 0))
234
+ pygame.display.flip()
235
+ time.sleep(30)
236
+
237
+ # Carregar perguntas
238
+ load_questions()
239
+
240
+ # Objetos do jogo
241
+ player = pygame.Rect(screen_width // 2, screen_height // 2, player_radius * 2, player_radius * 2)
242
+ player_health = 3
243
+ level_num = 1
244
+ items, obstacles, item_speeds, obstacle_speeds, item_directions, obstacle_directions, health_items, message = create_level(level_num)
245
+ score = 10 # Começar com 10 pontos de score
246
+ health_spawn_time = time.time() # Tempo inicial para o spawn de vida
247
+ current_question = None
248
+
249
+ # Carregar os melhores scores
250
+ high_scores = load_high_scores()
251
+
252
+ # Tela Inicial
253
+ show_start_screen()
254
+
255
+ # Loop principal do jogo
256
+ running = True
257
+ clock = pygame.time.Clock()
258
+
259
+ print("Iniciando o loop principal...") # Mensagem de depuração
260
+
261
+ while running:
262
+ for event in pygame.event.get():
263
+ if event.type == pygame.QUIT:
264
+ running = False
265
+ elif event.type == pygame.KEYDOWN:
266
+ if current_question:
267
+ if event.key == pygame.K_1:
268
+ answer = "1"
269
+ elif event.key == pygame.K_2:
270
+ answer = "2"
271
+ elif event.key == pygame.K_3:
272
+ answer = "3"
273
+ elif event.key == pygame.K_4:
274
+ answer = "4"
275
+ else:
276
+ answer = None
277
+
278
+ if answer:
279
+ if check_answer(current_question, answer):
280
+ score += 3
281
+ correct_answers += 1
282
+ correct_answers_streak += 1
283
+ answered_questions.add(current_question["pergunta"])
284
+ print(f"Resposta correta! Streak: {correct_answers_streak}, Total corretas: {correct_answers}") # Mensagem de depuração
285
+ obstacles_to_remove = 1
286
+ if level_num > 5:
287
+ obstacles_to_remove = 2
288
+ if level_num > 8:
289
+ obstacles_to_remove = 3
290
+ if obstacles:
291
+ for _ in range(min(obstacles_to_remove, len(obstacles))):
292
+ idx = random.randint(0, len(obstacles) - 1)
293
+ obstacles.pop(idx)
294
+ obstacle_speeds.pop(idx)
295
+ obstacle_directions.pop(idx)
296
+ if correct_answers_streak >= 3:
297
+ player_health += 1
298
+ correct_answers_streak = 0 # Reinicia a contagem de respostas corretas
299
+ current_question = None
300
+ beep.play() # Beep sonoro
301
+ if len(answered_questions) == len(questions):
302
+ show_congratulations_screen()
303
+ running = False
304
+ else:
305
+ correct_answers_streak = 0 # Reinicia a contagem de respostas corretas
306
+ score -= 1
307
+ print("Resposta incorreta.") # Mensagem de depuração
308
+ for _ in range(3):
309
+ obstacles.append(pygame.Rect(random.randint(0, screen_width - 20), random.randint(100, screen_height - 120), 20, 20))
310
+ obstacle_speeds.append(random.uniform(1.0, 2.0) + 0.5 * level_num)
311
+ obstacle_directions.append(pygame.math.Vector2(random.choice([-1, 1]), random.choice([-1, 1])))
312
+ current_question = None
313
+
314
+ # Movimento do jogador
315
+ move_player(player, player_speed)
316
+
317
+ # Verifica colisão com itens
318
+ for item in items[:]:
319
+ if player.colliderect(item):
320
+ items.remove(item)
321
+ score += 1
322
+ current_question = get_random_question()
323
+ if not current_question:
324
+ show_congratulations_screen()
325
+ running = False
326
+ break
327
+ print(f"Nova pergunta: {current_question['pergunta']}") # Mensagem de depuração
328
+
329
+ # Verifica colisão com obstáculos
330
+ for obstacle in obstacles[:]:
331
+ if player.colliderect(obstacle):
332
+ player_health -= 1
333
+ collision_count += 1
334
+ idx = obstacles.index(obstacle)
335
+ obstacles.remove(obstacle)
336
+ obstacle_speeds.pop(idx)
337
+ obstacle_directions.pop(idx)
338
+ print(f"Colidiu com obstáculo. Vidas restantes: {player_health}") # Mensagem de depuração
339
+ if player_health <= 0 or score <= 0:
340
+ running = False
341
+ message = "Game Over"
342
+ print(message) # Mensagem de depuração
343
+
344
+ # Verifica colisão com itens de saúde
345
+ for health_item in health_items[:]:
346
+ if player.colliderect(health_item):
347
+ health_items.remove(health_item)
348
+ player_health += 1
349
+
350
+ # Verifica se o nível foi concluído
351
+ if not items:
352
+ level_num += 1
353
+ items, obstacles, item_speeds, obstacle_speeds, item_directions, obstacle_directions, health_items, message = create_level(level_num)
354
+ player_radius += 2 # Aumenta o raio do jogador a cada nível
355
+ player = pygame.Rect(player.x, player.y, player_radius * 2, player_radius * 2)
356
+ player_speed = player_base_speed + level_num * player_speed_increment # Incrementa a velocidade do jogador com o nível
357
+ print(f"Iniciando nível {level_num}") # Mensagem de depuração
358
+
359
+ # Movimento dos itens e obstáculos
360
+ items, item_speeds, item_directions = move_objects(items, item_speeds, item_directions)
361
+ obstacles, obstacle_speeds, obstacle_directions = move_objects(obstacles, obstacle_speeds, obstacle_directions)
362
+
363
+ # Tratamento de colisões entre itens e obstáculos
364
+ handle_collisions(items, obstacles, item_speeds, obstacle_speeds, item_directions, obstacle_directions)
365
+
366
+ # Aparição aleatória de itens de saúde
367
+ if level_num > 5 and time.time() - health_spawn_time > random.randint(10, 20):
368
+ health_items = [pygame.Rect(random.randint(0, screen_width - 20), random.randint(100, screen_height - 120), 20, 20)]
369
+ health_spawn_time = time.time()
370
+
371
+ # Remover itens de saúde após 5 segundos
372
+ if health_items and time.time() - health_spawn_time > 5:
373
+ health_items = []
374
+
375
+ # Cronômetro para subtrair pontos do score a cada intervalo de tempo
376
+ current_time = time.time()
377
+ if current_time - start_time >= score_decrement_interval:
378
+ if score > 0: # Apenas decrementar se o score for maior que 0
379
+ score -= 1
380
+ start_time = current_time # Reseta o tempo
381
+ print(f"Score atualizado: {score}") # Mensagem de depuração
382
+ if score <= 0:
383
+ running = False
384
+ message = "Game Over"
385
+ print(message) # Mensagem de depuração
386
+
387
+ # Desenha na tela
388
+ screen.fill(black)
389
+ pygame.draw.circle(screen, green, player.center, player_radius)
390
+ for item in items:
391
+ pygame.draw.rect(screen, white, item)
392
+ for obstacle in obstacles:
393
+ pygame.draw.rect(screen, red, obstacle)
394
+ for health_item in health_items:
395
+ pygame.draw.rect(screen, yellow, health_item)
396
+
397
+ # Exibe a pontuação, número de vidas, nível atual e contagem de colisões
398
+ draw_text(screen, f"Pontos: {score}", 24, 10, 10, align="left")
399
+ draw_text(screen, f"Vidas: {player_health}", 24, 10, 40, align="left")
400
+ draw_text(screen, f"Nível: {level_num}", 24, 10, 70, align="left")
401
+ draw_text(screen, f"Colisões: {collision_count}", 24, 10, 100, align="left")
402
+
403
+ # Exibe a pergunta na parte superior da tela
404
+ if current_question:
405
+ show_question(current_question)
406
+
407
+ pygame.display.flip()
408
+ clock.tick(30)
409
+
410
+ # Atualiza os melhores scores
411
+ date_str = time.strftime("%Y-%m-%d %H:%M:%S")
412
+ high_scores.append([str(score), date_str])
413
+ high_scores = sorted(high_scores, key=lambda x: int(x[0]), reverse=True)[:10]
414
+ save_high_scores(high_scores)
415
+
416
+ # Exibe a tela de Game Over com os resultados
417
+ duration_seconds = int(time.time() - game_start_time)
418
+ duration_minutes = duration_seconds // 60
419
+ duration_seconds = duration_seconds % 60
420
+ duration_formatted = f"{duration_minutes:02}:{duration_seconds:02}"
421
+
422
+ screen.fill(black)
423
+ draw_text(screen, "Game Over", 48, screen_width // 2, screen_height // 2 - 100, align="center")
424
+ draw_text(screen, f"Pontuação Final: {score}", 36, screen_width // 2, screen_height // 2 - 50, align="center")
425
+ draw_text(screen, f"Nível Final: {level_num}", 36, screen_width // 2, screen_height // 2, align="center")
426
+ draw_text(screen, f"Duração da Partida: {duration_formatted}", 36, screen_width // 2, screen_height // 2 + 50, align="center")
427
+ draw_text(screen, f"Respostas Corretas: {correct_answers}", 36, screen_width // 2, screen_height // 2 + 100, align="center")
428
+ draw_text(screen, f"Colisões: {collision_count}", 36, screen_width // 2, screen_height // 2 + 150, align="center")
429
+ pygame.display.flip()
430
+ time.sleep(30)
431
+
432
+ pygame.quit()
433
+ print("Jogo encerrado.") # Mensagem de depuração
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ pygame
2
+ pandas
3
+ openpyxl
4
+ streamlit