Exemple #1
0
 def move_to_heard(self):
     dino_1 = Dinosaur('T-rex', 40)
     dino_2 = Dinosaur('Raptor', 25)
     dino_3 = Dinosaur('Pterodactyl', 35)
     self.dinos.append(dino_1)
     self.dinos.append(dino_2)
     self.dinos.append(dino_3)
Exemple #2
0
 def __init__(self):
     self.dinosaur = Dinosaur(win, 500 - 100, 450)
     self.bg_colour = win.fill((255, 255, 255))
     self.cactuses = [Cactus(win, 1000), Cactus(win, 1000)]
     self.bg = pygame.image.load("imgs/floor.png")
     self.timer = time.time()
     self.score = -1
Exemple #3
0
    def __init__(self):
        pygame.display.set_caption('Dinosaur Game')
        self.clock = pygame.time.Clock()
        self.height = 400
        self.width = 700
        self.screen_res = [self.width, self.height]
        self.screen = pygame.display.set_mode(self.screen_res,
                                              pygame.HWSURFACE, 32)
        self.white = [222, 222, 222]
        self.black = [0, 0, 0]
        self.screen.fill(self.white)
        self.font = pygame.font.SysFont("Calibri", 16)
        self.ground_y = 250
        self.end = False
        self.obj_speed = 2.5
        self.dinosaur = Dinosaur(self)
        self.cactus_group = pygame.sprite.Group()
        self.collide = False
        self.object_period = 5
        self.current_obj = None
        self.score = 0
        self.add_speed = 5
        self.current_cloud = None

        while not self.end:
            self.loop()
Exemple #4
0
    def __init__(self, screen):
        """ 初始化 """
        self._screen = screen  # 屏幕画面
        self._gameState = GameState.start  # 游戏状态 0:开始画面; 1:游戏中; 2:游戏结束
        self._frameCount = 0  # 每个游戏状态的帧数计数
        self._score = Score(self)  # 分数系统

        # 游戏元素
        self._startScene = StartScene()
        self._gameoverScene = GameoverScene(self)
        self._dinosaur = Dinosaur(self)
        self._cactusGroup = pygame.sprite.RenderPlain()
        self._birdGroup = pygame.sprite.RenderPlain()
        self._terrian = Terrian(self)
        self._cloudGroup = pygame.sprite.RenderPlain()
        self._moon = Moon(self)
        self._starGroup = pygame.sprite.RenderPlain()

        # 控制难度的变量
        self._lastEnemyFrameCount = 0  # 上一次出现敌人的帧数计数
        self._curEnemeyProbability = Settings.enemyInitProbability  # x,当前每帧敌人出现的概率为1/x
        self._curEnemyMinFrameInterval = Settings.enemyInitMinFrameInterval  # 当前敌人最小帧数间隔
        self._curTerrianSpeed = Settings.terrianInitSpeed  # 当前地形移动速度

        # 控制环境的变量
        self._lastCloudFrameCount = Settings.cloudFrameInterval  # 上一次出现云的帧数计数
        self._isDay = True  # 是否白天
        self._dayNightFrame = Settings.dayNightChangeFrame  # 自从白天/黑夜开始的帧数,初始值不为0,因为开始无需昼夜交替
Exemple #5
0
 def create_herd(self):
     Dinosaur_1 = Dinosaur()
     Dinosaur_2 = Dinosaur()
     Dinosaur_3 = Dinosaur()
     self.herd_of_robots.append(Dinosaur_1)
     self.herd_of_robots.append(Dinosaur_2)
     self.herd_of_robots.append(Dinosaur_3)
    def create_herd(self):
        dino1 = Dinosaur("Stegosaurus", 8)
        dino2 = Dinosaur("Raptor", 15)
        dino3 = Dinosaur("T-Rex", 50)

        self.dinosaurs.append(dino1)
        self.dinosaurs.append(dino2)
        self.dinosaurs.append(dino3)
Exemple #7
0
 def init_game(self):
     # 游戏结束
     self.over = False
     # 创建滚动地图对象
     self.bg = RollBackground()
     # 创建恐龙对象
     self.dinosaur = Dinosaur()
     # 创建障碍物组合
     self.obstacles = ObstacleGroup()
Exemple #8
0
 def create_herd(self):
     self.dinosaur_herd = []
     dino1 = Dinosaur("Rex", "T-Rex", 120, 75, 300)
     dino2 = Dinosaur("Tony", "Triceratops", 75, 50, 275)
     dino3 = Dinosaur("Ed", "Raptor", 100, 100, 200)
     self.dinosaur_herd.append(dino1)
     self.dinosaur_herd.append(dino2)
     self.dinosaur_herd.append(dino3)
     for dino in self.dinosaur_herd:
         print(dino.name + " the " + dino.dinosaur_type)
     print(self.dinosaur_herd)
     return self.dinosaur_herd
Exemple #9
0
 def reset_game(self):
     self.score = 0
     self.cont_enemies_x_level = 0
     self.over = False
     self.level = 0
     self.last_timestamp = time.time()
     self.enemies_list.empty()
     sprites_list_temp = pygame.sprite.Group()
     sprites_list_temp.add(enemy for enemy in self.sprites_list if enemy.__module__ != 'enemy' and enemy.__module__ != 'dinosaur')
     self.sprites_list = sprites_list_temp
     self.dino = Dinosaur()
     self.dino.walls = self.walls_list
     self.sprites_list.add(self.dino)
Exemple #10
0
    def __init__(self):
        """Initilize the game, and create game resources"""
        pygame.init()

        self.settings = Settings()

        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Snap Strats")
        self.dinosaur = Dinosaur(self)
        self.car = Car(self)
        self.dinosaurs = pygame.sprite.Group()

        self._create_fleet()
Exemple #11
0
    def _create_fleet(self):
        """Create the cars"""
        # Create an alien and find the number of aliens in a rrow.
        dinosaur = Dinosaur(self)
        dinosaur_height = dinosaur.rect.height
        available_space_y = self.settings.screen_height - (2 * dinosaur_height)
        number_dinosaurs_y = available_space_y // (2 * dinosaur_height)

        # Create the first row of dino saurs
        for dinosaur_number in range(number_dinosaurs_y):
            dinosaur = Dinosaur(self)
            dinosaur.y = dinosaur_height + 2 * dinosaur_height * dinosaur_number
            dinosaur.rect.y = dinosaur.y

            self.dinosaurs.add(dinosaur)
Exemple #12
0
def run_game():
    tick = 0
    while 1923014810498219048120948:
        if game_settings.game_active:
            game_func.check_events(screen, game_settings, squares, characters,
                                   bullets)
            # screen.fill(game_settings.bg_color);
            tick += 1
            if tick % 30 == 0 or tick == 1:
                dinosaurs.add(Dinosaur(screen, game_settings))

            dinosaur_got_shot = groupcollide(dinosaurs, bullets, False, False)
            character_got_hit = groupcollide(dinosaurs, characters, False,
                                             True)
            for dinosaur in dinosaur_got_shot:
                # print dinosaur;
                if dinosaur.yard_row == dinosaur_got_shot[dinosaur][
                        0].yard_row:
                    bullets.remove(dinosaur_got_shot[dinosaur][0])
                    dinosaur.hit(1)
                    if (dinosaur.health <= 0):
                        dinosaurs.remove(dinosaur)
                        # os.system("say ow")
                        game_settings.dinosaur_in_row[dinosaur.yard_row] -= 1

        game_func.update_screen(screen, game_settings, background, dinosaurs,
                                squares, characters, bullets, tick)
        pygame.display.flip()
Exemple #13
0
def run_game():
    pygame.init()
    dino_settings = Settings()
    screen = pygame.display.set_mode((dino_settings.screen_width, dino_settings.screen_height))
    pygame.display.set_caption("dino")
    score = float(0)
    while True:
        ground = Ground(dino_settings, screen)
        dinosaur = Dinosaur(dino_settings, screen)
        clouds = Group()
        birds = Group()
        cactus = Group()
        gf.create_clouds(dino_settings, screen, clouds)
        gf.create_birds(dino_settings, screen, birds)
        gf.create_cactus(dino_settings, screen, cactus)
        sb = Scoreboard(dino_settings, screen)
        while not dinosaur.dead:
            gf.check_events(dinosaur)
            ground.update()
            dinosaur.update()
            score += 3
            dino_settings.score = int(score)
            sb.prep_score()
            gf.update_clouds(dino_settings, screen, clouds)
            gf.update_birds(dino_settings, screen, birds, dinosaur)
            gf.update_cactus(dino_settings, screen, cactus, dinosaur)
            gf.update_screen(dino_settings, screen, ground, clouds, dinosaur, cactus, birds, sb)
        while dinosaur.dead:
            exit_game = False
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    mouse_x, mouse_y = pygame.mouse.get_pos()
                    if button.rect.collidepoint(mouse_x, mouse_y):
                        exit_game = True
            if exit_game:
                if dino_settings.score > dino_settings.high_score:
                    dino_settings.high_score = dino_settings.score
                    sb.prep_high_score()
                dino_settings.score = 0
                score = 0
                break
            
            button = Button(dino_settings, screen)
            button.blitme()
            pygame.display.flip()
Exemple #14
0
 def __init__(self):
     self.score = 0
     self.cont_enemies_x_level = 0
     self.level = 0
     self.over = False
     self.pause = False
     self.messages = []
     self.sprites_list = pygame.sprite.Group()
     self.walls_list = pygame.sprite.Group()
     self.enemies_list = pygame.sprite.Group()
     self.define_borders()
     self.grown = Grown()
     self.sprites_list.add(self.grown.objects_list)
     self.dino = Dinosaur()
     self.dino.walls = self.walls_list
     self.sprites_list.add(self.dino)
     self.last_timestamp = time.time()
     self.next_level_timestamp = time.time()
 def create_herd(self):
     i = 0
     while i < 3:
         print(f"If Dinosaur {i+1} is a T-Rex press 1:")
         print(f"If Dinosaur {i+1} is a Triceratops press 2:")
         print(f"If Dinosaur {i+1} is a Stegosaurus press 3:")
         selector = {"1": "T-Rex", "2": "Triceratops", "3": "Stegosaurus"}
         self.dinos.append(
             Dinosaur(selector[input()],
                      input(f"What is Dinosaur {i+1}'s Attack Power?")))
         i += 1
Exemple #16
0
 def create_herd_custom_amount(self, amount):
     self.dinosaurs = []
     i = 1
     while i <= amount:
         self.dinosaurs.append(
             Dinosaur(f'Dinosaur {i}', random.randint(15, 30)))
         if 20 < self.dinosaurs[i - 1].attack_power <= 25:
             self.dinosaurs[i - 1].energy_drain = -15
         elif self.dinosaurs[i - 1].attack_power > 25:
             self.dinosaurs[i - 1].energy_drain = -20
         i += 1
Exemple #17
0
def handler(event, context):
    """
    The function to create a new dinosaur and store it into DynamoDB
    """
    dinosaur_dict = event.get('dinosaur', None)
    if not dinosaur_dict:
        print('No dinosaur provided.')
        return
    if not all(keys in dinosaur_dict for keys in
               ['name', 'diet', 'period', 'weight', 'armor', 'hybrid']):
        print('Missing dinosaur values.')
        return

    # Get dinosaur information from event
    dino_name = dinosaur_dict.get('name')
    dino_diet = dinosaur_dict.get('diet')
    dino_period = dinosaur_dict.get('period')
    dino_weight = dinosaur_dict.get('weight')
    dino_armor = dinosaur_dict.get('armor')
    dino_hybrid = dinosaur_dict.get('hybrid')

    # Create new dinosaur object
    new_dinosaur = Dinosaur(name=dino_name,
                            diet=dino_diet,
                            period=dino_period,
                            weight=dino_weight,
                            armor=dino_armor,
                            hybrid=dino_hybrid)

    # Store new dinosaur object in DynamoDB
    print(new_dinosaur.__dict__)
    response = dinosaurs_table.put_item(
        Item={
            'name': new_dinosaur.name,
            'diet': new_dinosaur.diet,
            'period': new_dinosaur.period,
            'attack': new_dinosaur.attack,
            'defense': new_dinosaur.defense,
            'life': new_dinosaur.life,
            'info': {
                'weight': new_dinosaur.weight,
                'armor': new_dinosaur.armor,
                'nature': new_dinosaur.nature,
                'hybrid': new_dinosaur.hybrid
            }
        })

    print('PutItem succeeded:')
    print(json.dumps(response, indent=2))
Exemple #18
0
 def create_herd(self, team_size):
     dinosaur_list = ["T-Rex", "Raptor", "Triceratops"]
     dinosaurs = []
     # Loop to create robot fleet
     i = 0
     while i < team_size:
         x = random.randrange(0, 2)
         dino_type = dinosaur_list[x]
         dinosaur = Dinosaur(dino_type)
         dinosaurs.append(dinosaur)
         if dino_type == "T-Rex":
             dinosaur.health = random.randrange(80, 110, 10)
             dinosaur.attack_power = random.randrange(20, 30)
         elif dino_type == "Triceratops":
             dinosaur.health = random.randrange(50, 80, 5)
             dinosaur.attack_power = random.randrange(10, 20)
             dinosaur.energy = 100
         elif dino_type == "Raptor":
             dinosaur.health = random.randrange(30, 50, 5)
             dinosaur.attack_power = random.randrange(10, 15)
             dinosaur.energy = 200
         i += 1
     self.dinosaurs = dinosaurs
     pass
Exemple #19
0
class Game:

    def __init__(self):
        self.bump_audio = BUMP_AUDIO
        self.over_img = OVER_IMG
        self.init_game()

    def init_game(self):
        # 游戏结束
        self.over = False
        # 创建滚动地图对象
        self.bg = RollBackground()
        # 创建恐龙对象
        self.dinosaur = Dinosaur()
        # 创建障碍物组合
        self.obstacles = ObstacleGroup()

    def process_event(self):
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit(0)
            elif event.type == KEYDOWN and event.key == K_SPACE:
                if self.over:
                    self.init_game()
                else:
                    self.dinosaur.jump()

    def start(self):
        while True:
            self.process_event()

            if not self.over:
                self.update_window()
                if self.dinosaur.collide(self.obstacles):
                    self.over = True
                    self.game_over()
            self.dinosaur.show_score()

            pygame.display.update()
            set_fps(30)

    def update_window(self):
        self.bg.update()
        self.dinosaur.update()
        self.obstacles.update()

    def game_over(self):
        self.bump_audio.play()
        x = (SCREEN_WIDTH - self.over_img.get_width()) // 2
        y = (SCREEN_HEIGHT - self.over_img.get_height()) // 2
        SCREEN.blit(self.over_img, (x, y))
Exemple #20
0
class Herd:
    health = Dinosaur().health

    def __init__(self):
        dinosaur_1 = Dinosaur()
        dinosaur_1.type = 'Indominus-Rex'
        dinosaur_1.health = 100
        dinosaur_1.energy = 100
        dinosaur_1.attack_power = 10

        dinosaur_2 = Dinosaur()
        dinosaur_2.type = 'Triceratops'
        dinosaur_2.health = 100
        dinosaur_2.energy = 100
        dinosaur_2.attack_power = 15

        dinosaur_3 = Dinosaur()
        dinosaur_3.type = 'T-Rex'
        dinosaur_3.health = 150
        dinosaur_3.energy = 150
        dinosaur_3.attack_power = 25
Exemple #21
0
    def dino_turn(self):
        dino_index = random.randint(0, len(self.herd.dinosaurs) - 1)
        robot_index = random.randint(0, len(self.fleet.robots) - 1)

        current_dino = self.herd.dinosaurs[dino_index]
        current_robot = self.fleet.robots[robot_index]

        print("\n" + Dinosaur.attack(current_dino, current_robot))

        if current_robot.health <= 0:
            print(f'{current_robot.name} health now depleted! {current_robot.name} OUT!')
            self.fleet.robots.remove(current_robot)
        else:
            print(f'{current_robot.name} health now {current_robot.health}')

        if current_dino.energy <= 0:
            print(f'{current_dino.type} energy now depleted! {current_dino.type} OUT!')
            self.herd.dinosaurs.remove(current_dino)

        else:
            print(f'{current_dino.type} energy now {current_dino.energy}')
    def eval_genomes(self, genomes, config):
        # Terminate if the user closed the window
        if self.has_exit:
            exit()

        # Increment the generation number
        self.generation += 1
        self.number_of_dinosaurs = len(genomes)

        # Set up the list of genomes
        self.neural_nets = []
        self.dinosaurs = []
        self.genomes = []

        # Set up the genomes
        for _, genome in genomes:
            genome.fitness = 0  # Start with fitness level of 0
            self.neural_nets.append(neat.nn.FeedForwardNetwork.create(genome, config))
            self.dinosaurs.append(Dinosaur(self.dinosaur_run_animation, 65, 45, batch=self.main_batch))
            self.genomes.append(genome)
        
        # Run the game
        pyglet.app.run()
Exemple #23
0
 def creat_herd(self):
     dino1 = Dinosaur()
     dino1.health = 100
     dino1.energy = 100
     dino2 = Dinosaur()
     dino2.health = 100
     dino2.energy = 100
     dino3 = Dinosaur()
     dino3.health = 100
     dino3.energy = 100
     self.dinosaurs.append(dino1)
     self.dinosaurs.append(dino2)
     self.dinosaurs.append(dino3)
Exemple #24
0
class Game:
    BLACK = (0, 0, 0)

    def __init__(self):
        pygame.display.set_caption('Dinosaur Game')
        self.clock = pygame.time.Clock()
        self.height = 400
        self.width = 700
        self.screen_res = [self.width, self.height]
        self.screen = pygame.display.set_mode(self.screen_res,
                                              pygame.HWSURFACE, 32)
        self.white = [222, 222, 222]
        self.black = [0, 0, 0]
        self.screen.fill(self.white)
        self.font = pygame.font.SysFont("Calibri", 16)
        self.ground_y = 250
        self.end = False
        self.obj_speed = 2.5
        self.dinosaur = Dinosaur(self)
        self.cactus_group = pygame.sprite.Group()
        self.collide = False
        self.object_period = 5
        self.current_obj = None
        self.score = 0
        self.add_speed = 5
        self.current_cloud = None

        while not self.end:
            self.loop()

    def loop(self):
        self.event_loop()
        self.draw()
        pygame.display.update()
        self.clock.tick(60)

    def event_loop(self):
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()

    def draw(self):
        self.screen.fill(self.white)
        self.draw_line()
        self.draw_dinosaur()
        self.draw_objects()
        self.draw_cloud()
        self.print_score()

    def draw_line(self):
        pygame.draw.aaline(self.screen, self.black, (0, self.ground_y),
                           (self.width, self.ground_y))

    def print_score(self):
        font = pygame.font.SysFont(None, 30)
        text = font.render('Score: ' + str(self.score), True, self.BLACK)
        self.screen.blit(text, (0, 0))

    def draw_dinosaur(self):
        keys = pygame.key.get_pressed()
        if not self.dinosaur.is_jumping:
            if keys[pygame.K_SPACE]:
                self.dinosaur.is_jumping = True
                self.dinosaur.direction = 'up'

        if self.dinosaur.is_jumping:
            if self.dinosaur.direction == 'up':
                self.dinosaur.move_up()
                if self.dinosaur.check_reached_top():
                    self.dinosaur.direction = 'down'
                    self.dinosaur.set_speed_zero()
            if self.dinosaur.direction == 'down':
                self.dinosaur.move_down()
                if self.dinosaur.check_reached_down():
                    self.dinosaur.direction = 'up'
                    self.dinosaur.reset_speed()
                    self.dinosaur.is_jumping = False
        self.dinosaur.update()

    def create_object(self):
        self.update_object_speed()
        random_number = random.randrange(2)
        if random_number == 0:
            collide_object = Cactus(self)
        else:
            collide_object = Bird(self)
        return collide_object

    def init_objects(self):
        if self.current_obj:
            if self.current_obj.x < self.get_appear_position():
                self.current_obj = self.create_object()
                self.score += 1
        else:
            self.current_obj = self.create_object()

    def update_object_speed(self):
        if self.score % self.add_speed == 0:
            self.obj_speed += 0.3

    def draw_objects(self):
        self.init_objects()
        self.current_obj.check_collide()
        if self.collide:
            self.end = True
        else:
            self.current_obj.move()
        self.current_obj.update()

    def draw_cloud(self):
        if self.current_cloud is None:
            self.current_cloud = Cloud(self)
        else:
            if self.current_cloud.check_passed() and random.randint(1, 4) != 1:
                self.current_cloud = Cloud(self)
        self.current_cloud.update()

    @staticmethod
    def get_appear_position():
        return 2 * random.randrange(-5, 5)
Exemple #25
0
import pygame

from settings import Settings
from landscape import Landscape
from dinosaur import Dinosaur

pygame.init()
canvas = pygame.display.set_mode(Settings.screen_size)

landscape = Landscape(canvas)
dinosaur = Dinosaur(canvas, landscape)

clock = pygame.time.Clock()

done = False
while not done:
    canvas.fill((0, 0, 0))
    landscape.draw()
    dinosaur.draw()
    pygame.display.flip()
    landscape.update()
    clock.tick(10)
from dinosaur import Dinosaur

dinosaur_one = Dinosaur()
dinosaur_two = Dinosaur()
dinosaur_three = Dinosaur()

dinosaur_herd = [dinosaur_one, dinosaur_two, dinosaur_three]


class Herd:

    def dinosaur_herd_health(self):
        herd_health = dinosaur_one.dinosaur_health
        herd_health += dinosaur_two.dinosaur_health
        herd_health += dinosaur_three.dinosaur_health
        if herd_health == 0:
            print("all dinosaurs are dead, robots win!")
        elif herd_health != 0:
            print(herd_health)
Exemple #27
0
    def create_herd(self):
        dinosaur1 = Dinosaur()
        dinosaur1.type = 'raptor'
        dinosaur1.health = 20
        dinosaur1.energy = 10
        dinosaur1.attack_power = 5

        dinosaur2 = Dinosaur()
        dinosaur2.type = 'pterosaur'
        dinosaur2.health = 20
        dinosaur2.energy = 10
        dinosaur2.attack_power = 5

        dinosaur3 = Dinosaur()
        dinosaur3.type = 'triceratops'
        dinosaur3.health = 30
        dinosaur3.energy = 5
        dinosaur3.attack_power = 10

        dinos = [dinosaur1, dinosaur2, dinosaur3]
        return dinos
    def __init__(self, enable_neat=False, *args, **kwargs):
        # Inherit the pyglet window
        super().__init__(*args, **kwargs)

        # Save the configuration that determines if the NEAT algorithm is used
        self.enable_neat = enable_neat

        # Generate the font style
        pyglet.font.add_file('data/fonts/press_start_2p.ttf')
        pyglet.font.load("Press Start 2P")

        # Save and draw the FPS
        self.frame_rate = 1/60
        self.fps_display = FPSDisplay(self)
        self.fps_display.label.x = self.width - 10
        self.fps_display.label.y = 10
        self.fps_display.label.anchor_x = "right"
        self.fps_display.label.font_name = "Press Start 2P"
        self.fps_display.label.font_size = 20
        self.fps_display.label.color = (192, 192, 192, 192)

        # Set the FPS
        pyglet.clock.schedule_interval(self.update, self.frame_rate)

        # Control the horizontal velocity of the obstacles
        self.obstacle_velx = -600

        # Create batches
        self.bg_batch = pyglet.graphics.Batch()
        self.main_batch = pyglet.graphics.Batch()
        if self.enable_neat:
            self.neat_batch = pyglet.graphics.Batch()
        else:
            self.game_over_batch = pyglet.graphics.Batch()

        # Preload the images into memory and save them
        game_sprites = self.preload_image("sprites.png")
        self.terrain_img = game_sprites.get_region(2, 0, 2402, 27)
        self.dinosaur_run_animation = Animation.from_image_sequence(
            ImageGrid(
                game_sprites.get_region(1854, 33, 176, 95),
                1,
                2,
                item_width=88,
                item_height=96
            ),
            0.3,
            loop=True
        )
        self.dinosaur_duck_animation = Animation.from_image_sequence(
            ImageGrid(
                game_sprites.get_region(2203, 33, 240, 61),
                1,
                2,
                item_width=118,
                item_height=62
            ),
            0.3,
            loop=True
        )
        self.dinosaur_jump_img = game_sprites.get_region(1678, 33, 88, 95)
        self.dinosaur_collision_img = game_sprites.get_region(2030, 33, 88, 95)
        self.cacti_imgs = (
            game_sprites.get_region(446, 58, 34, 70),  # Small cacti 1
            game_sprites.get_region(480, 58, 68, 70),  # Small cacti 2
            game_sprites.get_region(548, 58, 102, 70), # Small cacti 3
            game_sprites.get_region(652, 32, 50, 98),  # Large cacti 1
            game_sprites.get_region(702, 32, 100, 98), # Large cacti 2
            game_sprites.get_region(802, 30, 150, 98), # Large cacti 3

        )
        self.bird_animation = Animation.from_image_sequence(
            ImageGrid(
                game_sprites.get_region(260, 48, 184, 80),
                1, 2, item_width=92, item_height=80
            ),
            0.3,
            loop=True
        )
        self.cloud_img = game_sprites.get_region(165, 100, 95, 28)
        self.moon_phases = cycle((
            game_sprites.get_region(1234, 47, 40, 82),
            game_sprites.get_region(1194, 47, 40, 82),
            game_sprites.get_region(1154, 47, 40, 82),
            game_sprites.get_region(1074, 47, 80, 82),
            game_sprites.get_region(1034, 47, 40, 82),
            game_sprites.get_region(994, 47, 40, 82),
            game_sprites.get_region(954, 47, 40, 82)
        ))
        self.reset_button_img = game_sprites.get_region(2, 63, 72, 65)

        # Score and label
        self.score = 0
        self.score_label = pyglet.text.Label(
            f"{self.score:05}",
            font_name="Press Start 2P",
            font_size=20,
            x=self.width - 10,
            y=self.height - 10,
            anchor_x="right",
            anchor_y="top",
            batch=self.bg_batch
        )

        # Game over label (only if the user plays the game manually)
        if not self.enable_neat:
            self.game_over_label = pyglet.text.Label(
                "G A M E  O V E R",
                font_name="Press Start 2P",
                font_size=30,
                x=self.width / 2,
                y=self.height / 2 + 100,
                anchor_x="center",
                anchor_y="center",
                batch=self.game_over_batch
            )
        
        # Initialize the sprites
        self.terrain_1 = GameSprite(
            self.terrain_img,
            0,
            50,
            velx=self.obstacle_velx,
            batch=self.bg_batch
        )
        self.terrain_2 = GameSprite(
            self.terrain_img,
            2400,
            50,
            velx=self.obstacle_velx,
            batch=self.bg_batch
        )
        self.moon = GameSprite(next(self.moon_phases), 2920, 275, velx=-20, batch=self.main_batch)
        self.clouds = [] # Elements will be randomly generated as the game progresses
        self.obstacles = [] # Elements will be randomly generated as the game progresses
        
        # Reset button is only available when the user plays manually
        if not self.enable_neat:
            self.reset_button = GameSprite(
                self.reset_button_img,
                564,
                150,
                batch=self.game_over_batch
            )
        
        # Generate the user's dinosaur if the user plays manually
        if not self.enable_neat:
            self.dinosaur = Dinosaur(self.dinosaur_run_animation, 65, 45, batch=self.main_batch)

            # Set variables to track user inputs
            self.trigger_duck = False
            self.trigger_jump = False

            # Keep track of any user collisions
            self.user_collision = False

        # Add a delays to control when events happen
        self.next_score_increment = 0.1
        self.next_cloud_spawn = 3 * random() + 1
        self.next_obstacle_spawn = 2 * random() + 1
        self.next_velocity_increase = 1

        # Set up the NEAT algorithm if true. Otherwise, let the user play manually
        if self.enable_neat:
            # Locate the NEAT configuration file
            config_file = os.path.join(os.path.dirname(__file__), 'config-feedforward.txt')

            # Configure the NEAT algorithm
            config = neat.config.Config(
                neat.DefaultGenome,
                neat.DefaultReproduction,
                neat.DefaultSpeciesSet,
                neat.DefaultStagnation,
                config_file
            )

            # Generate the population
            population = neat.Population(config)

            # Add a reporter to show progress in the terminal
            population.add_reporter(neat.StdOutReporter(True))
            population.add_reporter(neat.StatisticsReporter())

            # Generation label
            self.generation = -1
            self.generation_label = pyglet.text.Label(
                f"GENERATION: {self.generation:02}",
                font_name="Press Start 2P",
                font_size=20,
                x=10,
                y=self.height - 10,
                anchor_x="left",
                anchor_y="top",
                batch=self.neat_batch
            )

            # Number of dinosaurs label
            self.number_of_dinosaurs = 0
            self.number_of_dinosaurs_label = pyglet.text.Label(
                f"DINOSAURS: {self.number_of_dinosaurs:03}",
                font_name="Press Start 2P",
                font_size=20,
                x=10,
                y=self.height - 40,
                anchor_x="left",
                anchor_y="top",
                batch=self.neat_batch
            )
            # Run the NEAT algorithm and find the best "player"
            winner = population.run(self.eval_genomes, 25)
        else:
            # Run the main loop and play the game manually
            pyglet.app.run()
class ChromeDinosaurGame(pyglet.window.Window):
    def __init__(self, enable_neat=False, *args, **kwargs):
        # Inherit the pyglet window
        super().__init__(*args, **kwargs)

        # Save the configuration that determines if the NEAT algorithm is used
        self.enable_neat = enable_neat

        # Generate the font style
        pyglet.font.add_file('data/fonts/press_start_2p.ttf')
        pyglet.font.load("Press Start 2P")

        # Save and draw the FPS
        self.frame_rate = 1/60
        self.fps_display = FPSDisplay(self)
        self.fps_display.label.x = self.width - 10
        self.fps_display.label.y = 10
        self.fps_display.label.anchor_x = "right"
        self.fps_display.label.font_name = "Press Start 2P"
        self.fps_display.label.font_size = 20
        self.fps_display.label.color = (192, 192, 192, 192)

        # Set the FPS
        pyglet.clock.schedule_interval(self.update, self.frame_rate)

        # Control the horizontal velocity of the obstacles
        self.obstacle_velx = -600

        # Create batches
        self.bg_batch = pyglet.graphics.Batch()
        self.main_batch = pyglet.graphics.Batch()
        if self.enable_neat:
            self.neat_batch = pyglet.graphics.Batch()
        else:
            self.game_over_batch = pyglet.graphics.Batch()

        # Preload the images into memory and save them
        game_sprites = self.preload_image("sprites.png")
        self.terrain_img = game_sprites.get_region(2, 0, 2402, 27)
        self.dinosaur_run_animation = Animation.from_image_sequence(
            ImageGrid(
                game_sprites.get_region(1854, 33, 176, 95),
                1,
                2,
                item_width=88,
                item_height=96
            ),
            0.3,
            loop=True
        )
        self.dinosaur_duck_animation = Animation.from_image_sequence(
            ImageGrid(
                game_sprites.get_region(2203, 33, 240, 61),
                1,
                2,
                item_width=118,
                item_height=62
            ),
            0.3,
            loop=True
        )
        self.dinosaur_jump_img = game_sprites.get_region(1678, 33, 88, 95)
        self.dinosaur_collision_img = game_sprites.get_region(2030, 33, 88, 95)
        self.cacti_imgs = (
            game_sprites.get_region(446, 58, 34, 70),  # Small cacti 1
            game_sprites.get_region(480, 58, 68, 70),  # Small cacti 2
            game_sprites.get_region(548, 58, 102, 70), # Small cacti 3
            game_sprites.get_region(652, 32, 50, 98),  # Large cacti 1
            game_sprites.get_region(702, 32, 100, 98), # Large cacti 2
            game_sprites.get_region(802, 30, 150, 98), # Large cacti 3

        )
        self.bird_animation = Animation.from_image_sequence(
            ImageGrid(
                game_sprites.get_region(260, 48, 184, 80),
                1, 2, item_width=92, item_height=80
            ),
            0.3,
            loop=True
        )
        self.cloud_img = game_sprites.get_region(165, 100, 95, 28)
        self.moon_phases = cycle((
            game_sprites.get_region(1234, 47, 40, 82),
            game_sprites.get_region(1194, 47, 40, 82),
            game_sprites.get_region(1154, 47, 40, 82),
            game_sprites.get_region(1074, 47, 80, 82),
            game_sprites.get_region(1034, 47, 40, 82),
            game_sprites.get_region(994, 47, 40, 82),
            game_sprites.get_region(954, 47, 40, 82)
        ))
        self.reset_button_img = game_sprites.get_region(2, 63, 72, 65)

        # Score and label
        self.score = 0
        self.score_label = pyglet.text.Label(
            f"{self.score:05}",
            font_name="Press Start 2P",
            font_size=20,
            x=self.width - 10,
            y=self.height - 10,
            anchor_x="right",
            anchor_y="top",
            batch=self.bg_batch
        )

        # Game over label (only if the user plays the game manually)
        if not self.enable_neat:
            self.game_over_label = pyglet.text.Label(
                "G A M E  O V E R",
                font_name="Press Start 2P",
                font_size=30,
                x=self.width / 2,
                y=self.height / 2 + 100,
                anchor_x="center",
                anchor_y="center",
                batch=self.game_over_batch
            )
        
        # Initialize the sprites
        self.terrain_1 = GameSprite(
            self.terrain_img,
            0,
            50,
            velx=self.obstacle_velx,
            batch=self.bg_batch
        )
        self.terrain_2 = GameSprite(
            self.terrain_img,
            2400,
            50,
            velx=self.obstacle_velx,
            batch=self.bg_batch
        )
        self.moon = GameSprite(next(self.moon_phases), 2920, 275, velx=-20, batch=self.main_batch)
        self.clouds = [] # Elements will be randomly generated as the game progresses
        self.obstacles = [] # Elements will be randomly generated as the game progresses
        
        # Reset button is only available when the user plays manually
        if not self.enable_neat:
            self.reset_button = GameSprite(
                self.reset_button_img,
                564,
                150,
                batch=self.game_over_batch
            )
        
        # Generate the user's dinosaur if the user plays manually
        if not self.enable_neat:
            self.dinosaur = Dinosaur(self.dinosaur_run_animation, 65, 45, batch=self.main_batch)

            # Set variables to track user inputs
            self.trigger_duck = False
            self.trigger_jump = False

            # Keep track of any user collisions
            self.user_collision = False

        # Add a delays to control when events happen
        self.next_score_increment = 0.1
        self.next_cloud_spawn = 3 * random() + 1
        self.next_obstacle_spawn = 2 * random() + 1
        self.next_velocity_increase = 1

        # Set up the NEAT algorithm if true. Otherwise, let the user play manually
        if self.enable_neat:
            # Locate the NEAT configuration file
            config_file = os.path.join(os.path.dirname(__file__), 'config-feedforward.txt')

            # Configure the NEAT algorithm
            config = neat.config.Config(
                neat.DefaultGenome,
                neat.DefaultReproduction,
                neat.DefaultSpeciesSet,
                neat.DefaultStagnation,
                config_file
            )

            # Generate the population
            population = neat.Population(config)

            # Add a reporter to show progress in the terminal
            population.add_reporter(neat.StdOutReporter(True))
            population.add_reporter(neat.StatisticsReporter())

            # Generation label
            self.generation = -1
            self.generation_label = pyglet.text.Label(
                f"GENERATION: {self.generation:02}",
                font_name="Press Start 2P",
                font_size=20,
                x=10,
                y=self.height - 10,
                anchor_x="left",
                anchor_y="top",
                batch=self.neat_batch
            )

            # Number of dinosaurs label
            self.number_of_dinosaurs = 0
            self.number_of_dinosaurs_label = pyglet.text.Label(
                f"DINOSAURS: {self.number_of_dinosaurs:03}",
                font_name="Press Start 2P",
                font_size=20,
                x=10,
                y=self.height - 40,
                anchor_x="left",
                anchor_y="top",
                batch=self.neat_batch
            )
            # Run the NEAT algorithm and find the best "player"
            winner = population.run(self.eval_genomes, 25)
        else:
            # Run the main loop and play the game manually
            pyglet.app.run()


    # Load and save the image into memory
    def preload_image(self, image):
        return pyglet.image.load(f"data/images/{image}")
    

    # Handle the events when a key is pressed
    def on_key_press(self, symbol, modifiers):
        # Terminate the game if the ESC is pressed
        if symbol == key.ESCAPE:
            self.has_exit = True
            pyglet.app.exit()
        
        # Disable if the NEAT algorithm is being used
        if not self.enable_neat:
            # Check if the user triggers a duck or jump (duck is a priority over jump)
            if symbol in (key.DOWN, key.S):
                self.trigger_duck = True
            elif symbol in (key.SPACE, key.UP, key.W):
                self.trigger_jump = True

            # Accept the ENTER key only if the game is over
            if self.user_collision and symbol == key.ENTER:
                self.reset()

    
    # Handle the events when a key is pressed
    def on_key_release(self, symbol, modifiers):
        # Disable if the NEAT algorithm is being used
        if not self.enable_neat:
            # Check if the user released a key that triggers a duck
            if symbol in (key.DOWN, key.S):
                self.trigger_duck = False
            
            # Check if the user released a key that triggers a jump
            if symbol in (key.SPACE, key.UP, key.W):
                self.trigger_jump = False

    
    # Handle the events when the mouse is pressed
    def on_mouse_press(self, x, y, button, modifiers):
        # Disable if the NEAT algorithm is being used
        if not self.enable_neat:
            if (self.user_collision 
            and button == mouse.LEFT
            and self.reset_button.x <= x <= self.reset_button.x + self.reset_button.width 
            and self.reset_button.y <= y <= self.reset_button.y + self.reset_button.height):
                self.reset()


    # Draw the contents on the screen
    def on_draw(self):
        self.clear()
        self.bg_batch.draw() # Draw the background first
        self.main_batch.draw() # Draw the dinosaur and the obstacles next
        self.fps_display.draw()

        # Draw the NEAT batch if used. Otherwise, draw the game over batch if a collision occurs
        if self.enable_neat:
            self.neat_batch.draw()
        else:
            # Draw the game over label if a collision has been detected 
            if self.user_collision:
                self.game_over_batch.draw()
    

    # Check if the sprites collide
    def collide(self, sprite_1, sprite_2): 
        # If one sprite is on left side of other, then no collision is possible
        if sprite_1.x + sprite_1.width <= sprite_2.x or sprite_2.x + sprite_2.width <= sprite_1.x: 
            return False
        
        # If one sprite is above other, then no collision is possible 
        if sprite_1.y + sprite_1.height <= sprite_2.y or sprite_2.y + sprite_2.height <= sprite_1.y: 
            return False
        
        # The only other outcome is that they overlap
        return True


    # Update the dinosaur
    def update_dinosaur(self, dinosaur, dt, output=None):
        # Check if the dinosaur is jumping first
        if dinosaur.jumping:
            # Dinosaur is in the air. Check if it has landed
            if dinosaur.y <= 45 and dinosaur.vely <= 0:
                # Dinosaur hits the ground after jumping
                dinosaur.change_image(self.dinosaur_run_animation)
                dinosaur.land()
            else:
                # Decrement the dinosaur's vertical velocity
                dinosaur.vely -= 75
        
        # If NEAT is used, let it make the next move. Otherwise, let the user do so
        if self.enable_neat:
            # If an output is provided, let it make the next move
            if output:
                # Determine if the dinosaur should duck or jump
                if output[0] > 0.5 and not dinosaur.jumping and not dinosaur.ducking:
                    # Start ducking animation
                    dinosaur.change_image(self.dinosaur_duck_animation)
                    dinosaur.duck()
                if output[0] <= 0.5 and not dinosaur.jumping and dinosaur.ducking:
                    # End duck animation
                    dinosaur.change_image(self.dinosaur_run_animation)
                    dinosaur.rise()
                elif output[1] > 0.5 and not dinosaur.jumping and not dinosaur.ducking:
                    # Start jumping animation
                    dinosaur.change_image(self.dinosaur_jump_img)
                    dinosaur.jump()
        else:
            # Make the dinosaur duck or jump, depending on the key pressed
            if self.trigger_duck and not dinosaur.jumping and not dinosaur.ducking:
                # Start duck animation
                dinosaur.change_image(self.dinosaur_duck_animation)
                dinosaur.duck()
            elif not self.trigger_duck and not dinosaur.jumping and dinosaur.ducking:
                # End duck animation
                dinosaur.change_image(self.dinosaur_run_animation)
                dinosaur.rise()
            elif self.trigger_jump and not self.trigger_duck:
                # Start jump animation
                dinosaur.change_image(self.dinosaur_jump_img)
                dinosaur.jump()

        # Update the dinosaur's position
        dinosaur.update(dt)
    

    # Update the objects
    def update(self, dt):
        # Handle the collisions
        for obstacle in self.obstacles:
            if self.enable_neat:
                # Check each dinosaur for collisions
                for dinosaur, neural_net, genome in zip(self.dinosaurs, self.neural_nets, self.genomes):
                    if self.collide(dinosaur, obstacle):
                        # Remove any animations so that the sprite is properly removed
                        dinosaur.change_image(self.dinosaur_jump_img)

                        # Penalize the genome for the collision
                        genome.fitness -= 100
                        
                        # Eliminate the dinosaur genome
                        self.dinosaurs.remove(dinosaur)
                        self.neural_nets.remove(neural_net)
                        self.genomes.remove(genome)
                        
                        # Decrement the number of dinosaurs left and check if any remain
                        self.number_of_dinosaurs -= 1
                        if not self.dinosaurs:
                            self.reset()
                            pyglet.app.exit()
            else:
                # Check if the user collided with any obstacles
                if self.collide(self.dinosaur, obstacle):
                    self.user_collision = True
                    self.dinosaur.change_image(self.dinosaur_collision_img)
                    
                    # Prevent any further updates if a collision has been detected
                    return
        
        # Update the terrain sprites and check if any of them need to be moved
        if self.terrain_1.x + self.terrain_1.width < 0: # Off the screen
            self.terrain_1.x = self.terrain_2.x + self.terrain_2.width
        elif self.terrain_2.x + self.terrain_2.width < 0: # Off the screen
            self.terrain_2.x = self.terrain_1.x + self.terrain_1.width
        self.terrain_1.update(dt)
        self.terrain_2.update(dt)

        # Update the clouds and delete those that run off the left side of the screen
        for cloud in self.clouds:
            if cloud.x + cloud.width < 0:
                self.clouds.remove(cloud)
            else:
                cloud.update(dt)

        # Update the moon and move the moon if needed
        if self.moon.x + 80 < 0:
            self.moon.x += 3000
            self.moon.change_image(next(self.moon_phases))
        self.moon.update(dt)

        # Update the dinosaur(s)
        if self.enable_neat:
            for dinosaur, neural_net, genome in zip(self.dinosaurs, self.neural_nets, self.genomes):
                # Reward the genome with points for surviving
                genome.fitness += dt

                # Get the first obstacle if it exists and let the network make a decision
                output = neural_net.activate((
                    dinosaur.y, # Dinosaur's y-coordinate
                    self.obstacles[0].y, # Obstacle's y-coordinate
                    self.obstacles[0].width, # Width of the obstacle
                    self.obstacles[0].height, # Height of the obstacle
                    abs(dinosaur.x + dinosaur.width - self.obstacles[0].x), # Distance
                    self.obstacle_velx # Game speed
                )) if self.obstacles else None
                
                # Update the dinosaur and have the neural network determine its next move
                self.update_dinosaur(dinosaur, dt, output=output)
        else:
            self.update_dinosaur(self.dinosaur, dt)

        # Update the obstacles and delete those that run off the left side of the screen
        for obstacle in self.obstacles:
            if obstacle.x + obstacle.width < 0:
                self.obstacles.remove(obstacle)
            else:
                obstacle.update(dt)

        # Increment the score if scheduled to do so
        self.next_score_increment -= dt
        if self.next_score_increment <= 0:
            self.score += 1
            self.score_label.text = f"{self.score:05}"
            self.next_score_increment += 0.1 # Reset delay
        
        # Update the cloud spawn delay
        self.next_cloud_spawn -= dt
        if self.next_cloud_spawn <= 0:
            self.clouds.append(
                GameSprite(self.cloud_img, 1200, randint(225, 325), velx=-150, batch=self.bg_batch)
            )
            ''' 
            The 2 ensures that the cloud spawns at least 2 seconds later
            The random() function gives us a decimal number between 0 and 1 
            so by multiplying it by 3 and adding 2 to it
            we get a random decimal number between 3 and 5
            The idea was to have the clouds generate randomly and within an interval of time
            '''
            self.next_cloud_spawn += 3 * random() + 2 # Reset delay
        
        # Update the obstacle spawn delay
        self.next_obstacle_spawn -= dt
        if self.next_obstacle_spawn <= 0:
            object_type = randint(1, 6)
            if object_type == 6: # Spawn bird
                self.obstacles.append(
                    GameSprite(
                        self.bird_animation,
                        1200,
                        choice((50, 125, 200)),
                        velx=self.obstacle_velx - 100,
                        batch=self.main_batch
                    )
                )
            else: # Spawn cacti
                self.obstacles.append(
                    GameSprite(
                        choice(self.cacti_imgs),
                        1200,
                        45,
                        velx=self.obstacle_velx,
                        batch=self.main_batch
                    )
                )
            self.next_obstacle_spawn = 1.5 * random() + 1 # Reset delay

        # Update the velocity increase delay
        self.next_velocity_increase -= dt
        if self.next_velocity_increase <= 0:
            # Increment to change the velocity by
            increment = -5

            # Increase the velocity of the terrain and the obstacles
            self.terrain_1.velx += increment
            self.terrain_2.velx += increment

            for obstacle in self.obstacles:
                obstacle.velx += increment
            
            self.obstacle_velx += increment # Change the obstacle velocity
            self.next_velocity_increase += 1 # Reset delay

        # Update the generation and number of dinosaurs labels if the NEAT algorithm is used
        if self.enable_neat:
            self.generation_label.text = f"GENERATION: {self.generation:02}"
            self.number_of_dinosaurs_label.text = f"DINOSAURS: {self.number_of_dinosaurs:03}"
    

    # Reset the game
    def reset(self):
        # To remove the bird animations, all sprites are changed to static images
        for obstacle in self.obstacles:
            obstacle.change_image(self.cacti_imgs[0])
        
        # Clear the list of obstacles
        self.obstacles.clear()

        # Reset the dinosaur(s)
        if self.enable_neat:
            for dinosaur in self.dinosaurs:
                dinosaur.change_image(self.dinosaur_run_animation)
        else:
            self.dinosaur.change_image(self.dinosaur_run_animation)
            self.dinosaur.y = 45
            self.jumping = False
            self.ducking = False

        # Reset the score
        self.score = 0

        # Reset the velocities (obstacles are deleted, so we don't need to worry about them)
        self.obstacle_velx = -600
        self.terrain_1.velx = self.obstacle_velx
        self.terrain_2.velx = self.obstacle_velx

        # Reset the collision boolean so the game can start
        self.user_collision = False

    
    # Run the game with the NEAT algorithm
    def eval_genomes(self, genomes, config):
        # Terminate if the user closed the window
        if self.has_exit:
            exit()

        # Increment the generation number
        self.generation += 1
        self.number_of_dinosaurs = len(genomes)

        # Set up the list of genomes
        self.neural_nets = []
        self.dinosaurs = []
        self.genomes = []

        # Set up the genomes
        for _, genome in genomes:
            genome.fitness = 0  # Start with fitness level of 0
            self.neural_nets.append(neat.nn.FeedForwardNetwork.create(genome, config))
            self.dinosaurs.append(Dinosaur(self.dinosaur_run_animation, 65, 45, batch=self.main_batch))
            self.genomes.append(genome)
        
        # Run the game
        pyglet.app.run()
Exemple #30
0
class Game(object):

    def __init__(self):
        self.score = 0
        self.cont_enemies_x_level = 0
        self.level = 0
        self.over = False
        self.pause = False
        self.messages = []
        self.sprites_list = pygame.sprite.Group()
        self.walls_list = pygame.sprite.Group()
        self.enemies_list = pygame.sprite.Group()
        self.define_borders()
        self.grown = Grown()
        self.sprites_list.add(self.grown.objects_list)
        self.dino = Dinosaur()
        self.dino.walls = self.walls_list
        self.sprites_list.add(self.dino)
        self.last_timestamp = time.time()
        self.next_level_timestamp = time.time()

    def define_borders(self):
        # BORDER LEFT
        wall = Wall(0, 0, 2, SCREEN_Y_GAME)
        self.walls_list.add(wall)
        self.sprites_list.add(wall)

        # BORDER TOP
        wall = Wall(2, 0, SCREEN_X_GAME, 2)
        self.walls_list.add(wall)
        self.sprites_list.add(wall)

        # BORDER RIGHT
        wall = Wall(SCREEN_X_GAME, 0, 2, SCREEN_Y_GAME)
        self.walls_list.add(wall)
        self.sprites_list.add(wall)

        # BORDER BOTTOM
        wall = Wall(0, SCREEN_Y_GAME - 2, SCREEN_X_GAME, 2)
        self.walls_list.add(wall)
        self.sprites_list.add(wall)

    def event_handler(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return True

            if event.type == pygame.KEYDOWN:
                if self.over:
                    self.reset_game()
                if event.key == pygame.K_p:
                    self.pause = not self.pause
                if not self.pause:
                    if event.key == pygame.K_UP:
                        self.dino.jump()
                    if event.key == pygame.K_DOWN:
                        self.dino.stand_down()

            if event.type == pygame.KEYUP:
                if not self.pause:
                    if event.key == pygame.K_DOWN:
                        self.dino.stand_up()

        return False

    def run(self):
        if not self.over:
            self.sprites_list.update()
            self.check_level()
            if self.pause:
                self.scroll_scene(0)
            else:
                self.scroll_scene(SPEED[self.level])
                self.increment_score()
                self.calculate_next_enemy()
                self.check_dino_impacted()

    def pause_game(self, screen):
        font = pygame.font.SysFont("serif", 25)
        text = font.render("Pause", True, BLACK)
        center_x = (SCREEN_X_GAME // 2) - (text.get_width() // 2)
        center_y = (SCREEN_Y_GAME // 2) - (text.get_height() // 2)
        screen.blit(text, [center_x, center_y])

        self.last_timestamp = time.time()

    def reset_game(self):
        self.score = 0
        self.cont_enemies_x_level = 0
        self.over = False
        self.level = 0
        self.last_timestamp = time.time()
        self.enemies_list.empty()
        sprites_list_temp = pygame.sprite.Group()
        sprites_list_temp.add(enemy for enemy in self.sprites_list if enemy.__module__ != 'enemy' and enemy.__module__ != 'dinosaur')
        self.sprites_list = sprites_list_temp
        self.dino = Dinosaur()
        self.dino.walls = self.walls_list
        self.sprites_list.add(self.dino)

    def check_level_old(self):
        """ deprecated. Not used """
        next_level = int((self.score // SCORE_X_LEVEL))
        self.level = next_level if next_level <= len(SPEED) - 1 else len(SPEED) - 1

    def check_level(self):
        if self.cont_enemies_x_level > ENEMIES_X_LEVEL[self.level]:
            next_level = self.level + 1
            if next_level <= len(SPEED) - 1:
                self.level = next_level
                self.cont_enemies_x_level = 0
                self.next_level_timestamp = time.time()

    def check_dino_impacted(self):
        if self.dino.impacted:
            self.over = True

    def log(self, message):
        """ Only for development propose """
        self.messages.append(message)

    def increment_score(self):
        tot_enemies = len(self.enemies_list)
        tmp_enemies_list = pygame.sprite.Group()
        tmp_enemies_list.add(enemy for enemy in self.enemies_list if not enemy.removable)
        num_enemies = len(tmp_enemies_list)
        self.enemies_list = tmp_enemies_list
        self.score += (tot_enemies - num_enemies)
        self.cont_enemies_x_level += (tot_enemies - num_enemies)

    def add_enemy_to_lists(self, enemy):
        self.enemies_list.add(enemy)
        self.sprites_list.add(enemy)
        self.dino.enemies_list.add(enemy)
        self.grown.objects_list.add(enemy)

    def calculate_next_enemy(self):
        wait = random.uniform(RANGE_TIME_NEXT_ENEMY[self.level][0], RANGE_TIME_NEXT_ENEMY[self.level][1])
        if time.time() - self.last_timestamp > wait:
            self.last_timestamp = time.time()
            result = random.choices(range(len(TYPE_ENEMY)), WEIGHTS_ENEMY[self.level])
            self.create_enemy(TYPE_ENEMY[result[0]])

    def create_enemy(self, enemy_type):
        self.add_enemy_to_lists(Enemy(enemy_type['x'], enemy_type['y'], enemy_type['w'], enemy_type['h']))

    def scroll_scene(self, scroll_x):
        for element in self.grown.objects_list:
            element.scroll_x = scroll_x

    def display_frame(self, screen):
        screen.fill(WHITE)
        self.display_score(screen)
        self.display_log(screen)
        self.display_level(screen)

        if self.over:
            self.display_game_over(screen)

        if self.pause:
            self.pause_game(screen)

        self.sprites_list.draw(screen)
        pygame.display.flip()

    def display_game_over(self, screen):
        font = pygame.font.SysFont("serif", 25)
        text = font.render("Game Over", True, BLACK)
        center_x = (SCREEN_X_GAME // 2) - (text.get_width() // 2)
        center_y = (SCREEN_Y_GAME // 2) - (text.get_height() // 2)
        screen.blit(text, [center_x, center_y])

    def display_score(self, screen):
        font = pygame.font.SysFont("serif", 25)
        text = font.render("Score: " + str(int(self.score)), True, BLACK)
        x = SCREEN_X_GAME - text.get_width() - 20
        screen.blit(text, [x, 10])

    def display_changes(self, screen):
        """ Only for development purpose """
        font = pygame.font.SysFont("serif", 25)
        text1 = font.render("Change X: " + str(self.dino.change_x), True, BLACK)
        x = 10
        screen.blit(text1, [x, 10])
        text2 = font.render("Change Y: " + str(self.dino.change_y), True, BLACK)
        x = text1.get_width() + 20
        screen.blit(text2, [x, 10])

    def display_cords(self, screen):
        """ Only for development purpose """
        font = pygame.font.SysFont("serif", 25)
        text1 = font.render("RECT X: " + str(self.dino.rect.x), True, BLACK)
        x = 10
        screen.blit(text1, [x, 40])
        text2 = font.render("RECT Y: " + str(self.dino.rect.y), True, BLACK)
        x = text1.get_width() + 20
        screen.blit(text2, [x, 40])

    def display_level(self, screen):
        if time.time() - self.next_level_timestamp < 0.5 or (time.time() - self.next_level_timestamp > 1 and time.time() - self.next_level_timestamp < 1.5):
            color = WHITE
        else:
            color = BLACK
        font = pygame.font.SysFont("serif", 25)
        txt_level = font.render("Level: ", True, BLACK)
        num_level = font.render(str(self.level + 1), True, color)
        screen.blit(txt_level, [20, 10])
        screen.blit(num_level, [20 + txt_level.get_width(), 10])

    def display_log(self, screen):
        font = pygame.font.SysFont("serif", 10)
        y = 0
        for message in reversed(self.messages):
            text = font.render(message, True, BLACK)
            x = SCREEN_X_GAME + 10
            screen.blit(text, [x, y])
            y += 12