async def main_game(): global SPRITES, SCREEN, COUNT, COUNTF, MY_POWERUPS main_group = pygame.sprite.LayeredUpdates() bombs_group = pygame.sprite.OrderedUpdates() enemies_group = pygame.sprite.OrderedUpdates() walls_group = pygame.sprite.OrderedUpdates() logging.info("Waiting for map information from server") state = await q.get() # first state message includes map information logging.debug("Initial game status: %s", state) newgame_json = json.loads(state) fps = newgame_json["fps"] GAME_SPEED = newgame_json["fps"] mapa = Map(size=newgame_json["size"], mapa=newgame_json["map"]) TIMEOUT = newgame_json["timeout"] s = scale(mapa.size) s2 = scale((10, 0)) SCREEN = pygame.display.set_mode([s[0] + s2[0], s[1] + s2[1]]) SPRITES = pygame.image.load("data/nes.png").convert_alpha() BACKGROUND = draw_background(mapa) SCREEN.blit(BACKGROUND, (0, 0)) main_group.add(BomberMan(pos=mapa.bomberman_spawn)) icon = pygame.Surface((CHAR_SIZE[0], CHAR_SIZE[1])) icon.blit(SPRITES, (0, 0), tuple([x for x in (*BOMBERMAN["down1"], *scale((1, 1)))])) pygame.display.set_icon(icon) state = {"score": 0, "player": "player1", "bomberman": (1, 1)} font_name = "data/digital-7.ttf" font = pygame.font.Font(font_name, int(22 * 2)) while True: offset_y = 1 SCREEN.blit(BACKGROUND, (0, 0)) pygame.event.pump() if pygame.key.get_pressed()[pygame.K_ESCAPE]: asyncio.get_event_loop().stop() main_group.clear(SCREEN, clear_callback) bombs_group.clear(SCREEN, BACKGROUND) enemies_group.clear(SCREEN, clear_callback) offset_y = add_player(SCREEN, state, mapa, offset_y, font, font_name) offset_y = add_level(SCREEN, state, mapa, offset_y, font, font_name) offset_y = add_score(SCREEN, state, mapa, offset_y, font, font_name) offset_y = add_lives(SCREEN, state, mapa, offset_y, font, font_name, fps) offset_y = add_powerups(SCREEN, state, mapa, offset_y, font, font_name) offset_y = add_steps(SCREEN, state, mapa, offset_y, font, font_name) if "bombs" in state: for bomb in bombs_group: if bomb.exploded: bombs_group.remove(bomb) if len(bombs_group.sprites()) < len(state["bombs"]): pos, timeout, radius = state["bombs"][-1] bombs_group.add(Bomb(pos=pos, timeout=timeout, radius=radius)) if len(bombs_group.sprites()) > len(state["bombs"]): bombs_group.empty() bombs_group.update(state["bombs"]) if "enemies" in state: enemies_group.empty() for enemy in state["enemies"]: enemies_group.add(Enemy(name=enemy["name"], pos=enemy["pos"])) if "walls" in state: walls_group.empty() for wall in state["walls"]: walls_group.add(Wall(pos=wall)) if "exit" in state and len(state["exit"]): if not [p for p in main_group if isinstance(p, Exit)]: logger.debug("Add Exit") ex = Exit(pos=state["exit"]) main_group.add(ex) main_group.move_to_back(ex) if "powerups" in state: for pos, name in state["powerups"]: if name not in [ p.type for p in main_group if isinstance(p, Powerups) ]: logger.debug(f"Add {name}") p = Powerups(pos=pos, name=name) main_group.add(p) main_group.move_to_back(p) for powerup in main_group: if isinstance(powerup, Powerups): name = powerup.type if name not in [p[1] for p in state["powerups"]]: MY_POWERUPS.append(name) logger.debug(f"Remove {name}") main_group.remove(powerup) walls_group.draw(SCREEN) main_group.draw(SCREEN) enemies_group.draw(SCREEN) bombs_group.draw(SCREEN) # Highscores Board if (("lives" in state and state["lives"] == 0) or ("step" in state and state["step"] >= TIMEOUT) or ("bomberman" in state and "exit" in state and state["bomberman"] == state["exit"] and "enemies" in state and state["enemies"] == [])): highscores = newgame_json["highscores"] if (f"{state['player']}", state["score"]) not in highscores: highscores.append((f"{state['player']}", state["score"])) highscores = sorted(highscores, key=lambda s: s[1], reverse=True)[:-1] HIGHSCORES = pygame.Surface(scale((22, 16))) HIGHSCORES.fill(COLORS["grey"]) draw_info(HIGHSCORES, "THE 10 BEST PLAYERS", scale((5, 1)), COLORS["white"]) draw_info(HIGHSCORES, "RANK", scale((2, 3)), COLORS["orange"]) draw_info(HIGHSCORES, "SCORE", scale((6, 3)), COLORS["orange"]) draw_info(HIGHSCORES, "NAME", scale((11, 3)), COLORS["orange"]) draw_info(HIGHSCORES, "TOTAL STEPS", scale((15, 3)), COLORS["orange"]) MY_POWERUPS = [] for i, highscore in enumerate(highscores): if i < 10: c = (i % 5) + 1 draw_info( HIGHSCORES, RANKS[i + 1], scale((2, i + 5)), list(COLORS.values())[c], ) draw_info( HIGHSCORES, str(highscore[1]), scale((6, i + 5)), list(COLORS.values())[c], ) draw_info( HIGHSCORES, highscore[0], scale((11, i + 5)), list(COLORS.values())[c], ) if len(highscore) > 2: draw_info(HIGHSCORES, str(highscore[2]), scale((15, i + 5)), list(COLORS.values())[c]) SCREEN.blit( HIGHSCORES, ( (SCREEN.get_width() - HIGHSCORES.get_width()) / 2, (SCREEN.get_height() - HIGHSCORES.get_height()) / 2, ), ) if "bomberman" in state: main_group.update(state["bomberman"]) pygame.display.flip() try: state = json.loads(q.get_nowait()) if ("step" in state and state["step"] == 1 or "level" in state and state["level"] != mapa.level): # New level! lets clean everything up! SCREEN.blit(BACKGROUND, (0, 0)) walls_group.empty() main_group.empty() enemies_group.empty() bombs_group.empty() main_group.add(BomberMan(pos=mapa.bomberman_spawn)) mapa.level = state["level"] except asyncio.queues.QueueEmpty: await asyncio.sleep(1.0 / GAME_SPEED) continue
async def main_game(): global SPRITES, SCREEN main_group = pygame.sprite.LayeredUpdates() bombs_group = pygame.sprite.OrderedUpdates() enemies_group = pygame.sprite.OrderedUpdates() walls_group = pygame.sprite.OrderedUpdates() logging.info("Waiting for map information from server") state = await q.get() # first state message includes map information logging.debug("Initial game status: %s", state) newgame_json = json.loads(state) GAME_SPEED = newgame_json["fps"] mapa = Map(size=newgame_json["size"], mapa=newgame_json["map"]) TIMEOUT = newgame_json["timeout"] SCREEN = pygame.display.set_mode(scale(mapa.size)) SPRITES = pygame.image.load("data/nes.png").convert_alpha() BACKGROUND = draw_background(mapa) SCREEN.blit(BACKGROUND, (0, 0)) main_group.add(BomberMan(pos=mapa.bomberman_spawn)) state = {"score": 0, "player": "player1", "bomberman": (1, 1)} while True: SCREEN.blit(BACKGROUND, (0, 0)) pygame.event.pump() if pygame.key.get_pressed()[pygame.K_ESCAPE]: asyncio.get_event_loop().stop() main_group.clear(SCREEN, clear_callback) bombs_group.clear(SCREEN, BACKGROUND) enemies_group.clear(SCREEN, clear_callback) if "score" in state and "player" in state: text = str(state["score"]) draw_info(SCREEN, text.zfill(6), (5, 1)) text = str(state["player"]).rjust(32) draw_info(SCREEN, text, (4000, 1)) if "lives" in state and "level" in state: w, h = draw_info(SCREEN, "lives: ", (SCREEN.get_width() / 4, 1)) draw_info(SCREEN, f"{state['lives']}", (SCREEN.get_width() / 4 + w, 1), color=(255, 0, 0)) w, h = draw_info(SCREEN, "level: ", (2 * SCREEN.get_width() / 4, 1)) draw_info(SCREEN, f"{state['level']}", (2 * SCREEN.get_width() / 4 + w, 1), color=(255, 0, 0)) if "step" in state: w, h = draw_info(SCREEN, "steps: ", (3 * SCREEN.get_width() / 4, 1)) draw_info(SCREEN, f"{state['step']}", (3 * SCREEN.get_width() / 4 + w, 1), color=(255, 0, 0)) if "bombs" in state: for bomb in bombs_group: if bomb.exploded: bombs_group.remove(bomb) if len(bombs_group.sprites()) < len(state["bombs"]): pos, timeout, radius = state["bombs"][-1] bombs_group.add(Bomb(pos=pos, timeout=timeout, radius=radius)) if len(bombs_group.sprites()) > len(state["bombs"]): bombs_group.empty() bombs_group.update(state["bombs"]) if "enemies" in state: enemies_group.empty() for enemy in state["enemies"]: enemies_group.add(Enemy(name=enemy["name"], pos=enemy["pos"])) if "walls" in state: walls_group.empty() for wall in state["walls"]: walls_group.add(Wall(pos=wall)) if "exit" in state and len(state["exit"]): if not [p for p in main_group if isinstance(p, Exit)]: logger.debug("Add Exit") ex = Exit(pos=state["exit"]) main_group.add(ex) main_group.move_to_back(ex) if "powerups" in state: for pos, name in state["powerups"]: if name not in [ p.type for p in main_group if isinstance(p, Powerups) ]: logger.debug(f"Add {name}") p = Powerups(pos=pos, name=name) main_group.add(p) main_group.move_to_back(p) for powerup in main_group: if isinstance(powerup, Powerups): name = powerup.type if name not in [p[1] for p in state["powerups"]]: logger.debug(f"Remove {name}") main_group.remove(powerup) walls_group.draw(SCREEN) main_group.draw(SCREEN) enemies_group.draw(SCREEN) bombs_group.draw(SCREEN) # Highscores Board if (("lives" in state and state["lives"] == 0) or ("step" in state and state["step"] >= TIMEOUT) or ("bomberman" in state and "exit" in state and state["bomberman"] == state["exit"] and "enemies" in state and state["enemies"] == [])): highscores = newgame_json["highscores"] if (f"<{state['player']}>", state["score"]) not in highscores: highscores.append((f"<{state['player']}>", state["score"])) highscores = sorted(highscores, key=lambda s: s[1], reverse=True)[:-1] HIGHSCORES = pygame.Surface(scale((20, 16))) HIGHSCORES.fill(COLORS["grey"]) draw_info(HIGHSCORES, "THE 10 BEST PLAYERS", scale((5, 1)), COLORS["white"]) draw_info(HIGHSCORES, "RANK", scale((2, 3)), COLORS["orange"]) draw_info(HIGHSCORES, "SCORE", scale((6, 3)), COLORS["orange"]) draw_info(HIGHSCORES, "NAME", scale((11, 3)), COLORS["orange"]) for i, highscore in enumerate(highscores): c = (i % 5) + 1 draw_info( HIGHSCORES, RANKS[i + 1], scale((2, i + 5)), list(COLORS.values())[c], ) draw_info( HIGHSCORES, str(highscore[1]), scale((6, i + 5)), list(COLORS.values())[c], ) draw_info( HIGHSCORES, highscore[0], scale((11, i + 5)), list(COLORS.values())[c], ) SCREEN.blit( HIGHSCORES, ( (SCREEN.get_width() - HIGHSCORES.get_width()) / 2, (SCREEN.get_height() - HIGHSCORES.get_height()) / 2, ), ) if "bomberman" in state: main_group.update(state["bomberman"]) pygame.display.flip() try: state = json.loads(q.get_nowait()) if ("step" in state and state["step"] == 1 or "level" in state and state["level"] != mapa.level): # New level! lets clean everything up! SCREEN.blit(BACKGROUND, (0, 0)) walls_group.empty() main_group.empty() enemies_group.empty() bombs_group.empty() main_group.add(BomberMan(pos=mapa.bomberman_spawn)) mapa.level = state["level"] except asyncio.queues.QueueEmpty: await asyncio.sleep(1.0 / GAME_SPEED) continue
async def main_loop(queue): """Processes events from server and display's.""" global SPRITES, SCREEN main_group = pygame.sprite.LayeredUpdates() boxes_group = pygame.sprite.OrderedUpdates() logging.info("Waiting for map information from server") state = await queue.get() # first state message includes map information logging.debug("Initial game status: %s", state) newgame_json = json.loads(state) GAME_SPEED = newgame_json["fps"] try: mapa = Map(newgame_json["map"]) except (KeyError, FileNotFoundError): mapa = Map("levels/1.xsb") # Fallback to initial map SCREEN = pygame.display.set_mode(scale(mapa.size)) SPRITES = pygame.image.load("data/sokoban.png").convert_alpha() BACKGROUND = draw_background(mapa) SCREEN.blit(BACKGROUND, (0, 0)) main_group.add(Keeper(pos=mapa.keeper)) state = { "score": 0, "player": "player1", "keeper": mapa.keeper, "boxes": mapa.boxes, } new_event = True while True: SCREEN.blit(BACKGROUND, (0, 0)) pygame.event.pump() if pygame.key.get_pressed()[pygame.K_ESCAPE]: asyncio.get_event_loop().stop() main_group.clear(SCREEN, clear_callback) boxes_group.clear(SCREEN, clear_callback) if "score" in state and "player" in state: text = f"m, p, s: {state['score']}" draw_info(SCREEN, text.zfill(6), (5, 1)) text = str(state["player"]).rjust(32) draw_info(SCREEN, text, (4000, 1)) if "level" in state: w, _ = draw_info(SCREEN, "level: ", (SCREEN.get_width() / 2, 1)) draw_info( SCREEN, f"{state['level']}", (SCREEN.get_width() / 2 + w, 1), color=(200, 20, 20), ) if "boxes" in state: boxes_group.empty() for box in state["boxes"]: boxes_group.add( Box( pos=box, stored=mapa.get_tile(box) in [Tiles.GOAL, Tiles.BOX_ON_GOAL], )) boxes_group.draw(SCREEN) main_group.draw(SCREEN) # Highscores Board if "highscores" in state and "player" in state: if new_event: highscores = state["highscores"] highscores.append( (f"<{state['player']}>", reduce_score(state["score"]))) highscores = sorted(highscores, key=lambda s: s[1]) highscores = highscores[:len(RANKS)] HIGHSCORES = pygame.Surface((256, 280)) HIGHSCORES.fill((30, 30, 30)) COLS = [20, 80, 150] draw_info(HIGHSCORES, "THE 10 BEST PLAYERS", (20, 10), COLORS["white"]) for value, column in zip(["RANK", "SCORE", "NAME"], COLS): draw_info(HIGHSCORES, value, (column, 30), COLORS["orange"]) for i, highscore in enumerate(highscores): color = ( random.randrange(66, 222), random.randrange(66, 222), random.randrange(66, 222), ) for value, column in zip( [RANKS[i + 1], str(highscore[1]), highscore[0]], COLS): draw_info(HIGHSCORES, value, (column, 60 + i * 20), color) SCREEN.blit( HIGHSCORES, ( (SCREEN.get_width() - HIGHSCORES.get_width()) / 2, (SCREEN.get_height() - HIGHSCORES.get_height()) / 2, ), ) if "keeper" in state: main_group.update(state["keeper"]) pygame.display.flip() try: state = json.loads(queue.get_nowait()) new_event = True if "step" in state and state["step"] <= 1: logger.debug("New Level!") # New level! lets clean everything up! try: mapa = Map(f"levels/{state['level']}.xsb") except FileNotFoundError: logger.error( "Can't find levels/%s.xsb, means we have a WINNER!", state["level"], ) continue SCREEN = pygame.display.set_mode(scale(mapa.size)) BACKGROUND = draw_background(mapa) SCREEN.blit(BACKGROUND, (0, 0)) boxes_group.empty() main_group.empty() main_group.add(Keeper(pos=mapa.keeper)) mapa.level = state["level"] pygame.display.flip() except asyncio.queues.QueueEmpty: await asyncio.sleep(1.0 / GAME_SPEED) new_event = False continue