def draw(self, screen: Surface, clock: pg.time.Clock) -> Optional[ScreenType]: player.handle_keys() light_mask = Surface((screen.get_width(), screen.get_height()), flags=SRCALPHA) light_mask.fill(Color(0, 0, 0)) # Draw stuff and fill the light mask with light sources map.draw(screen, light_mask) player.draw(screen, light_mask) screen.blit(light_mask, (0, 0)) monsters.draw_all(screen) clock.tick(60) try: logic.tick() except GameOverEx: return DefeatScreen except WonEx: return EndScreen fps = clock.get_fps() if fps > 0: pg.display.set_caption(f"FPS: {clock.get_fps()}") return None
def in_room(screen: pygame.display, clock: pygame.time.Clock, my_acc: Account, accounts: List[Account], room: Room) -> None: ViewHandler.clear_views() is_in_room = True sent_ready = False def game_listener(view): nonlocal is_in_room nonlocal sent_ready if not sent_ready: n.send("ready") print("Sent ready") sent_ready = True play = Button(WIDTH / 2 - 150, 50, 300) \ .set_text("Ready") \ .set_on_click_listener(game_listener) \ .set_on_hover_listener(on_hover) \ .set_on_unhover_listener(on_unhover) my_textview = TextView(50, 150, 200).set_text(my_acc.username) accounts_display = [] # type: List[TextView] for i, acc in enumerate(accounts): # type: int, Account accounts_display.append(TextView(WIDTH / 2, 200 + (i * 50), 300) .set_text(acc.username)) while is_in_room: data = n.receive() if data: if type(data) == Account: new_account = data print("got another acc") accounts.append(new_account) accounts_display.append(TextView(WIDTH / 2, 200 + ((len(accounts) - 1) * 50), 300) .set_text(new_account.username)) elif data == "ready": print("Got ready") room.running = True is_in_room = False else: print("-----------Weird data!!!!:", data) screen.fill(BACKGROUND_COLOR) events = pygame.event.get() for event in events: if event.type == pygame.QUIT: is_in_room = False pygame.quit() break ViewHandler.handle_view_events(events) ViewHandler.render_views(screen) pygame.display.update() clock.tick(60)
def game_over(self, surf: Surface, screen: Surface, dims: Tuple[int, int], clock: pygame.time.Clock) -> None: for _ in range(10): self.block_positions += 25 pygame.surfarray.blit_array(surf, self.block_positions) surf2 = pygame.transform.scale(surf, dims) screen.blit(surf2, (0, 0)) pygame.display.update() clock.tick(4)
def draw(screen: pygame.Surface, background: pygame.Surface, framerate: int, all_sprites: pygame.sprite.Group, clock: pygame.time.Clock, grid: Grid, current_time: int, grid_visible: bool) -> None: screen.blit(background, [0, 0]) all_sprites.update() if grid_visible: grid.draw_grid(screen, current_time) all_sprites.draw(screen) pygame.display.flip() clock.tick(framerate)
def game(screen: pygame.Surface, main_clock: pygame.time.Clock) -> None: """ Main game loop Parameters ---------- screen: pygame.Surface Screen to display game on main_clock: pygame.time.Clock Game clock """ GameState.load_level() draw_manager = DrawManager(screen) collision_manager = CollisionManager() input_manager = InputManager() running: bool = True while running and GameState.player.alive(): for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: running = False draw_manager.adjust_screen() input_manager.handle_input() physics_tick(collision_manager) collision_manager.check_all_collisions() if collision_manager.player_collides_goal(): # Level completed print(f"Level {GameState.level} completed!") GameState.next_level() draw_manager.draw_all() pygame.display.update() main_clock.tick(60) if not GameState.player.alive(): GameState.level = 1 running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: running = False draw_manager.draw_game_over() pygame.display.update()
def run_game(self, clock: pg.time.Clock) -> bool: """Run the game.""" run: bool = True # Check for events for event in pg.event.get(): if event.type == pg.QUIT: run = False # Code for slides elif event.type == pg.MOUSEBUTTONDOWN: pos = pg.mouse.get_pos() for s in self.slides: if s.button_rect.collidepoint(pos): s.hit = True elif event.type == pg.MOUSEBUTTONUP: for s in self.slides: s.hit = False # Fill the screen with black to remove old drawings self.screen.screen.fill(Colors.BLACK.value) # Draw arena self.arena.draw(self.screen.screen) # Move players self.physics.move_players() # Draw players for p in self.players: p.update_health() p.draw(self.screen.screen) # Draw plots for graph in self.graphs: graph.draw(self.screen.screen) # Move sliders for s in self.slides: if s.hit: pass s.move() # Draw sliders for s in self.slides: s.draw(self.screen.screen) pg.display.flip() clock.tick(60) if True in [p.health_bar.health <= 0 for p in self.players]: return False return run
def mainloop(screen: pg.Surface, main_clock: pg.time.Clock): background_color = "black" run = True time = 0 # angle for polar-to-cartesian conversion r = 100 wave = [] circles = 3 circle_color = (100, 100, 100) while run: for event in pg.event.get(): if event.type == pg.QUIT: run = False elif event.type == pg.KEYDOWN: if event.key == pg.K_UP: circles += 1 elif event.key == pg.K_DOWN: circles -= 1 screen.fill(background_color) x, y = 0, 0 for i in range(0, circles): previous_x = x previous_y = y n = i * 2 + 1 radius = r * (4.0 / (n * math.pi)) x += radius * math.cos(n * time) y += radius * math.sin(n * time) pg.draw.line(screen, "white", coords(previous_x, previous_y), coords(x, y)) pg.draw.circle(screen, circle_color, coords(previous_x, previous_y), radius=radius, width=1) wave.insert(0, y) if len(wave) > 2: pg.draw.aalines( screen, pg.Color("white"), False, [coords(200 + i, wave[i]) for i in range(len(wave))], 1) pg.draw.line(screen, pg.Color("white"), coords(x, y), coords(200, wave[0]), 1) time -= 0.02 pg.display.flip() main_clock.tick(60)
def prompt_difficulty( displaysurf: pg.surface.Surface, clock: pg.time.Clock) -> Tuple[str, Tuple[int, int, int]]: """난이도 선택 화면을 구현한다. Args: displaysurf: init 함수에 의해 반환된 최상위 Surface clock: init 함수에 의해 반환된 Clock Returns: 난이도, 난이도에 해당하는 색상을 tuple로 반환한다. """ allow: Dict[int, Tuple[str, Tuple[int, int, int]]] = { ord('e'): ('easy', ct.BLUETRACK), ord('n'): ('normal', ct.GREENTRACK), ord('h'): ('hard', ct.YELLOW), ord('i'): ('insane', ct.REDTRACK), ord('x'): ('extra', ct.RED) } write_text_ct(displaysurf, 60, (ct.WIDTH / 2, ct.HEIGHT * 0.15), 'Select difficulty', ct.WHITE) write_text_ct(displaysurf, 40, (ct.WIDTH / 2, ct.HEIGHT * 0.3), 'e: easy', ct.BLUETRACK) write_text_ct(displaysurf, 40, (ct.WIDTH / 2, ct.HEIGHT * 0.4), 'n: normal', ct.GREENTRACK) write_text_ct(displaysurf, 40, (ct.WIDTH / 2, ct.HEIGHT * 0.5), 'h: hard', ct.YELLOW) write_text_ct(displaysurf, 40, (ct.WIDTH / 2, ct.HEIGHT * 0.6), 'i: insane', ct.REDTRACK) write_text_ct(displaysurf, 40, (ct.WIDTH / 2, ct.HEIGHT * 0.7), 'x: extra', ct.RED) write_text_ct(displaysurf, 40, (ct.WIDTH / 2, ct.HEIGHT * 0.85), 'q: quit', ct.WHITE) while True: for event in pg.event.get(): if event.type == pg.QUIT\ or (event.type == pg.KEYDOWN and event.key == ord('q')): # 종료 pg.quit() sys.exit() if event.type == pg.KEYDOWN and event.key in allow: return allow[event.key] pg.display.update() clock.tick(ct.FPS)
def result(displaysurf: pg.surface.Surface, clock: pg.time.Clock, diff: str, diff_color: Tuple[int, int, int], score: int) -> None: """스코어보드를 업데이트하고 출력한다. Args: displaysurf: init 함수에 의해 반환된 최상위 Surface clock: init 함수에 의해 반환된 Clock diff: prompt_difficulty 함수에 의해 반환된 난이도 diff_color: prompt_difficulty 함수에 의해 반환된 난이도에 해당하는 색상 score: game 함수에 의해 반환된 점수 """ scorefile: Path = Path.cwd() / ct.SCOREDIR / f"{diff}.pkl" scores: List[int] = [] try: scores = pickle.load(scorefile.open("rb")) except FileNotFoundError: pass scores.append(score) scores.sort() scores.reverse() scores = scores[:5] pickle.dump(scores, scorefile.open("wb")) displaysurf.fill(ct.BLACK) write_text_ct(displaysurf, 60, (ct.WIDTH / 2, ct.HEIGHT * 0.15), f'Score ({diff})', diff_color) for i, sco in enumerate(scores): write_text_ct(displaysurf, 40, (ct.WIDTH / 2, ct.HEIGHT * (0.3 + 0.1 * i)), f'{i + 1}. {sco}', ct.WHITE) write_text_ct(displaysurf, 40, (ct.WIDTH / 2, ct.HEIGHT * 0.85), f'Your score: {score}', ct.WHITE) while True: for event in pg.event.get(): if event.type == pg.QUIT\ or (event.type == pg.KEYDOWN and event.key == ord('q')): # 종료 pg.quit() sys.exit() pg.display.update() clock.tick(ct.FPS)
def loop(self, screen: pygame.Surface, clock: pygame.time.Clock) -> None: self.loop_pre(screen) self.handle_events() self.update_screen(screen) pygame.display.flip() elapsed = clock.tick(config.fps) / 1000.0 self.loop_post(elapsed)
def show_power_menu(main_menu_buttons: button.ButtonRenderer, clock: pygame.time.Clock, dsp: pygame.Surface, bg_image: pygame.Surface, font: pygame.font.Font): in_menu = True power_buttons = button.ButtonRenderer(True) power_buttons.buttons.append(button.Button("Shutdown", WIDTH / 2, HEIGHT * (3/8), font)) power_buttons.buttons.append(button.Button("Reboot", WIDTH / 2, HEIGHT * (5 / 8), font)) power_buttons.active_button = 0 power_buttons.buttons[0].on_click = lambda: os.system("sudo shutdown -h now") power_buttons.buttons[1].on_click = lambda: os.system("sudo shutdown -r now") power_buttons.snap_position() while in_menu: clicked = False for event in pygame.event.get(): if event.type == pygame.QUIT: in_menu = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: in_menu = False if event.key == pygame.K_RETURN: clicked = True if event.type == pygame.JOYBUTTONDOWN: if inputsys.joystick_count: if inputsys.joy_in.get_button(INPUT_OK_BUTTON): clicked = True elif inputsys.joy_in.get_button(INPUT_BACK_BUTTON): in_menu = False power_buttons.update(clicked) dsp.fill((0, 0, 0)) dsp.blit(bg_image, (0, 0)) main_menu_buttons.draw(dsp, font) grey_screen(dsp) power_buttons.draw(dsp, font) pygame.display.update() clock.tick(FPS)
def update_thread(fps: float, clock: pygame.time.Clock): ''' This loop runs on a seperate thread, and controls the internal game logic Currently, this should run at around 500 fps ''' fps_controller = FPSController(fps) global done while not done: s_time = time.time() b.drive(pygame.key.get_pressed()) b.update_loc() e_time = time.time() work_time = e_time - s_time fps_controller.sleep(work_time, clock.get_fps()) clock.tick(1000)
def draw_thread(fps: float, clock: pygame.time.Clock): ''' This loop controls the graphics in the game, and runs on the main thread Should run at 60 FPS ''' fps_controller = FPSController(fps) global done while not done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True s_time = time.time() pygame.draw.rect(screen, (255, 255, 255), (0, 0, w, h)) b.draw(screen) pygame.display.flip() e_time = time.time() work_time = e_time - s_time fps_controller.sleep(work_time, clock.get_fps()) clock.tick(1000)
def intro(screen: pygame.Surface, clock: pygame.time.Clock, draw_callable: typing.Callable[[], None]) -> None: # make title screen title = pygame.Surface((settings.WIDTH, settings.HEIGHT)) title.blit(get_grass(settings.WIDTH, settings.HEIGHT), (0, 0)) title.blit(get_dirt(int(settings.WIDTH * 0.8), int(settings.HEIGHT * 0.8)), (int(settings.WIDTH * 0.1), int(settings.HEIGHT * 0.1))) title_text = settings.TITLE_FONT.render("Cultivate", True, pygame.Color("0x875ddd")) title.blit( title_text, pygame.Rect(settings.WIDTH // 2 - title_text.get_rect().w // 2, settings.HEIGHT // 2 - title_text.get_rect().h // 2, title_text.get_rect().w, title_text.get_rect().h)) # draw title screen and wait for 1 second screen.blit(title, (0, 0)) pygame.display.flip() game_wait(clock, 0.5) # scroll title screen for 3 seconds scroll_frames = settings.FPS * 1 dy = settings.HEIGHT // scroll_frames y = 0 while y > -settings.HEIGHT: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit(0) draw_callable() screen.blit(title, (0, y)) pygame.display.flip() y -= dy clock.tick(settings.FPS)
def game(displaysurf: pg.surface.Surface, clock: pg.time.Clock, diff: str, diff_color: Tuple[int, int, int]) -> int: """게임의 메인 로직을 실행한다. Args: displaysurf: init 함수에 의해 반환된 최상위 Surface clock: init 함수에 의해 반환된 Clock diff: prompt_difficulty 함수에 의해 반환된 난이도 diff_color: prompt_difficulty 함수에 의해 반환된 난이도에 해당하는 색상 Returns: 게임 결과(점수) """ screenrect = displaysurf.get_rect() # 게임 영역 설정 groupdict: Dict[str, pg.sprite.Group] = dict() # 그룹 불러오기 groupdict = { 'bullet': pg.sprite.Group(), 'player': pg.sprite.Group(), 'enemy': pg.sprite.Group(), 'danmaku': pg.sprite.Group() } spritedict: Dict[str, Element] = dict() parser = Parser(screenrect, groupdict, spritedict) # 패턴 구문분석 spritedict['player'] = parser.load('assets/player.json') groupdict['player'].add(spritedict['player']) # 플레이어 추가 loadeddict = loadfiles(diff) # 패턴 파일 로드 sounddict = loadsounds() _frame: int = 0 frame: int = 0 score: int = ct.INITIALSCORE limittime: float = ct.LIMITTIME onon: int = 0 # 변수 결정 pg.mixer.Sound.play(sounddict['bgm']) while True: # 게임 구동기 _frame += 1 # 시간 증가 frame += 1 if frame == limittime // 1 and onon == 0: # 게임 중 적 생성 시간일 때 enemychoose(groupdict['enemy'], parser, loadeddict) # 적 생성 frame = 0 # 적 생성 시간 초기화 if limittime > ct.OVERLIMIT: limittime -= ct.LIMITREDUCE # 적 생성 주기 단축 else: onon = 1 # 게임 종료 시간 if onon == 1: # 게임 끝 if frame == ct.OVERTIME: return score for event in pg.event.get(): groupdict['player'].update(event=event) # 객체 위치 이동 if event.type == pg.QUIT: # 종료 버튼 pg.quit() sys.exit() displaysurf.fill(ct.BLACK) # 배경 색 if pg.sprite.groupcollide(groupdict['player'], groupdict['danmaku'], False, False): score -= 1 # 부딫혔을 때 충돌 카운트 +1 pg.mixer.Sound.play(sounddict['gothit']) # 쏜 총이 적 맞았을 때 적 kill pg.sprite.groupcollide(groupdict['bullet'], groupdict['enemy'], False, True) enemyn = len(groupdict['enemy']) for key in groupdict: groupdict[key].update() # 모든 객체 위치 업데이트 groupdict[key].draw(displaysurf) # 적이 자연적으로 죽을 경우 페널티 score -= ct.PENALTY * (enemyn - len(groupdict['enemy'])) write_text(displaysurf, 60, (20, 20), f"{score}", ct.WHITE) write_text_rt(displaysurf, 60, (ct.WIDTH - 20, 20), diff, diff_color) pg.display.update() clock.tick(ct.FPS) # 시간 업데이트