Esempio n. 1
0
    def start(self, player_name):
        logger.debug("Reset world")
        self._player_name = player_name
        self._running = True
        self._score = INITIAL_SCORE
        self._bomberman = Bomberman(self.map.bomberman_spawn, self._initial_lives)

        self.next_level(self.initial_level)
Esempio n. 2
0
    def start(self, player_name):
        logger.debug("Reset world")
        self._player_name = player_name
        self._running = True
        self._total_steps = 0
        self._score = INITIAL_SCORE
        self._bomberman = Bomberman(self.map.bomberman_spawn, self._initial_lives)
        for powerup in range(1, self.initial_level):
            self._bomberman.powerup(LEVEL_POWERUPS[powerup])
        logger.debug("Bomberman Powerups: %s", self._bomberman.powers)

        self.next_level(self.initial_level)
Esempio n. 3
0
    def next_level(self, level):
        if level > len(LEVEL_ENEMIES):
            logger.info("You WIN!")
            self.stop()
            return

        logger.info("NEXT LEVEL")
        self.map = Map(level=level, size=self.map.size, enemies=len(LEVEL_ENEMIES[level]))
        self._step = 0
        self._bomberman = Bomberman(self.map.bomberman_spawn, self._initial_lives)
        self._bombs = []
        self._powerups = []
        self._bonus = []
        self._exit = []
        self._lastkeypress = ""
        self._bomb_radius = 3
        self._enemies = [
            t(p) for t, p in zip(LEVEL_ENEMIES[level], self.map.enemies_spawn)
        ]
Esempio n. 4
0
class Game:
    def __init__(self, level=1, lives=LIVES, timeout=TIMEOUT, size=MAP_SIZE):
        logger.info(f"Game(level={level}, lives={lives})")
        self.initial_level = level
        self._running = False
        self._timeout = timeout
        self._score = 0
        self._state = {}
        self._initial_lives = lives
        self.map = Map(size=size, empty=True)
        self._enemies = []

    def info(self):
        return {
            "size": self.map.size,
            "map": self.map.map,
            "fps": GAME_SPEED,
            "timeout": TIMEOUT,
            "lives": LIVES,
            "score": self.score,
        }

    @property
    def running(self):
        return self._running

    @property
    def score(self):
        return self._score

    def start(self, player_name):
        logger.debug("Reset world")
        self._player_name = player_name
        self._running = True
        self._score = INITIAL_SCORE
        self._bomberman = Bomberman(self.map.bomberman_spawn,
                                    self._initial_lives)

        self.next_level(self.initial_level)

    def stop(self):
        logger.info("GAME OVER")
        self._running = False

    def next_level(self, level):
        if level > len(LEVEL_ENEMIES):
            logger.info("You WIN!")
            self.stop()
            return

        logger.info("NEXT LEVEL")
        self.map = Map(level=level,
                       size=self.map.size,
                       enemies=len(LEVEL_ENEMIES[level]))
        self._bomberman.respawn()
        self._step = 0
        self._bombs = []
        self._powerups = []
        self._bonus = []
        self._exit = []
        self._lastkeypress = ""
        self._enemies = [
            t(p) for t, p in zip(LEVEL_ENEMIES[level], self.map.enemies_spawn)
        ]
        logger.debug(self._enemies)

    def quit(self):
        logger.debug("Quit")
        self._running = False

    def keypress(self, key):
        self._lastkeypress = key

    def update_bomberman(self):
        try:
            if self._lastkeypress.isupper():
                # Parse action
                if self._lastkeypress == "A" and len(self._bombs) > 0:
                    self._bombs[0].detonate(
                    )  # always detonate the oldest bomb
                elif (self._lastkeypress == "B" and len(self._bombs) <
                      self._bomberman.powers.count(Powerups.Bombs) + 1):
                    self._bombs.append(
                        Bomb(
                            self._bomberman.pos,
                            self.map,
                            MIN_BOMB_RADIUS + self._bomberman.flames(),
                            detonator=Powerups.Detonator
                            in self._bomberman.powers,
                        ))  # must be dependent of powerup
            else:
                # Update position
                new_pos = self.map.calc_pos(
                    self._bomberman.pos, self._lastkeypress,
                    self._bomberman.wallpass)  # don't bump into stones/walls
                if self._bomberman.bombpass or new_pos not in [
                        b.pos for b in self._bombs
                ]:  # don't pass over bombs
                    self._bomberman.pos = new_pos
                for pos, _type in self._powerups:  # consume powerups
                    if new_pos == pos:
                        self._bomberman.powerup(_type)
                        self._powerups.remove((pos, _type))

        except AssertionError:
            logger.error("Invalid key <%s> pressed. Valid keys: w,a,s,d A B",
                         self._lastkeypress)
        finally:
            self._lastkeypress = ""  # remove inertia

        if len(self._enemies) == 0 and self._bomberman.pos == self._exit:
            logger.info(f"Level {self.map.level} completed")
            #self._score += self._timeout - self._step
            self.next_level(self.map.level + 1)

    def kill_bomberman(self):
        logger.info(f"bomberman has died on step: {self._step}")
        self._bomberman.kill()
        logger.debug(f"bomberman has now {self._bomberman.lives} lives")
        if self._bomberman.lives > 0:
            logger.debug("RESPAWN")
            self._bomberman.respawn()
        else:
            self.stop()

    def collision(self):
        for e in self._enemies:
            if e.pos == self._bomberman.pos:
                self.kill_bomberman()
                e.respawn()

    def explode_bomb(self):
        for bomb in self._bombs[:]:
            bomb.update()
            if bomb.exploded():
                logger.debug("BOOM")
                if bomb.in_range(
                        self._bomberman) and not self._bomberman.flamepass:
                    self.kill_bomberman()

                for wall in self.map.walls[:]:
                    if bomb.in_range(wall):
                        logger.debug(f"Destroying wall @{wall}")
                        self.map.remove_wall(wall)
                        if self.map.exit_door == wall:
                            self._exit = wall
                        if self.map.powerup == wall:
                            self._powerups.append(
                                (wall, LEVEL_POWERUPS[self.map.level]))

                for enemy in self._enemies[:]:
                    if bomb.in_range(enemy):
                        logger.debug(f"killed enemy @{enemy}")
                        self._score += enemy.points()
                        self._enemies.remove(enemy)

                self._bombs.remove(bomb)

    async def next_frame(self):
        await asyncio.sleep(1.0 / GAME_SPEED)

        if not self._running:
            logger.info("Waiting for player 1")
            return

        self._step += 1
        if self._step == self._timeout:
            self.stop()

        if self._step % 100 == 0:
            logger.debug(
                f"[{self._step}] SCORE {self._score} - LIVES {self._bomberman.lives}"
            )

        self.explode_bomb()
        self.update_bomberman()
        self.collision()

        if (self._step % (self._bomberman.powers.count(Powerups.Speed) + 1) ==
                0):  # increase speed of bomberman by moving enemies less often
            for enemy in self._enemies:
                enemy.move(self.map, self._bomberman, self._bombs,
                           self._enemies)
            self.collision()

        self._state = {
            "level":
            self.map.level,
            "step":
            self._step,
            "timeout":
            self._timeout,
            "player":
            self._player_name,
            "score":
            self._score,
            "lives":
            self._bomberman.lives,
            "bomberman":
            self._bomberman.pos,
            "bombs": [(b.pos, b.timeout, b.radius) for b in self._bombs],
            "enemies": [{
                "name": str(e),
                "id": str(e.id),
                "pos": e.pos
            } for e in self._enemies],
            "walls":
            self.map.walls,
            "powerups": [(p, Powerups(n).name) for p, n in self._powerups],
            "bonus":
            self._bonus,
            "exit":
            self._exit,
        }

    @property
    def state(self):
        # logger.debug(self._state)
        return json.dumps(self._state)