def run_game(): pygame.init() pygame.mixer.init() ai_settings = Settings() screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height)) pygame.mixer.music.load('sounds/bg_music2.mp3') pygame.mixer.music.play() pygame.mixer.music.set_volume(0.5) pygame.display.set_caption("Perestroika") bracing = Bracing(screen) GlobalState() blocks = Group() tower = Tower() trucks = Group() record = None for r in Record.filter(user="******"): record = r if record is None: record = Record(user="******", score=0) record.save() GlobalState().record = record builder = Builder(screen) block = Block(bracing) block.make_static() button = Button(screen) while True: gf.check_events(bracing, blocks, tower, builder, block, trucks, button) builder.update() bracing.update() blocks.update(bracing) block.update(bracing) trucks.update() gf.update_screen(screen, bracing, blocks, builder, block, trucks, button) GlobalState().ticks += 1
def check_collisions(blocks): sprite_list = blocks.sprites() inv_sprite_list = sprite_list if len(sprite_list) == 0: return if len(sprite_list) == 1: if sprite_list[0].rect.bottom >= Settings().screen_height: sprite_list[0].stop = True sprite_list[0].rect.bottom = Settings().screen_height GlobalState().falling = False else: top_block = sprite_list[-1] width = top_block.rect.right - top_block.rect.left pre_top_block = sprite_list[-2] offset = abs(top_block.rect.left - pre_top_block.rect.left) inv_sprite_list.reverse() for i in range(1, len(sprite_list)): new_off = abs(inv_sprite_list[i].rect.left - top_block.rect.left) if new_off < width: offset = new_off pre_top_block = inv_sprite_list[i] break if offset > width: if top_block.rect.bottom >= Settings().screen_height: top_block.stop = True top_block.rect.bottom = Settings().screen_height GlobalState().falling = False elif top_block.rect.bottom >= pre_top_block.rect.top: top_block.stop = True top_block.rect.bottom = pre_top_block.rect.top GlobalState().falling = False
def check_keyup_events(event, bracing, builder): if event.key == pygame.K_RIGHT and not GlobalState().over: bracing.moving_right = False builder.right = False builder.anim_queue.append("from_right") elif event.key == pygame.K_LEFT and not GlobalState().over: bracing.moving_left = False builder.left = False builder.anim_queue.append("from_left")
def check_game(bracing, blocks, tower, builder, block): if GlobalState().over and not GlobalState().falling: # resetting bracing.moving_left = False bracing.moving_right = False builder.reset() for i in range(tower.size): tower.pop() blocks.remove(blocks.sprites()[0]) GlobalState().blocked = False # GlobalState().falling = False block.make_static()
def update(self): if self.moving_left and self.rect.left > self.screen_rect.left: self.center -= GlobalState().bracing_speed if self.moving_right and self.rect.right < self.screen_rect.right - 200: self.center += GlobalState().bracing_speed self.rect.centerx = self.center if self.moving_left or self.moving_right: self.shaker *= -1 self.rect.top += self.shaker else: self.rect.top = self.screen_rect.top + 170
def wrapper_func(bracing, blocks, tower, builder, block): function_to_decorate(bracing, blocks, tower, builder, block) if GlobalState().over and not GlobalState( ).falling and GlobalState().score > GlobalState().record.score: GlobalState().record.score = GlobalState().score GlobalState().record.save() GlobalState().score = 0
def check_limit(blocks, tower): if len(tower) >= GlobalState().limit: if blocks.sprites()[-1].stop: for i in range(1): tower.pop() blocks.remove(blocks.sprites()[0]) normalize_tower(blocks)
def check_events(bracing, blocks, tower, builder, block, trucks, button): for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: check_keydown_events(event, bracing, blocks, tower, builder, block) elif event.type == pygame.KEYUP: check_keyup_events(event, bracing, builder) elif event.type == pygame.MOUSEBUTTONDOWN: mouse_x, mouse_y = pygame.mouse.get_pos() check_start_button(button, mouse_x, mouse_y) spawn_trucks(trucks, bracing.screen) check_collisions(blocks) check_limit(blocks, tower) if not tower.sustainable: GlobalState().blocked = True GlobalState().over = True check_limit(blocks, tower) check_game(bracing, blocks, tower, builder, block)
def update_screen(screen, bracing, blocks, builder, block, trucks, button): screen.blit(Settings().bg_pic, (0, 0)) trucks.draw(screen) blocks.draw(screen) bracing.blitme() builder.blitme() block.blitme() if GlobalState().over: button.draw_button() pygame.display.flip()
def __init__(self, bracing): super().__init__() self.screen = bracing.screen self.image = pygame.image.load("images/block.jpg") self.trans = pygame.image.load("images/transparent.png") self.rect = self.image.get_rect() self.rect.centerx = bracing.center self.rect.top = GlobalState().y0 self.release_time = time.time() self.stop = False self.state = 'default' self.dir_set = 'none'
def sustainable(self): tower_height = len(self) if GlobalState().falling or tower_height < 2: return True width = self._blocks[0].rect.right - self._blocks[0].rect.left counter = 1 sum_center = self._blocks[-1].rect.centerx for i in range(tower_height - 2, -1, -1): # up -> down block_x = self._blocks[i].rect.centerx if abs(block_x - sum_center) > width / 2: return False sum_center = (block_x + counter * sum_center) / (counter + 1) counter += 1 return True
def update(self, bracing): if GlobalState().over: self.rect.centerx = -100 return if self.state == 'default': if not self.stop: current_time = time.time() t = current_time - self.release_time self.rect.top = GlobalState( ).y0 + GlobalState().acceleration * t**2 if self.dir_set == 'none': if bracing.moving_right: self.dir_set = 'right' elif bracing.moving_left: self.dir_set = 'left' else: self.dir_set = 'center' if self.dir_set == 'right': self.rect.centerx += GlobalState().bracing_speed - 2 elif self.dir_set == 'left': self.rect.centerx -= GlobalState().bracing_speed - 2 elif self.state == 'static': width = self.rect.right - self.rect.left interval = True if random.random() > 0.5 else False left_edge = 10 right_edge = Settings().screen_width - 350 left = bracing.rect.centerx - int(width * 1.5) right = bracing.rect.centerx + int(width * 0.5) if left < left_edge: self.rect.left = random.randint(right, right_edge) elif right > right_edge: self.rect.left = random.randint(left_edge, left) else: if interval: self.rect.left = random.randint(left_edge, left) else: self.rect.left = random.randint(right, right_edge) self.state = 'waiting' elif self.state == 'waiting': GlobalState().blocked = True if abs(bracing.rect.centerx - self.rect.centerx) < 5: self.state = 'hooked' elif self.state == 'hooked': GlobalState().blocked = False self.rect.centerx = bracing.rect.centerx
def check_keydown_events(event, bracing, blocks, tower, builder, block): if event.key == pygame.K_RIGHT and not GlobalState().over: bracing.moving_right = True builder.anim_queue.append("to_right") builder.right = True elif event.key == pygame.K_LEFT and not GlobalState().over: bracing.moving_left = True builder.anim_queue.append("to_left") builder.left = True elif event.key == pygame.K_SPACE and not GlobalState().blocked and not GlobalState().falling: new_block = Block(bracing) blocks.add(new_block) tower.push(new_block) GlobalState().falling = True block.state = 'static' GlobalState().played = False elif event.key == pygame.K_p: mods = pygame.key.get_mods() if mods & pygame.KMOD_CTRL: GlobalState().score += 50
def check_start_button(button, mouse_x, mouse_y): if button.rect.collidepoint(mouse_x, mouse_y) and GlobalState().over: GlobalState().over = False
def spawn_trucks(trucks, screen): if GlobalState().ticks >= 400: trucks.add(Truck(screen)) GlobalState().ticks = 0
def push(self, value): self._blocks.append(value) GlobalState().score += 1