class Game(): def __init__(self): pygame.init() pygame.font.init() self.screen_commit = pygame.display.set_mode(WINDOW_SIZE) pygame.display.set_caption("Master Key - LD43") self.screen = pygame.Surface(MAX_FRAME_SIZE) pygame.mixer.pre_init(44100, -16, 1, 512) self.mus = pygame.mixer.Sound(fp("LD43.wav")) self.mus.play(-1) self.box_slide = pygame.mixer.Sound(fp("box_slide.wav")) self.box_slide.set_volume(0.12) self.box_fall = pygame.mixer.Sound(fp("box_fall.wav")) self.box_fall.set_volume(0.35) self.prompt_continue = pygame.mixer.Sound(fp("prompt_continue.wav")) self.prompt_continue.set_volume(0.3) self.collect_gem = pygame.mixer.Sound(fp("collect_gem.wav")) self.collect_gem.set_volume(0.5) self.altar_place = pygame.mixer.Sound(fp("altar_place.wav")) self.altar_place.set_volume(0.4) self.reset_noise = pygame.mixer.Sound(fp("reset.wav")) self.reset_noise.set_volume(0.15) self.dash_sound = pygame.mixer.Sound(fp("dash.wav")) self.dash_sound.set_volume(0.05) self.key_select = pygame.mixer.Sound(fp("key_select.wav")) self.key_select.set_volume(0.15) self.cam = Camera(self.screen_commit) self.cam.set_pan_pid(6, 2, -0.2) self.notice_frame = pygame.image.load(fp("notice.png")) self.levels = [ Level("level_1.txt"), Level("level_2.txt"), Level("level_3.txt"), Level("level_3.5.txt"), Level("level_4.txt"), Level("level_5.txt"), Level("level_6.txt"), Level("level_7.txt") ] self.main() def main(self): # level_to_msg = {0: "Welcome to Master Key!\nUse the arrow keys to move.", # 1: "Hold Z while moving to dash.", # 2: "Hold X to push objects.", # 3: "Hold C to hop up ledges.", # 4: "Altars require you to\nsacrifice your controls!\n\nStand in front of the book, and\n drag a key onto it with the mouse.", # 5: "You're on your own now.\n Good Luck!"} # level_to_hint = {0: "Move around with the arrow keys.", # 1: "Hold Z while moving to dash.\nThis allows you to cross short gaps.", # 2: "Hold X while moving to push.\nYou can push cubes into holes.", # 3: "Hold C while moving to jump.\nThis lets you get up short platforms.", # 4: "Try standing next to the book, and\n drag a key onto it with the mouse.", # 5: "You can replace the key on an altar\nby dragging a different key onto it.", # 6: "Don't forget you can sacrifice\nyour movement keys, too!", # 7: "Don't forget you can sacrifice\nyour movement keys, too!", # 8: ""} # for key in level_to_msg: # self.tooltip(level_to_msg[key]) # for key in level_to_hint: # self.tooltip(level_to_hint[key]) self.level_counter = 0 while self.level_counter < len(self.levels): self.cam.zoom = 1.0 self.cam.set_target_zoom(1.0) self.run_level(self.levels[self.level_counter]) self.level_counter += 1 self.tooltip("That's all!\nThanks for playing!") def set_starting_hud(self): if self.level_counter == 0: bad = [] for key in self.hud_key_array.hud_keys: if key.key in [JUMP, DASH, PUSH]: bad.append(key) for item in bad: self.hud_key_array.hud_keys.remove(item) elif self.level_counter == 1: bad = [] for key in self.hud_key_array.hud_keys: if key.key in [JUMP, PUSH]: bad.append(key) for item in bad: self.hud_key_array.hud_keys.remove(item) elif self.level_counter == 2: bad = [] for key in self.hud_key_array.hud_keys: if key.key in [JUMP]: bad.append(key) for item in bad: self.hud_key_array.hud_keys.remove(item) #################################################333333 def tooltip(self, str): self.mus.set_volume(0.4) self.press_enable = False frame = self.notice_frame.copy().convert_alpha() cur_state = self.screen_commit.copy() myfont = pygame.font.Font(fp("Myriad.otf"), 30) tsplit = str.split("\n") l = len(tsplit) any_button = pygame.font.Font(fp("Myriad.otf"), 20) any_button_text = any_button.render("Press any button to continue.", 1, (0, 0, 0)) tool_shadow_alpha = 0 tool_shadow = pygame.Surface(WINDOW_SIZE) tool_shadow.fill((0, 0, 0)) tool_shadow.set_alpha(tool_shadow_alpha) tool_shadow_rate = 300 tool_shadow_max = 150 tool_shadow_multiplier = 1.0 for i2, i in enumerate(tsplit): a = myfont.render(i, 1, (0, 0, 0)) frame.blit(a, (frame.get_width() / 2 - a.get_width() / 2, frame.get_height() / 2 - a.get_height() / 2 - a.get_height() * 0.6 * l + a.get_height() * 1.2 * i2)) frame.blit( any_button_text, (frame.get_width() / 2 - any_button_text.get_width() / 2, 240)) then = time.time() pause_time = time.time() paused = True to_break = False while not to_break: now = time.time() dt = now - then then = now tsm = tool_shadow_multiplier events = pygame.event.get() for event in events: if event.type == pygame.QUIT: pygame.quit() sys.exit() elif event.type == pygame.KEYDOWN: if time.time() - pause_time > 0.5: if paused: self.prompt_continue.play() self.mus.set_volume(1.0) paused = False tool_shadow_alpha = min( tool_shadow_max, int((time.time() - pause_time) * tool_shadow_rate)) tool_shadow.set_alpha(tool_shadow_alpha * tool_shadow_multiplier) self.screen_commit.fill((0, 0, 0)) self.screen_commit.blit(cur_state, (0, 0)) self.screen_commit.blit(tool_shadow, (0, 0)) x = WINDOW_WIDTH / 2 - self.notice_frame.get_width() / 2 y = WINDOW_HEIGHT / 2 - self.notice_frame.get_height() / 2 self.screen_commit.blit( frame, (x, int(y * (3 * tsm - 2) - 200 * math.sin(2 * math.pi * tsm)))) pygame.display.flip() if paused == False: tool_shadow_multiplier -= dt * 3 if tool_shadow_multiplier < 0: to_break = True pass def run_level(self, level_obj): self.press_en = True self.mrd = DOWN self.hud_key_array = HudKeyArray() self.clicked = 0 self.selected_key = [] self.hovered_shrine = [] self.last_hover = [] self.cur_level = level_obj self.then = time.time() self.player_pos = level_obj.player_start_pos() self.cam.set_center((self.player_pos[0] * TILE_WIDTH, self.player_pos[1] * TILE_WIDTH - TILE_WIDTH)) self.player = Player(self.player_pos) self.goal = Goal(level_obj.goal_pos()) self.blocks = [] for item in level_obj.block_pos(): self.blocks.append(Block(item)) self.set_starting_hud() self.shrines = [] self.doors = [] if self.cur_level.shrine_count() > 0: self.shrine_0 = Shrine(self.cur_level.shrine_0_pos(), num=0) self.door_0 = Door(self.cur_level.door_0_pos(), self.shrine_0) self.shrines.append(self.shrine_0) self.doors.append(self.door_0) shadow = pygame.Surface(WINDOW_SIZE) shadow.fill((0, 0, 0)) shadow_opacity = 255.0 shadow_fade_rate = 255.0 self.shadow_dir = 1 self.level_start = time.time() msg_not_said_yet = 1 while True: now = time.time() dt = now - self.then self.then = now dt = self.cam.time_step(dt) if msg_not_said_yet and self.level_counter <= 5: self.press_en = 0 if shadow_opacity < 80 and self.shadow_dir == 1: self.test_keydowns() else: pygame.event.get() self.screen.fill((0, 0, 0)) pypos = self.player.pos[1] items_to_draw = self.blocks + self.shrines + self.doors + [ self.player ] + [self.goal] self.draw_items(items_to_draw) self.cam.capture(self.screen) self.draw_tools(self.screen_commit) self.update_objects(dt) self.mouse_triggers() if shadow_opacity > 0 or self.shadow_dir == -1: shadow_opacity = max( 0, shadow_opacity - self.shadow_dir * shadow_fade_rate * dt) shadow.set_alpha(shadow_opacity) self.screen_commit.blit(shadow, (0, 0)) pygame.display.flip() if self.player_hit_goal(level_obj) and self.shadow_dir == 1: self.collect_gem.play() self.cam.set_zoom_pid(5, 1, -0.2) self.cam.set_target_zoom(1.5) self.goal.sprite.start_animation("collect") self.shadow_dir = -1 if shadow_opacity > 255 and self.shadow_dir == -1: break level_to_msg = { 0: "Welcome to Master Key!\nUse the arrow keys to move.", 1: "Hold Z while moving to dash.", 2: "Hold X to push objects.", 3: "Hold C to hop up ledges.", 4: "Altars require you to\nsacrifice your controls!\n\nStand in front of the book, and\n drag a key onto it with the mouse.", 5: "You're on your own now.\n Good Luck!" } self.level_to_hint = { 0: "Move around with the arrow keys.", 1: "Hold Z while moving to dash.\nThis allows you to cross short gaps.", 2: "Hold X while moving to push.\nYou can push cubes into holes.", 3: "Hold C while moving to jump.\nThis lets you get up short platforms.", 4: "Try standing next to the book, and\n drag a key onto it with the mouse.", 5: "You can replace the key on an altar\nby dragging a different key onto it.", 6: "Don't forget you can sacrifice\nyour movement keys, too!", 7: "Don't forget you can sacrifice\nyour movement keys, too!", 8: "" } if time.time( ) - self.level_start > 0.75 and msg_not_said_yet and self.level_counter in level_to_msg and self.shadow_dir != -1: self.tooltip(level_to_msg[self.level_counter]) self.then = time.time() msg_not_said_yet = 0 self.press_en = True def draw_items(self, items): self.player.pos = self.player.pos[0], self.player.pos[1] + 0.001 bump_these = [] for thing in items: if thing in self.blocks: if thing.mrd == UP and not thing.fell: thing.pos = thing.pos[0], thing.pos[1] + 1 bump_these.append(thing) if self.mrd == UP: self.player.pos = self.player.pos[ 0], self.player.pos[1] + 1 + self.player.dash_mode items.sort(key=lambda x: x.pos[1]) self.player.pos = self.player.pos[0], int(self.player.pos[1]) y = 0 while y <= self.cur_level.height: self.cur_level.draw_level(self.screen, y_range=(y, y)) if not len(items): y += 1 continue while items[0].pos[1] == y: items[0].draw(self.screen) items = items[1:] if items == []: break y += 1 if self.mrd == UP: self.player.pos = self.player.pos[ 0], self.player.pos[1] - 1 - self.player.dash_mode for block in bump_these: block.pos = block.pos[0], block.pos[1] - 1 def can_move_here(self, pos, block=False, prev_pos=(0, 0), hop=False): if self.unpassable_door_here(pos): return False block_poses = [item.pos for item in self.blocks] if self.cur_level.can_move_here(pos, block=block, prev_pos=prev_pos, hop=hop): if pos not in block_poses: return True if self.cur_level.pit_here(pos) and pos in block_poses: return True return False def unpassable_door_here(self, pos): for item in self.doors: if item.pos == pos: if not item.is_passable(): return True if self.cur_level.unpassable_here(pos): return True if self.cur_level.shrine_here(pos): return True return False def block_here(self, pos): block_poses = [item.pos for item in self.blocks] for item in block_poses: if item == pos: if not self.cur_level.pit_here(pos): return True return False def test_keydowns(self): events = pygame.event.get() for event in events: if event.type == pygame.QUIT: pygame.quit() sys.exit() if not self.press_en: return keydowns = self.player.get_keydowns(events) keyups = self.player.get_keyups(events) bad_keydowns = self.player.get_bad_keydowns(events) for item in keydowns: if item in [UP, DOWN, RIGHT, LEFT]: if not self.unpassable_door_here( self.player.move_target(item, force_1=True)): if not self.block_here( self.player.move_target(item, force_1=True)): if self.can_move_here(self.player.move_target(item), prev_pos=self.player.pos, hop=self.player.jump_mode): if self.player.dash_mode: self.dash_sound.play() self.player.move(item) self.mrd = item if self.player.jump_mode: self.player.hop() elif self.can_move_here(self.player.move_target( item, force_1=True), prev_pos=self.player.pos, hop=self.player.jump_mode): if self.player.dash_mode: self.dash_sound.play() self.player.move(item, force_1=True) self.mrd = item if self.player.jump_mode: self.player.hop() elif self.player.push_mode: for block in self.blocks: if block.pos == self.player.move_target(item): target = block.move_target(item) if self.can_move_here((target), block=True): self.box_slide.play() block.move(item) self.player.move(item) self.mrd = item # elif self.cur_level. if item == DASH: self.player.dash_mode = 1 if item == JUMP: self.player.jump_mode = 1 if item == PUSH: self.player.push_mode = 1 if item == RESET: self.reset_noise.play() self.shadow_dir = -1 level_index = self.levels.index(self.cur_level) self.level_counter -= 1 if item == HINT: self.tooltip(self.level_to_hint[self.level_counter]) self.then = time.time() for item in keyups: if item == DASH: self.player.dash_mode = 0 if item == JUMP: self.player.jump_mode = 0 if item == PUSH: self.player.push_mode = 0 def update_objects(self, dt): self.hud_key_array.update(dt) if len(self.selected_key): self.selected_key[0].update(dt) for shrine in self.shrines: shrine.update(dt) for door in self.doors: door.update(dt) for block in self.blocks: block.update(dt) if self.cur_level.pit_here(block.pos): if block.fell == 0: self.box_fall.play() block.fall() self.goal.update(dt) self.player.update(dt) cam_x = self.player.pos[0] * TILE_WIDTH cam_y = self.player.pos[1] * TILE_WIDTH self.cam.set_target_center((cam_x, cam_y)) def player_hit_goal(self, level_obj): if self.player.pos == level_obj.goal_pos(): return True def draw_tools(self, surf): enabled = self.player.control_enables self.hud_key_array.draw(surf) if len(self.selected_key): self.selected_key[0].draw(surf) def check_adjacency_to_shrine(self, shrine): dist = abs(shrine.pos[0] - self.player.pos[0]) + abs(shrine.pos[1] - self.player.pos[1]) if dist <= 1: return True else: return False def mouse_triggers(self): clicked = pygame.mouse.get_pressed()[0] if not clicked and len(self.selected_key): if len(self.hovered_shrine): if self.check_adjacency_to_shrine(self.hovered_shrine[0]): cap_key = self.hovered_shrine[0].captured_key if len(cap_key): cap_key[0].x, cap_key[0].y = ( cap_key[0].x - self.cam.pos[0] + WINDOW_WIDTH / 2 - HUD_KEY_WIDTH, cap_key[0].y - self.cam.pos[1] + WINDOW_WIDTH / 2 - HUD_KEY_HEIGHT - TILE_WIDTH * 2) self.hud_key_array.hud_keys.append(cap_key[0]) self.selected_key[0].scale = 0.8 self.altar_place.play() self.hovered_shrine[0].captured_key = [ self.selected_key.pop() ] else: self.hud_key_array.return_key(self.selected_key[0]) else: self.hud_key_array.return_key(self.selected_key[0]) self.selected_key = [] self.hovered_shrine = [] mpos = pygame.mouse.get_pos() mx = mpos[0] my = mpos[1] for key in self.hud_key_array.hud_keys: if key.mouse_over(mpos): if key not in self.last_hover: self.last_hover = [key] self.key_select.play() if clicked: if len(self.selected_key): self.hud_key_array.return_key(self.selected_key[0]) self.hud_key_array.select_key(key.key) self.selected_key = [key] if len(self.selected_key): key = self.selected_key[0] key.target_x = mx - HUD_KEY_WIDTH / 2 key.target_y = my - HUD_KEY_HEIGHT / 2 for item in self.shrines: x = item.pos[ 0] * TILE_WIDTH + -self.cam.pos[0] + WINDOW_WIDTH / 2 y = item.pos[ 1] * TILE_WIDTH + -self.cam.pos[1] + WINDOW_HEIGHT / 2 key.target_scale = 1.2 margin = TILE_WIDTH / 2 if mx > x - margin and mx < x + item.width + margin: if my > y - margin and my < y + item.height + margin: key.target_scale = 0.5 self.hovered_shrine = [item] self.set_control_enables() def set_control_enables(self): self.player.reset_control_enables() for item in self.hud_key_array.hud_keys: for k in CONTROLS: if CONTROLS[k] == item.key: self.player.control_enables[k] = 1
class Game(): def __init__(self): pygame.init() pygame.mixer.init() #pygame.mixer.music.load('mus.wav') #pygame.mixer.music.play(-1) self.screen = pygame.Surface([WINDOW_WIDTH, WINDOW_HEIGHT]) self.final_screen = pygame.display.set_mode( [WINDOW_WIDTH, WINDOW_HEIGHT]) self.cam = Camera(self.final_screen) pygame.display.set_caption("Command Prompt") self.screen.fill((0, 0, 0)) self.framerate = 50 # This just got a little too meta. self.beat_length = 500 self.current_color = 0 self.multiplier = 1.0 self.health = 100.0 self.healthbar_health = 100.0 self.healthbar_color = [255, 255, 255] self.time_offset = 0 self.goal_pos = (60, WINDOW_HEIGHT - 55) self.code_font = pygame.font.SysFont("monospace", 20) self.multiplier_font = pygame.font.SysFont("monospace", 50) self.win_font = pygame.font.SysFont("monospace", 35) self.clock = pygame.time.Clock() self.key_list = [ pygame.K_q, pygame.K_w, pygame.K_e, pygame.K_r, pygame.K_t, pygame.K_y, pygame.K_u, pygame.K_i, pygame.K_o, pygame.K_p, pygame.K_a, pygame.K_s, pygame.K_d, pygame.K_f, pygame.K_g, pygame.K_h, pygame.K_j, pygame.K_k, pygame.K_l, pygame.K_z, pygame.K_x, pygame.K_c, pygame.K_v, pygame.K_b, pygame.K_n, pygame.K_m, pygame.K_RETURN ] self.last_presses = self.determine_keypresses() self.code = CODE self.lines = self.code.split("\n") for idx, item in enumerate(self.lines): if len(item) > 50: self.lines[idx] = item[0:50] i = 0 while i < len(self.lines): if not len(self.lines[i]): self.lines.pop(i) else: i += 1 self.line_idx = 0 self.bang_list = [] self.flash_list = [] self.lines_to_render = [] self.max_lines_rendered = 12 self.yoffset = 25 self.additional_offset = self.yoffset self.shock_offset = 0 self.score = 0 #self.success_sound = pygame.mixer.Sound('success.wav') #self.success_sound.set_volume(0.4) #self.failure_sound = pygame.mixer.Sound('failure.wav') #self.failure_sound.set_volume(0.7) self.beat_list = [ 8, 16, 24, 28, # First chorus 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 82, 84, 88, 90, 92, # Second chorus 96, 98, 100, 104, 106, 108, 112, 114, 116, 120, 123, 125, 128, 130, 132, 136, 139, 142, 144, 148, 150, 152, 156, 158, 160, 162, 164, 168, 170, 172, 176, 178, 180, 182, 184, 186, 188, # Third chorus 192, 194, 195, 200, 204, 207, 208, 212, 216, 217, 218, 224, 226, 228, 232, 233, 234, 235, 236, 239, 241, 243, 244, 246, 248, 249, 250, 251, 252, 256, 258, 260, 262, 264, 265, 266, 267, 268, 270, 271, 272, 276 ] def render_score(self, pos): a = 10 - len(str(self.score)) if pos == 0: string = game.code_font.render( "Score: %s%s Juice:" % ("0" * a, self.score), 1, (255, 255, 255)) self.screen.blit(string, (120 + self.shock_offset, 50 + self.shock_offset)) elif pos == 1: string = game.code_font.render("Score: %s" % (self.score), 1, (255, 255, 255)) self.screen.blit( string, (300 + self.shock_offset, 260 + self.shock_offset)) def render_goal(self, size): self.goal_size = (size, size) self.goal_surface = pygame.Surface(self.goal_size) self.goal_surface.set_colorkey((0, 0, 0)) self.goal_color = (200, 200, 200) pygame.draw.circle(self.goal_surface, self.goal_color, (self.goal_size[0] / 2, self.goal_size[0] / 2), self.goal_size[0] / 2, 2) half = self.goal_size[0] / 2 self.screen.blit(self.goal_surface, (self.goal_pos[0] - half, self.goal_pos[1] - half)) def render_bangs(self, size): size = (size + 30) / 2 for bang in self.bang_list: bang_size = (size, size) bang_surface = pygame.Surface(bang_size) ypos = self.goal_pos[1] - bang.beats_away(self.time_ms) * 100.0 lightness = max(200 - abs(self.goal_pos[1] - ypos), 120) bang_surface.set_colorkey((0, 0, 0)) bang_color = (lightness, lightness, lightness) half = bang_size[0] / 2 pygame.draw.circle(bang_surface, bang_color, (half, half), half, 0) half = bang_size[0] / 2 self.screen.blit(bang_surface, (self.goal_pos[0] - half, ypos - half)) def render_flashes(self): for prop in self.flash_list: if prop > 1: prop = 1 size = 30 + 120 * prop surf = pygame.Surface((size, size)) surf.set_colorkey((0, 0, 0)) shade = 255 - 255 * prop**0.5 xpos, ypos = self.goal_pos[0], self.goal_pos[1] half = int(size / 2) color = [shade / 1.2, shade / 1.2, shade / 1.2] color[self.current_color] *= 1.2 color = [int(i) for i in color] pygame.draw.circle(surf, (color[2], color[1], color[0]), (half, half), half, 0) self.screen.blit(surf, (xpos - half, ypos - half)) def make_flash(self): self.flash_list.append(0.0) def get_next_line(self): if self.line_idx >= len(self.lines): self.line_idx = 0 res = self.line_idx self.line_idx += 1 return self.lines[res] def render_lines(self): yoffset, xoffset, yspacing = 90, 120, self.yoffset start_position = (xoffset, WINDOW_HEIGHT - yoffset) current_y_position = start_position[1] for line in self.lines_to_render: t = OLD_FONT_TRANSPARENCY if line[0] == "!": hack = game.code_font.render(line, 1, (t / 2 + 128, t / 2, t / 2)) elif line[:7] == "Current": hack = game.code_font.render(line, 1, (t / 2, t / 2 + 128, t / 2)) elif line[0] == "#": hack = game.code_font.render( line, 1, (t / 2 + 32, t / 2 + 96, t / 2 + 128)) else: hack = game.code_font.render(line, 1, (t, t, t)) self.screen.blit( hack, (start_position[0] + self.shock_offset, current_y_position + self.additional_offset + self.shock_offset)) current_y_position -= yspacing def update_lines(self, line): self.additional_offset = self.yoffset if len(self.lines_to_render) < self.max_lines_rendered: self.lines_to_render = [line] + self.lines_to_render else: self.lines_to_render = [line] + self.lines_to_render[:-1] def get_warning_message(self): message_list = [ "!ERROR! : Out of mayonnaise.", "!WARNING! : Hacking too much time.", "!ERROR! : Speed has not reached 88mph.", "!CAUTION! : Ground approaching rapidly.", "!DANGER! : Troll in the dungeon.", "!WARNING! : Maximum recursion depth of 1 exceeded.", "!ERROR! : What the hell is even going on.", "!ERROR! : Improbability drive produced rats." ] a = rd.choice(message_list) if self.health <= 20: a = "!DANGER! : Juice levels critical!" return a def loop(self): self.clock.tick() self.time_ms = self.time_offset time_since_semicolon = 0 speed = 1000 progress = 0 press_tolerance = 0.2 multiplier_mentioned = 0 flashy = 0 self.last_error = self.time_ms beat = 0 won = 0 then = time.time() while True: pygame.event.pump() now = time.time() dt = now - then then = now dt = self.cam.time_step(dt) time_diff = dt * 1000 pressed = self.presses_since_last() self.clock.tick(self.framerate) prev_time = self.time_ms self.time_ms += time_diff if prev_time % self.beat_length > self.time_ms % self.beat_length: beat += 1 self.current_color += 1 if self.current_color >= 3: self.current_color = 0 if beat + 4 in self.beat_list: self.bang_list.append( Bang(self.time_ms + self.beat_length * 4, self.beat_length)) time_since_semicolon += time_diff for key in pressed[0:-1]: if key == 1: progress = min(progress + 0.15, 1.0) if pressed[ -1] == 1 and time_since_semicolon > 0.05 and progress == 1: for item in self.bang_list: if abs(item.beats_away(self.time_ms)) <= press_tolerance: self.multiplier += 1 flashy = 1 if self.multiplier % 5 == 0: self.update_lines("Current multiplier: %s" % self.multiplier) #self.success_sound.play() self.update_lines(self.get_next_line() + "") time_since_semicolon = 0 progress = 0 self.destroy_bang(item) self.make_flash() self.shock_offset = 5 for item in self.bang_list: if item.beats_away(self.time_ms) < -press_tolerance: #self.failure_sound.play() self.cam.set_target_center( (int(rd.random() * WINDOW_WIDTH), int(rd.random() * WINDOW_HEIGHT))) self.cam.set_target_zoom(rd.random() * 2 + 0.5) #self.health = max(0, self.health - 30) self.destroy_bang(item) #self.shock_offset = 50 self.update_lines(self.get_warning_message()) self.update_lines("Multiplier reset.") self.last_error = self.time_ms self.multiplier = 1.0 dif = (self.time_ms % self.beat_length) * 1.0 / self.beat_length self.render_background(dif) if flashy: flashy = 0 self.screen.fill((150, 150, 150)) num_over_one = 0 for idx, item in enumerate(self.flash_list): self.flash_list[idx] = item + dif / 8 if item > 1: num_over_one += 1 self.flash_list = self.flash_list[num_over_one:] self.render_flashes() min_rad = 0.3 goal_size = max(dif, 1 - dif)**4 goal_size = int((min_rad + goal_size * (1 - min_rad)) * 50) self.render_health() self.render_bangs(goal_size) self.render_goal(goal_size) self.render_lines() self.render_current_line(progress) self.additional_offset -= self.additional_offset * time_diff / 100.0 self.shock_offset *= -0.6 self.score += int(self.multiplier * time_diff) if self.health != 0: self.health = min(self.health + time_diff / 200.0, 100) self.render_score(0) if abs(self.shock_offset) <= 1: self.shock_offset = 0 if beat > 280 or self.health == 0: won = self.health > 0 break for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.display.quit() pygame.quit() sys.exit() self.cam.capture(self.screen) pygame.display.flip() while 1: time_diff = self.clock.tick(self.framerate) prev_time = self.time_ms self.time_ms += time_diff if prev_time % self.beat_length > self.time_ms % self.beat_length: self.current_color = (self.current_color + 1) % 3 self.shock_offset += 12 dif = (self.time_ms % self.beat_length) * 1.0 / self.beat_length self.render_background(dif) self.render_you_win(won) self.render_score(1) self.shock_offset *= -0.6 if abs(self.shock_offset) <= 1: self.shock_offset = 0 pygame.display.flip() def render_health(self): surf = pygame.Surface((300, 16)) surf.set_colorkey((0, 0, 0)) if self.health == 100: aim_color = (200, 200, 200) elif self.health >= 50: aim_color = (80, 110, 150) elif self.health >= 20: aim_color = (150, 140, 60) self.shock_offset += rd.choice([-1, 0, 1]) else: aim_color = (130, 50, 40) self.shock_offset += rd.choice([-2, 0, 2]) self.healthbar_color = [self.healthbar_color[i] + 5*(aim_color[i] - \ self.healthbar_color[i])/self.framerate for i in range(0, 3)] color = (self.healthbar_color[0], self.healthbar_color[1], self.healthbar_color[2]) self.healthbar_health += 3 * (self.health - self.healthbar_health) / self.framerate pygame.draw.rect(surf, color, (0, 0, 3 * self.healthbar_health, 16)) self.screen.blit(surf, (432 + self.shock_offset, 52 + self.shock_offset)) def render_you_win(self, won): if won: text = "Task completed." else: text = "Task failed." text_obj = self.win_font.render(text, 1, (255, 255, 255)) self.screen.blit(text_obj, (255 + self.shock_offset, 200 + self.shock_offset)) def render_background(self, dif): self.screen.fill((10, 10, 10)) if dif < 0.5: if self.current_color == 0: self.screen.fill( (35 - dif * 50, 35 - dif * 50, 70 - dif * 120)) elif self.current_color == 1: self.screen.fill((35 - dif * 50, 55 - dif * 90, 35 - dif * 50)) elif self.current_color == 2: self.screen.fill( (80 - dif * 140, 35 - dif * 50, 35 - dif * 50)) def render_current_line(self, progress): line = self.lines[self.line_idx] num_letters = int(progress * len(line)) new_line = line[0:num_letters] color = (155 + 100 * progress, 155 + 100 * progress, 155 + 100 * progress) # if progress == 1.0: # color = (150, 255, 180) hack = self.code_font.render(new_line, 1, color) self.screen.blit(hack, (120 + self.shock_offset, WINDOW_HEIGHT - 90 + self.yoffset + self.shock_offset)) def determine_keypresses(self): pressed = pygame.key.get_pressed() self.last_keypresses = [pressed[key] for key in self.key_list] return self.last_keypresses def presses_since_last(self): # -1 means key release a = self.last_keypresses b = self.determine_keypresses() c = [b[i] - a[i] for i in range(len(a))] return c def make_bang(self, beats_from_now): new_bang = Bang(self.time_ms + beats_from_now * self.beat_length) self.bang_list.append(new_bang) def destroy_bang(self, bang): self.bang_list.remove(bang)