コード例 #1
0
ファイル: game.py プロジェクト: iainduncani/pacman-kata
class Game(object):
    def __init__(self, inputMap=None):
        if inputMap is not None:
            self.inputMap = inputMap.rstrip()
        self.field = None
        self.lives = 3
        self.score = 0
        self.pacman = None
        self.ghosts = []
        self.pills = []
        self.walls = []
        self.gameOver = False
        self.controller = None
        self.gate = None
        self.level = 1
        self.lastLevel = 1
        self.levelMaps = None
        self.animation = False

    def play(self, debug):
        self.parse()
        while (self.gameOver is False):
            self.tick()
            self.render()
            self.refresh()
            sleep(0.1)
            if (self.pacman.alive is False):
                self.pacman.restart()
            if (debug is True):
                self.gameOver = True

    def parse(self):
        if self.levelMaps:
            self.inputMap = self.levelMaps.getLevel(self.level)
        else:
            if "SEPARATOR" in self.inputMap:
                self.levelMaps = LevelMaps(self.inputMap)
                self.lastLevel = self.levelMaps.maxLevel()
                self.inputMap = self.levelMaps.getLevel(self.level)
        columns = self.inputMap.index("\n")
        self.parseStatus(self.inputMap[:columns])
        screenRows = self.inputMap[columns + 1:].split('\n')
        rows = len(screenRows)
        self.field = GameField(columns, rows)
        self.parseField(screenRows)

    def parseStatus(self, statusLine):
        elements = statusLine.split()
        try:
            self.lives = int(elements[0])
            self.score = int(elements[1])
        except ValueError:
            pass

    def parseField(self, screenRows):
        for y in range(self.field.height()):
            for x in range(self.field.width()):
                if Pacman.isPacman(screenRows[y][x]):
                    self.pacman = Pacman(self, (x, y), screenRows[y][x])
                    self.pacman.useAnimation(self.animation)
                    self.field.add((x, y), self.pacman)
                if Wall.isWall(screenRows[y][x]):
                    wall = Wall((x, y), screenRows[y][x])
                    self.walls.append(wall)
                    self.field.add((x, y), wall)
                    if Wall.isGate(screenRows[y][x]):
                        self.gate = wall
                if Pill.isPill(screenRows[y][x]):
                    pill = Pill((x, y), screenRows[y][x])
                    self.pills.append(pill)
                    self.field.add((x, y), pill)
                if Ghost.isGhost(screenRows[y][x]):
                    ghost = Ghost(self, (x, y), screenRows[y][x])
                    self.ghosts.append(ghost)
                    self.field.add((x, y), ghost)

    def setGameField(self, width, height):
        self.field = GameField(width, height)

    def setPacman(self, coordinates, direction):
        self.pacman = Pacman(self, coordinates)
        self.pacman.setDirection(direction)
        self.field.add(coordinates, self.pacman)

    def addWall(self, coordinates, icon):
        wall = Wall(coordinates, icon)
        self.walls.append(wall)
        self.field.add(coordinates, wall)

    def tick(self):
        if not self.gameOver:
            for ghost in self.ghosts:
                ghost.tick()
            if self.pacman:
                self.pacman.tick()
        self.updateField()

    def render(self):
        self.output = "{lives:1d}".format(lives=self.lives)
        self.output += "{score:>{width}d}\n".format(score=self.score,
                                                    width=self.field.width() -
                                                    len(self.output))
        self.output += self.field.render()

    def refresh(self):
        print("\u001B[H" + "\u001B[2J" + "\u001B[1m")
        print(self.output)

    def updateField(self):
        newField = GameField(self.field.width(), self.field.height())
        for wall in self.walls:
            newField.add(wall.coordinates, wall)
        for pill in self.pills:
            newField.add(pill.coordinates, pill)
        for ghost in self.ghosts:
            newField.add(ghost.coordinates, ghost)
        if self.pacman:
            newField.add(self.pacman.coordinates, self.pacman)
        if self.gameOver:
            Game.printGameOver(newField)
        self.field = newField

    def getElement(self, coords):
        return self.field.get(coords)

    def isGhost(self, coordinates):
        return Ghost.isGhost(self.field.get(coordinates))

    def isWall(self, coordinates):
        return Wall.isWall(self.field.get(coordinates))

    def isGate(self, coordinates):
        return Wall.isGate(self.field.get(coordinates))

    def isField(self, coordinates):
        return Wall.isField(self.field.get(coordinates))

    def isPill(self, coordinates):
        return Pill.isPill(self.field.get(coordinates))

    def isPacman(self, coordinates):
        return isinstance(self.field.get(coordinates), Pacman)

    def eatPill(self, coordinates):
        pill = self.field.get(coordinates)
        self.pills.remove(pill)
        self.score += pill.score()
        for ghost in self.ghosts:
            ghost.triggerEffect(pill)
        if len(self.pills) == 0:
            self.nextLevel()

    def killGhost(self, ghost):
        self.score += ghost.score()
        ghost.kill()

    def killPacman(self):
        self.pacman.kill()
        self.lives -= 1
        if (self.lives == 0):
            self.gameOver = True

    def getPacman(self):
        return self.pacman

    def setController(self, controller):
        self.controller = controller

    def move(self, direction):
        self.pacman.move(direction)

    def setLevel(self, level):
        self.level = level

    def setMaxLevel(self, level):
        self.lastLevel = level

    def nextLevel(self):
        if self.level < self.lastLevel:
            self.level += 1
            self.pills = []
            self.walls = []
            self.ghosts = []
            self.parse()
        else:
            self.gameOver = True
            self.pacman.restart()

    def useAnimation(self):
        self.animation = True

    def getLives(self):
        return self.lives

    def getScore(self):
        return self.score

    def printGameOver(field):
        cols = field.width()
        rows = field.height()
        GAME = "GAME"
        OVER = "OVER"
        y = floor(rows / 2) - 2
        padding = floor(((cols - 2) - len(GAME)) / 2)
        for i in range(len(GAME)):
            x = padding + i + 1
            field.add((x, y), GAME[i])
            field.add((x, y + 1), OVER[i])
コード例 #2
0
class Game:
    size = None
    screen = None
    star_background = None
    game_field = None
    game_speed = 1
    game_thread = None
    player = None
    fps = 60
    running = True
    gameover = False
    waiting = True
    font = None
    padding = 20
    score = 0
    random_color = [255, 0, 0]
    milestone = 2000
    hit = 0
    highscore = 0
    fpsClock = pygame.time.Clock()

    def __init__(self, size):
        self.size = size
        pygame.font.init()
        self.score = 0
        self.star_background = Stars(self.size)
        self.font = pygame.font.Font("res/font.ttf", 28)
        self.screen = pygame.display.set_mode(size)
        if not self.gameover:
            self.new_game()
        self.loop()

    def new_game(self):
        self.running = True
        self.waiting = True
        self.gameover = False
        self.milestone = 100
        self.game_speed = 1
        self.lives = 4
        self.game_field = GameField(self.size)
        self.player = Player(
            [self.size[0] / 2 - Player.size[0] / 2, self.size[1] - 80],
            [255, 255, 255])

    def draw_score(self):
        fps = self.font.render("x" + str(round(self.game_speed, 2)), False,
                               (255, 255, 255))
        self.screen.blit(fps, (self.padding, self.padding))
        lives = self.font.render(
            str(self.lives) + " Lives", False, (255, 255, 255))
        self.screen.blit(
            lives,
            (self.size[0] - lives.get_width() - self.padding, self.padding))
        score = self.font.render(str(int(self.score)), False, (255, 255, 100))
        self.screen.blit(
            score, ((self.size[0] / 2) - score.get_width() / 2, self.padding))
        if self.waiting:
            start = self.font.render("Press any key to start", False,
                                     self.random_color)
            self.screen.blit(
                start,
                ((self.size[0] / 2) - start.get_width() / 2,
                 (self.size[1] - start.get_height()) - self.padding - 140))
        if self.gameover or self.waiting:
            highscore = self.font.render(
                "Highscore: " + str(int(self.highscore)), False,
                (255, 255, 255))
            self.screen.blit(highscore,
                             ((self.size[0] / 2) - highscore.get_width() / 2,
                              self.padding + self.size[1] / 2))

    def render_game(self):
        self.star_background.render(self.screen)
        self.game_field.render(self.screen)
        self.player.render(self.screen)
        self.draw_score()

    def update_score(self):
        if not self.gameover:
            self.score += self.game_speed * 0.1
        if self.score > self.highscore:
            self.highscore = self.score

    def game_over_animation(self):
        if self.game_speed > 0.5:
            self.game_speed -= 0.01
        if self.player.pos[1] < self.size[1]:
            self.player.pos[1] += 0.5
        else:
            new = True
            for obj in self.game_field.objects:
                if obj.pos[1] < self.size[1]:
                    new = False
            if new:
                self.new_game()

    def update_game(self):
        self.star_background.update(2 * self.game_speed)

        if self.score > self.milestone and not self.waiting:
            self.milestone += 250 * self.game_speed * self.game_speed
            print(self.milestone)
            self.game_speed += 0.5

        if not self.waiting:
            self.game_field.update(4 * self.game_speed, self.gameover)
            self.update_score()
            if self.lives <= 0:
                self.gameover = True

            if self.game_field.is_colliding(self.player):
                if not self.lives <= 0:
                    self.lives -= 1
                    self.hit = 10
            self.player.update(4 * self.game_speed, self.size[0])

    def event_handling(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
            if not self.waiting and not self.gameover:
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT:
                        self.player.move_left = True
                    if event.key == pygame.K_RIGHT:
                        self.player.move_right = True
                if event.type == pygame.KEYUP:
                    if event.key == pygame.K_LEFT:
                        self.player.move_left = False
                    if event.key == pygame.K_RIGHT:
                        self.player.move_right = False
            if self.waiting:
                if event.type == pygame.KEYDOWN:
                    self.score = 0
                    self.game_speed = 1
                    self.waiting = False

    def animation_handling(self):
        if self.gameover:
            self.game_over_animation()

        if self.hit > 0:
            self.hit -= 1

    def calc_colors(self):
        j = 0
        while j < len(self.random_color):
            self.random_color[j] += (j + 1) * 10
            if self.random_color[j] > 255:
                self.random_color[j] = 0
            j += 1

    def loop(self):
        while self.running:
            if self.hit == 0:
                self.screen.fill((0, 0, 0))
            else:
                self.screen.fill(self.random_color)

            self.animation_handling()
            self.calc_colors()
            self.event_handling()
            self.update_game()

            self.render_game()
            pygame.display.flip()
            self.fpsClock.tick(self.fps)
コード例 #3
0
ファイル: game.py プロジェクト: techcobweb/pacman-kata
class Game(object):
    def __init__(self, input_map=None):
        if input_map is not None:
            self.input_map = input_map.rstrip()
        self.field = None
        self.lives = 3
        self.score = 0
        self.pacman = None
        self.ghosts = []
        self.pills = []
        self.walls = []
        self.game_over = False
        self.controller = None
        self.display = None
        self.gate = None
        self.level = 1
        self.last_level = 1
        self.level_maps = None
        self.animation = False
        self.using_pills = False
        self.player = None
        self.scoreboard = None

    def init(self):
        self.parse()
        self.display.init(self)

    def play(self, debug):
        while True:
            self.tick()
            self.render()
            self.refresh()
            sleep(FRAME_RATE_IN_SECS)
            if (not self.pacman.alive):
                self.display.flash()
                self.pacman.restart()
            if self.game_over or debug:
                break
        self.post_score()

    def parse(self):
        self.set_game_input()
        columns = self.input_map.index("\n")
        self.parse_status(self.input_map[:columns])
        screen_rows = self.input_map[columns+1:].split('\n')
        rows = len(screen_rows)
        self.field = GameField(columns, rows)
        self.parse_field(screen_rows)

    def set_game_input(self):
        if self.level_maps:
            self.input_map = self.level_maps.get_level(self.level)
        else:
            if "SEPARATOR" in self.input_map:
                self.level_maps = LevelMaps(self.input_map)
                self.last_level = self.level_maps.max_level()
                self.input_map = self.level_maps.get_level(self.level)

    def parse_status(self, status_line):
        elements = status_line.split()
        try:
            self.lives = int(elements[0])
            self.score = int(elements[1])
        except ValueError:
            pass

    def parse_field(self, screen_rows):
        for y in range(self.field.height()):
            for x in range(self.field.width()):
                element = tokenizer.get_element((x, y), screen_rows[y][x])
                if (element):
                    element.add_to_game(self)

    def add_pill(self, pill):
        self.using_pills = True
        self.pills.append(pill)
        self.field.add(pill.coordinates, pill)

    def add_ghost(self, ghost):
        self.ghosts.append(ghost)
        self.field.add(ghost.coordinates, ghost)

    def set_field(self, width, height):
        self.field = GameField(width, height)

    def set_pacman(self, coordinates, direction):
        pacman = Pacman(coordinates)
        pacman.set_direction(direction)
        pacman.add_to_game(self)

    def add_pacman(self, pacman):
        self.pacman = pacman
        self.field.add(pacman.coordinates, pacman)

    def add_wall(self, coordinates, icon):
        wall = Wall(coordinates, icon)
        self.walls.append(wall)
        self.field.add(coordinates, wall)
        if Wall.is_gate(wall):
            self.gate = wall

    def tick(self):
        for ghost in self.ghosts:
            ghost.tick()
        if self.pacman:
            self.pacman.tick()
        if self.is_level_clear():
            self.next_level()
        self.update_field()

    def render(self):
        composite = Game.render_status(self.lives,
                                       self.score,
                                       self.field.width())
        self.output = composite["video"]
        self.colour = composite["colour"]
        self.output += "\n"
        self.colour.append(0)
        composite = self.field.render()
        self.output += composite["video"]
        self.colour.extend(composite["colour"])

    def render_status(lives, score, columns):
        colour = []
        video = "{lives:1d}".format(lives=lives)
        video += "{score:>{width}d}".format(score=score,
                                            width=columns - len(video))
        for i in range(len(video)):
            colour.append(0)
        return {"video": video, "colour": colour}

    def refresh(self):
        self.display.refresh(self.output, self.colour)

    def update_field(self):
        new_field = GameField(self.field.width(), self.field.height())
        for wall in self.walls:
            new_field.add(wall.coordinates, wall)
        for pill in self.pills:
            new_field.add(pill.coordinates, pill)
        for ghost in self.ghosts:
            new_field.add(ghost.coordinates, ghost)
        if self.pacman:
            new_field.add(self.pacman.coordinates, self.pacman)
        if self.game_over:
            Game.print_game_over(new_field)
        self.field = new_field

    def get_element(self, coords):
        return self.field.get(coords)

    def is_ghost(self, coordinates):
        return Ghost.is_ghost(self.field.get(coordinates))

    def is_wall(self, coordinates):
        return Wall.is_wall(self.field.get(coordinates))

    def is_gate(self, coordinates):
        return Wall.is_gate(self.field.get(coordinates))

    def is_field(self, coordinates):
        return Wall.is_field(self.field.get(coordinates))

    def is_pill(self, coordinates):
        return Pill.is_pill(self.field.get(coordinates))

    def is_pacman(self, coordinates):
        return isinstance(self.field.get(coordinates), Pacman)

    def eat_pill(self, coordinates):
        pill = self.field.get(coordinates)
        self.pills.remove(pill)
        self.score += pill.score()
        for ghost in self.ghosts:
            ghost.trigger_effect(pill)

    def kill_ghost(self, coordinates):
        ghost = self.field.get(coordinates)
        self.score += ghost.score()
        ghost.kill()

    def kill_pacman(self):
        self.pacman.kill()
        self.lives -= 1
        if (self.lives == 0):
            self.game_over = True

    def get_pacman(self):
        return self.pacman

    def set_controller(self, controller):
        self.controller = controller

    def set_display(self, display):
        self.display = display

    def move(self, direction):
        self.pacman.move(direction)

    def set_level(self, level):
        self.level = level

    def set_max_level(self, level):
        self.last_level = level

    def is_level_clear(self):
        return (len(self.pills) == 0) and self.using_pills

    def next_level(self):
        if self.level < self.last_level:
            self.level += 1
            self.pills[:] = []
            self.walls = []
            self.ghosts = []
            self.parse()
        else:
            self.game_over = True
            self.pacman.restart()

    def use_animation(self):
        self.animation = True

    def get_lives(self):
        return self.lives

    def get_score(self):
        return self.score

    def print_game_over(field):
        cols = field.width()
        rows = field.height()
        GAME = "GAME"
        OVER = "OVER"
        y = floor(rows / 2) - 2
        padding = floor(((cols - 2) - len(GAME)) / 2)
        for i in range(len(GAME)):
            x = padding + i + 1
            field.add((x, y), GAME[i])
            field.add((x, y+1), OVER[i])

    def set_player(self, player):
        self.player = player

    def post_score(self):
        if self.scoreboard is None:
            scoreboard_url = os.getenv("SCOREBOARD_URL")
            self.scoreboard = Scoreboard(scoreboard_url, self.player)
        self.scoreboard.post_score(self.score)

    def get_scores(self):
        response = self.scoreboard.scores()
        scores = []
        for score in response:
            name = score.player
            points = str(score.score)
            scores.append(name + ":" + points)
        return scores