Exemple #1
0
class Game:
    def __init__(self):
        self.__running = True
        self.screen = None
        self.player = Player(GridLoc(2, 2).to_pixel())
        self.world = World(self.player)
        self.all_sprites = None
        self.background = None
        self.clock = pygame.time.Clock()
        self.playtime = 0
        self.visual_sensors = None
        self.last_grid = GridLoc(-1, -1)
        self.input_map = {}
        self.input_debounce = self.bot_debounce = 0

    def setup(self):
        if settings.ai_mode:
            print('Running in AI mode. Move controls disabled')
        pygame.init()
        self.screen = pygame.display.set_mode(
            settings.size, pygame.HWACCEL | pygame.DOUBLEBUF)
        self.visual_sensors = [VisualSensors(self.player, *settings.size)]
        pygame.display.set_caption('James and Ashvin\'s Game \'AI\'')

        self.background = pygame.Surface(self.screen.get_size())
        self.background.fill((255, 155, 155))
        self.background = self.background.convert()

        if settings.dirty_rects:
            self.all_sprites = pygame.sprite.LayeredDirty(self.player)
            self.all_sprites.clear(self.screen, self.background)
        else:
            bot = Bot(GridLoc(3, 3).to_pixel(), self.world)
            self.bots = [bot]
            self.all_sprites = pygame.sprite.Group(*self.world.colliders,
                                                   *self.world.guns,
                                                   self.player, *self.bots)

        self.screen.blit(self.background, (0, 0))

    def draw_stats(self):
        font = pygame.font.Font('freesansbold.ttf', 16)
        actor = 'AI' if settings.ai_mode else 'Player'
        stat_str = '{}: {} (grid) | {} (pixels) | {} degrees (direction)'
        stats = stat_str.format(actor,
                                self.player.loc.to_grid(), self.player.loc,
                                round(self.player.direction, 2))
        text = font.render(stats, True, Colors.WHITE, Colors.BLACK)
        text_rect = text.get_rect()
        text_rect.center = (settings.width * 0.7, settings.height * 0.98)
        text_rect.width, text_rect.height = 750, 20
        self.screen.blit(text, text_rect)

    def redraw(self):
        if not settings.dirty_rects:
            self.screen.blit(self.background, (0, 0))
        wall_rects, old_wall_rects = self.world.draw(self.screen,
                                                     self.background)
        dirty_rects = self.all_sprites.draw(self.screen)

        if settings.visuals:
            for vs in self.visual_sensors:
                vs.draw(self.screen, self.world.draw_path, self.world.goal_loc,
                        self.world.collision_lines)
        if settings.stats:
            self.draw_stats()
        if settings.dirty_rects:
            pygame.display.update(dirty_rects + wall_rects + old_wall_rects)
        else:
            pygame.display.flip()

    def input(self, in_):
        if in_ in self.input_map:
            return self.input_map[in_]
        return False

    def check_inputs(self):
        if self.input_debounce > 0:
            self.input_debounce -= 1
        if self.input('mouse_down') and self.input(pygame.K_1):
            self.last_grid = self.world.create_wall(
                self.last_grid, self.input_map['wall_action'])
        if self.input('mouse_down'):
            self.player.shoot(self.world.colliders, self.world.grid.walls)
        if self.input('mouse_down') and self.input(pygame.K_2):
            x, y = pygame.mouse.get_pos()
            self.world.set_goal(x, y)
        if self.input(pygame.K_F1) and not self.input_debounce:
            settings.toggle('stats')
            self.input_debounce = 10
        if self.input(pygame.K_F2) and not self.input_debounce:
            settings.toggle('visuals')
            self.input_debounce = 10
        if self.input(pygame.K_F3) and not self.input_debounce:
            settings.toggle('ai_mode')
            if settings.ai_mode:
                settings.pathfinding = True
            self.world.toggle_ai()
            self.input_debounce = 10
        if self.input(pygame.K_F4) and not self.input_debounce:
            if not settings.ai_mode:
                settings.toggle('pathfinding')
                self.world.toggle_pathfinding()
            self.input_debounce = 10

    def check_event_queue(self):
        ins = self.input_map
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.__running = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.__running = False
                else:
                    ins[event.key] = True
            elif event.type == pygame.KEYUP:
                ins[event.key] = False
            elif event.type == pygame.MOUSEBUTTONDOWN:
                ins['mouse_down'] = True
                ins['wall_action'] = self.world.get_wall_action()
            elif event.type == pygame.MOUSEBUTTONUP:
                ins['mouse_down'] = False
                self.last_grid = GridLoc(-1, -1)

        self.check_inputs()

    def handle_keys(self, keys):
        if Keys.upright(keys):
            self.player.move(Actions.UR)
        elif Keys.downright(keys):
            self.player.move(Actions.DR)
        elif Keys.right(keys):
            self.player.move(Actions.R)
        elif Keys.upleft(keys):
            self.player.move(Actions.UL)
        elif Keys.downleft(keys):
            self.player.move(Actions.DL)
        elif Keys.left(keys):
            self.player.move(Actions.L)
        elif Keys.up(keys):
            self.player.move(Actions.U)
        elif Keys.down(keys):
            self.player.move(Actions.D)

    def mainloop(self):
        while self.__running:
            milliseconds = self.clock.tick(settings.FPS)
            self.playtime += milliseconds / 1000.0

            caption = 'James and Ashvin\'s Game \'AI\'  FPS: {}'.format(
                round(self.clock.get_fps(), 1))
            if settings.ai_mode:
                caption += ' | AI Mode'
            pygame.display.set_caption(caption)

            self.check_event_queue()
            if not settings.ai_mode:
                self.handle_keys(pygame.key.get_pressed())

            self.all_sprites.update()
            if settings.visuals:
                for vs in self.visual_sensors:
                    vs.update()
            self.world.update()
            self.redraw()

    def cleanup(self):
        self.background = self.screen = self.all_sprites = None
        Workers._pool.terminate()
        Workers._pool.join()
        pygame.quit()

    def run(self):
        self.setup()
        self.mainloop()
        self.cleanup()