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
Esempio n. 2
0
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
Esempio n. 3
0
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