-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgame.py
More file actions
284 lines (254 loc) · 9.01 KB
/
game.py
File metadata and controls
284 lines (254 loc) · 9.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
import pygame
import serial
import sys
import os
import utils
import microbit_serial as ubit
import connection_files.checkmark
from menu_files.backgrounds import Backgrounds
from random import randint
# Minigames
import wheelie
import engine
import coin
import overcoock
import match
import dinorun
import whichpath
minigames = [wheelie.wheelie_game, engine.engine_game, coin.coin_game, overcoock.overcoock_game, match.match_game, whichpath.whichpath_game]
# Demo flag
demo = False
counter = 0
# Init pygame
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((utils.width, utils.height))
utils.clock = pygame.time.Clock()
utils.win_sound = pygame.mixer.Sound("sounds" + utils.sep + "win.ogg")
utils.lose_sound = pygame.mixer.Sound("sounds" + utils.sep + "lose.ogg")
utils.text_colour = (255, 255, 255)
def connect_notice(status):
"""
This function displays information about
the microbit connection status before the
game starts.
status - Boolean value, true if connected.
"""
screen.fill((0, 0, 0))
microbit_img = pygame.image.load("connection_files" + utils.sep + "microbit.png").convert_alpha()
microbit_rect = microbit_img.get_rect()
microbit_rect.center = (utils.width / 2, utils.height / 2)
screen.blit(microbit_img, microbit_rect)
if status == False:
utils.draw_text(screen, "Please connect a microbit controller", utils.width / 2, utils.height - (utils.height / 5))
pygame.display.flip()
else:
# Init checkmark sprite
checkmark = connection_files.checkmark.Checkmark()
checkmark_sprites = pygame.sprite.Group()
checkmark_sprites.add(checkmark)
while utils.done_setup == False:
checkmark.animate()
checkmark_sprites.update()
checkmark_sprites.draw(screen)
pygame.display.flip()
utils.clock.tick(60)
pygame.time.wait(1500)
# Connect to the microbit
port = ubit.connect()
run_notice = False
while type(port) is not serial.Serial:
print("Looking for a microbit")
run_notice = True
port = ubit.connect()
connect_notice(False)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
print("Microbit Found")
if run_notice == True:
connect_notice(True)
port.open()
def get_data():
"""
This function is used to loop the retrieving of data
from the microbit. It depends on microbit_serial
functions.
"""
try:
if port.in_waiting > 0:
# Obtain data from the microbit
utils.data = ubit.data(port)
while type(utils.data) != list: # Make sure message is intact and wait for it to come
utils.data = ubit.data(port)
print(utils.data)
port.write("Y".encode()) # Let the microbit know we received the data
utils.check_data_integrity(screen)
try:
utils.update_volume()
except Exception as e:
print(e)
except: # Controller disconnected
utils.data = [-1, -1, -1, -1]
def decrease_lives():
"""
This function decreases by one the lives variable
and sends an instruction to the microbit so that
it turns off one LED.
"""
try:
utils.lives -= 1
port.write("D".encode())
except: # Controller disconnected
utils.data = [-1, -1, -1, -1]
def reset_lives():
"""
This function sends an instruction to the microbit
so that all the 8 LEDs light up and it resets
the lives variable to 8.
"""
try:
utils.lives = 8
port.write("R".encode())
except: # Controller disconnected
utils.data = [-1, -1, -1, -1]
def game():
"""
This function is used to handle the randomisation of the
minigames sequence. It randomises the order, starts a minigame
and eventually return back to the main menu if the user loses
all the lives.
"""
global demo
global counter
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
utils.time_remaining = 27
if demo == True:
if counter == 6: # Reset counter
counter = 0
minigame = minigames[counter]
counter += 1
if counter == 4: # Skip match minigame for ghost button clicks issue
counter += 1
else:
minigame = minigames[randint(0, len(minigames) - 1)]
minigame(screen, get_data, decrease_lives)
if (utils.lives == 0):
decrease_lives()
utils.lives = 8
break
def credits():
"""
This function handles the credits display.
"""
credit_lines = []
credit_objects = []
utils.text_size = 20
utils.text_colour = (255, 255, 255)
with open("credits.txt") as f:
# Strip \n from each line and store in a list
credit_lines = [line.rstrip() for line in f]
for line in range(0, len(credit_lines)):
# Create all the text objects
credit_objects.append(utils.draw_text(screen, credit_lines[line], utils.width / 2, utils.height + (50 * line)))
while credit_objects[len(credit_lines) - 1][1].y > 0:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# This loop scrolls the text up util the last line is outside of the screen
screen.fill((0, 0, 0))
for line in range(0, len(credit_lines)):
credit_objects[line][1].y -= 5
if credit_objects[line][1].y > 0:
screen.blit(credit_objects[line][0], credit_objects[line][1])
pygame.display.flip()
utils.clock.tick(25)
utils.text_size = 100
def menu():
"""
This function handles the game menu.
"""
# Reset lives
reset_lives()
options = ["Play", "Credits"]
# Create shade surface
shade = pygame.Surface((utils.width, utils.height))
shade.fill((0, 0, 0))
alpha = 0
shade.set_alpha(alpha)
alpha_increment = True # Whether or not to increment the shade's alpha
animate = True # Whether or not to animate the menu backgrounds
# Init backgrounds sprite
backgrounds_sprite = Backgrounds(os.path.dirname(os.path.realpath(__file__)), shade)
backgrounds_sprite_g = pygame.sprite.Group()
backgrounds_sprite_g.add(backgrounds_sprite)
selected_option = 0
while True:
utils.run_in_thread(get_data)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# Elaborate microbit data
if utils.data[0] == 1 and selected_option > 0:
selected_option -= 1
elif utils.data[0] == 3 and selected_option < 1:
selected_option += 1
elif utils.data[0] == 2 or utils.data[0] == 4:
utils.run_in_thread(get_data)
utils.data[0] = 0 # Clean to avoid interferance with games
if selected_option == 0:
game()
return
else:
credits()
return
print(utils.data)
screen.fill((0, 0, 0))
# Shade alpha
if (int(utils.stage) < int(utils.stage + 0.01) and animate == True) or (alpha == 0 and alpha_increment == False):
alpha_increment = not alpha_increment
backgrounds_sprite.animate() # Animate for one last time so that the next background fades in
if alpha_increment == True:
alpha += 2
else:
alpha -= 2
shade.set_alpha(alpha)
# Draw backgrounds
if alpha_increment == True:
backgrounds_sprite.animate()
animate = True
else:
animate = False
backgrounds_sprite_g.update()
backgrounds_sprite_g.draw(screen)
# Draw shade
screen.blit(shade, (0, 0))
# Draw options
for o in range(0, len(options)):
if selected_option == o:
utils.text_colour = (255, 0, 0)
else:
utils.text_colour = (204, 136, 0)
utils.draw_text(screen, options[o], utils.width / 2 - 5, (utils.height / 2) - 5 + 150 * o)
utils.text_colour = (255, 255, 255)
utils.draw_text(screen, options[o], utils.width / 2, (utils.height / 2) + 150 * o)
# Draw help
utils.text_colour = (0, 0, 0)
utils.draw_text(screen, "U/D to select", (utils.width / 2) - 5, (utils.height / 5) - 5)
utils.draw_text(screen, "L/R to accept", (utils.width / 2) - 5, (utils.height / 3) - 5)
utils.text_colour = (255, 255, 255)
utils.draw_text(screen, "U/D to select", utils.width / 2, utils.height / 5)
utils.draw_text(screen, "L/R to accept", utils.width / 2, utils.height / 3)
pygame.display.flip()
utils.clock.tick(15)
if __name__ == "__main__":
while True:
port.write("Y".encode()) # Sync microbit and computer
menu()