Ejemplo n.º 1
0
class GameWindow(pyglet.window.Window):
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.set_location(100, 100)
        self.frame_rate = 1/60.0
        self.fps_display = FPSDisplay(self)
        self.fps_display.label.font_size = 24
        
        # Hier wird der Pfad zum Verzeichnis des ».py«-Files gesetzt
        # Erspart einem das Herumgehample in TextMate mit dem os.getcwd()
        # und os.path.join()
        file_path = os.path.dirname(os.path.abspath(__file__))
        os.chdir(file_path)
        
        self.space_list = []
        self.space_img = preload_image("farback.gif")
        for i in range(2):
            self.space_list.append(GameObject(i*1782, 0, Sprite(self.space_img)))
        
        for space in self.space_list:
            space.velx = SPACESPEED
        
        player_spr = Sprite(preload_image_animation("Spritesheet_64x29.png", 4, 1, 64, 29))
        self.player = GameObject(50, 300, player_spr)
    
    def on_key_press(self, symbol, modifiers):
        if symbol == key.UP:
            self.player.vely = PLAYERSPEED
        if symbol == key.DOWN:
            self.player.vely = -PLAYERSPEED
    
    def on_key_release(self, symbol, modifiers):
        if symbol in (key.UP, key.DOWN):
            self.player.vely = 0
    
    def on_draw(self):
        self.clear()
        for space in self.space_list:
            space.draw()
        self.player.draw()
        
        self.fps_display.draw()
    
    def update_space(self, dt):
        for space in self.space_list:
            space.update(dt)
            if space.posx <= -1882:
                self.space_list.remove(space)
                self.space_list.append(GameObject(1682, 0, Sprite(self.space_img)))
            space.velx = SPACESPEED
    
    def update(self, dt):
        self.player.update(dt)
        self.update_space(dt)
Ejemplo n.º 2
0
class GameWindow(pyglet.window.Window):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.set_location(1000, 50)
        self.fps_draw = FPSDisplay(self)
        self.fps_draw.label.font_size = 50
        self.fps_draw.label.y = 800 - 50 - 10

        self.frame_rate = 1/60.0

    def load_data(self):
        player_sprite = Sprite(preload_img("PlayerShip.png"))
        space_sprite = preload_img("space.jpg")

        self.player = GameObject(500, 100, player_sprite)

        self.space_list = []
        for i in range(2):
            self.space_list.append(GameObject(0, i * 1200, Sprite(space_sprite)))

            self.space_list[i].vely = -600

    def on_key_press(self, symbol, modifiers):
        if symbol == key.RIGHT:
            self.player.velx = 300

        if symbol == key.LEFT:
            self.player.velx = -300

    def on_key_release(self, symbol, modifiers):
        if symbol in (key.RIGHT, key.LEFT):
            self.player.velx = 0

    def on_draw(self):
        self.clear()

        for space in self.space_list:
            space.draw()

        self.player.draw()

        self.fps_draw.draw()

    def update_space(self, dt):
        for space in self.space_list:
            space.update(dt)
            if space.posy <= -1300:
                space.posy = 1000

    def update(self, dt):
        self.update_space(dt)

        self.player.update(dt)
Ejemplo n.º 3
0
class GameWindow(pyglet.window.Window):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.set_location(300, 50)
        self.fps = FPSDisplay(self)

        self.space = pymunk.Space()
        self.options = DrawOptions()

        self.player = Player(self.space)
        self.ball = Ball(self.space, self.player.position)
        self.walls = Walls(self.space)
        self.bricks = Bricks(self.space)

    def on_draw(self):
        self.clear()
        self.space.debug_draw(self.options)
        self.fps.draw()

    def on_key_press(self, symbol, modifiers):
        if symbol == key.RIGHT:
            self.player.velocity = 600, 0
            if self.ball.on_paddle:
                self.ball.velocity = self.player.velocity
        if symbol == key.LEFT:
            self.player.velocity = -600, 0
            if self.ball.on_paddle:
                self.ball.velocity = self.player.velocity
        if symbol == key.SPACE:
            if self.ball.on_paddle:
                self.ball.shoot()
        if symbol == key.R:
            self.reset_game()

    def on_key_release(self, symbol, modifiers):
        if symbol in (key.RIGHT, key.LEFT):
            self.player.velocity = 0, 0
            if self.ball.on_paddle:
                self.ball.velocity = 0, 0

    def reset_game(self):
        for shape in self.space.shapes:
            if shape.body != self.space.static_body and shape.body.body_type != pymunk.Body.KINEMATIC:
                self.space.remove(shape.body, shape)
        for constraint in self.space.constraints:
            self.space.remove(constraint)
        self.player = Player(self.space)
        self.ball = Ball(self.space, self.player.position)

    def update(self, dt):
        self.space.step(dt)
        self.ball.update()
Ejemplo n.º 4
0
class Simulation(pyglet.window.Window):

    def __init__(self, width=1152, height=720, fullscreen=False):
        super().__init__(width, height, vsync=False, fullscreen=fullscreen, caption="Simple Pendulum")
        self.fps = FPSDisplay(self)
        self.T = 0
        self.ball = Ball()
        self.run = False
        self.trace = []

        pyglet.gl.glPointSize(10)
    
    @property
    def center(self):
        return self.width // 2, self.height // 2

    def update(self, dt):
        if not self.run:
            return

        self.ball.step(dt)

        self.T += dt
    
    def on_draw(self):
        self.clear()

        offset = (self.width // 2, 0)
        if self.run and (int(self.T * 100) % 10 == 0):
            self.trace.extend(self.ball.position_after_offset(offset))

        pyglet.graphics.draw(len(self.trace)//2, pyglet.gl.GL_POINTS,
                  ('v2f', self.trace),
                  ('c3B', [255, 0, 0]*(len(self.trace)//2)),
                  )

        self.ball.draw(offset)
        label = pyglet.text.Label(f"T = {self.T:.3f}",
                                  font_name='Halvetica Nenu',
                                  font_size=16, x=self.width - 10, y=10,
                                  anchor_x="right", anchor_y="bottom")
        label.draw()
        
        self.fps.draw()

    def on_key_press(self, symbol, modifiers):
        if symbol == key.Q and modifiers == key.MOD_COMMAND:
            pyglet.app.exit()

    def on_key_release(self, symbol, modifiers):
        if symbol == key.SPACE:
            self.run = not self.run
Ejemplo n.º 5
0
class GameWindow(pyglet.window.Window):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.set_location(100, 100)
        self.frame_rate = 1 / 60.0
        self.fps_display = FPSDisplay(self)

    def on_draw(self):
        self.clear()

        self.fps_display.draw()

    def update(self, dt):
        pass
Ejemplo n.º 6
0
class GameWindow(pyglet.window.Window):
    """

    """
    def __init__(self, aspect_ratio, dt_for_physicx, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # set window location
        position = aspect_ratio.scale(300, 50)
        self.set_location(position.x, position.y)
        # framerate display
        self.fps = FPSDisplay(self)
        self.engine = GameEngine(aspect_ratio, dt_for_physicx)
        self.dt_for_physicx = dt_for_physicx
        self.remain_time_for_updating_physicx = dt_for_physicx

    def on_draw(self):
        self.clear()
        self.engine.on_draw()
        self.fps.draw()

    def on_key_press(self, symbol, modifiers):
        try:
            self.engine.on_action_command_press(map_key_command[symbol])
        except KeyError:
            if symbol == key.ESCAPE:
                self.quit_game()

    def on_key_release(self, symbol, modifiers):
        try:
            self.engine.on_action_command_release(map_key_command[symbol])
        except KeyError:
            pass

    def update(self, dt):
        """

        :param dt:
        :return:

        """
        # dt: deltatime from display
        self.remain_time_for_updating_physicx -= dt

        while self.remain_time_for_updating_physicx < 0.0:
            self.engine.update(self.dt_for_physicx)
            self.remain_time_for_updating_physicx += self.dt_for_physicx

    def quit_game(self):
        # http://nullege.com/codes/search/pyglet.app.exit
        pyglet.app.exit()
Ejemplo n.º 7
0
class Simulation(pyglet.window.Window):
    def __init__(self, width=1152, height=720, fullscreen=False):
        super().__init__(width,
                         height,
                         vsync=False,
                         fullscreen=fullscreen,
                         caption="Simple Pendulum")
        self.fps = FPSDisplay(self)
        self.T = 0
        self.pendulums = [Pendulum(length=100)]
        # self.pendulums = [Pendulum(length=x, theta=math.pi/16) for x in range(25, 200, 25)]

    @property
    def center(self):
        return self.width // 2, self.height // 2

    def update(self, dt):
        for pendulum in self.pendulums:
            pendulum.step(dt)

        self.T += dt

    def on_draw(self):
        self.clear()

        for pendulum in self.pendulums:
            pendulum.draw((self.width // 2, self.height))

        label = pyglet.text.Label(f"T = {self.T:.3f}",
                                  font_name='Halvetica Nenu',
                                  font_size=16,
                                  x=self.width - 10,
                                  y=10,
                                  anchor_x="right",
                                  anchor_y="bottom")
        label.draw()

        self.fps.draw()

    def on_key_press(self, symbol, modifiers):
        if symbol == key.Q and modifiers == key.MOD_COMMAND:
            pyglet.app.exit()

    def on_key_release(self, symbol, modifiers):
        if symbol == key.SPACE:
            pyglet.clock.schedule_interval(self.update, 1 / 500.0)
Ejemplo n.º 8
0
class DebugWindow(BaseWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.draw_options = pymunk.pyglet_util.DrawOptions()
        self.fps_display = FPSDisplay(window=self)
        self.fps_display.label.color = (255, 255, 255, 255)
        self.fps_display.label.font_size = 10

    def on_draw(self):
        self.clear()
        self.group_world_camera.set_state_recursive()
        self.game.space.debug_draw(self.draw_options)
        self.group_world_camera.unset_state_recursive()
        self.fps_display.draw()

    def show_message(self, text, timeout):
        print(f"DEBUG: show_message '{text}' (timeout={timeout})")

    def update_track(self, track):
        pass
Ejemplo n.º 9
0
class Simulation(pyglet.window.Window):
    def __init__(self, width=1152, height=720):
        super().__init__(width, height, vsync=False, caption="Spring Pendulum")
        self.refresh_rate = 500.0
        self.fps = FPSDisplay(self)
        self.spring_pendulum = SpringPendulum(m=5)
        self.T = 0

        self.is_playing = False

    def update(self, dt):
        self.spring_pendulum.step(dt)
        self.T += dt

    def on_draw(self):
        self.clear()
        self.spring_pendulum.draw((self.width // 2, self.height - 50))
        label = pyglet.text.Label(f"T = {self.T:.6f}",
                                  font_name='Halvetica Nenu',
                                  font_size=16,
                                  x=self.width - 10,
                                  y=10,
                                  anchor_x="right",
                                  anchor_y="bottom")
        label.draw()
        self.fps.draw()

    def on_key_press(self, symbol, modifiers):
        if symbol == key.Q and modifiers == key.MOD_COMMAND:
            pyglet.app.exit()

    def on_key_release(self, symbol, modifiers):
        if symbol == key.SPACE:
            if self.is_playing:
                pyglet.clock.unschedule(self.update)
            else:
                pyglet.clock.schedule_interval(self.update,
                                               1 / self.refresh_rate)

            self.is_playing = not self.is_playing
Ejemplo n.º 10
0
class MyWindow(pyglet.window.Window):
    def __init__(self, *args, **kwargs):
        super(MyWindow, self).__init__(*args, **kwargs)
        #this clear thing affect the background color
        #comment it out to get a black background
        glClearColor(1, 1.0, 1.0, 1)
        self.fps_display = FPSDisplay(self)
        self.car = CarSprite()
        self.key_handler = key.KeyStateHandler()
        self.testTrack = Track([40, 60, 1200, 600], [240, 260, 800, 200])
        self.testGrid = Grid(40, 60, 1200, 600, 50)

    def on_draw(self):
        glClear(GL_COLOR_BUFFER_BIT)
        self.fps_display.draw()
        self.testGrid.draw()
        self.testTrack.draw()
        self.car.draw()

    def on_key_press(self, symbol, modifiers):
        if symbol == key.UP:
            print('accelerate')
            self.car.goStraight()
        elif symbol == key.DOWN:
            print('reverse')
            self.car.goReverse()
        elif symbol == key.LEFT:
            print('turn left')
            self.car.turnLeft()
        elif symbol == key.RIGHT:
            print('turn right')
            self.car.turnRight()
        elif symbol == key.ESCAPE:
            pyglet.app.exit()

    def update(self, dt):
        pass
Ejemplo n.º 11
0
class GameWindow(pyglet.window.Window):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.set_location(100, 100)
        self.frame_rate = 1 / 60.0
        self.fps_display = FPSDisplay(self)
        self.fps_display.label.font_size = 24

        # Hier wird der Pfad zum Verzeichnis des ».py«-Files gesetzt
        # Erspart einem das Herumgehample in TextMate mit dem os.getcwd()
        # und os.path.join()
        file_path = os.path.dirname(os.path.abspath(__file__))
        os.chdir(file_path)

        self.player = GameObject(50, 300, "Spritesheet_64x29.png")

    def on_draw(self):
        self.clear()
        self.player.sprite.draw()

        self.fps_display.draw()

    def update(self, dt):
        pass
class GameWindow(pyglet.window.Window):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.set_location(500, 50)
        self.fps = FPSDisplay(self)

        self.space = pymunk.Space()
        self.options = DrawOptions()

        self.player = Player(self.space)
        self.puck = Puck(self.space)
        self.rail = Rail(self.space)

    #Metoda służąca do rysowania, wpisujemy co ma rysować
    def on_draw(self):
        #czyści okno na fpsach
        self.clear()
        self.space.debug_draw(self.options)
        self.fps.draw()

    def on_key_press(self, symbol, modifiers):
        if symbol == key.RIGHT:
            self.player.velocity = 600, 0
        if symbol == key.LEFT:
            self.player.velocity = -600, 0
        if symbol == key.UP:
            self.player.velocity = 0, 600
        if symbol == key.DOWN:
            self.player.velocity = 0, -600

    def on_key_release(self, symbol, modifiers):
        if symbol in (key.RIGHT, key.LEFT, key.UP, key.DOWN):
            self.player.velocity = 0, 0

    def update(self, dt):
        self.space.step(dt)
Ejemplo n.º 13
0
class GameWindow(pyglet.window.Window):
    # Constructor
    def __init__(self, enable_neat=False, night_mode=False, *args, **kwargs):
        # Inherit the pyglet window
        super().__init__(caption="Google Chrome Dinosaur Game (with NEAT)",
                         width=WINDOW_WIDTH,
                         height=WINDOW_HEIGHT,
                         *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(FONT_NAME)
        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)

        # Create the game instance
        self.game = GameEventHandler(enable_neat=enable_neat,
                                     night_mode=night_mode)

        # If NEAT is enabled, run the game using NEAT. Otherwise, let the player play manually
        if enable_neat:
            self.game.run_neat()
        else:
            pyglet.app.run()

    # Handle the events when a key is pressed
    def on_key_press(self, symbol, modifiers):
        # Terminate the game if the ESC key is pressed
        if symbol == key.ESCAPE:
            self.on_close()

        # 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.game.trigger_duck = True
            elif symbol in (key.SPACE, key.UP, key.W):
                self.game.trigger_jump = True

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

    # Handle the events when a key is released
    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.game.trigger_duck = False

            # Check if the user released a key that triggers a jump
            if symbol in (key.SPACE, key.UP, key.W):
                self.game.trigger_jump = False

    # Handle the events when the mouse is pressed
    def on_mouse_press(self, x, y, button, modifiers):
        # Handle the left click
        if button == mouse.LEFT:
            self.game.on_mouse_press(x, y)

    # Draw the contents on the screen
    def on_draw(self):
        self.clear()  # Clear the screen
        self.game.draw()  # Draw the game
        self.fps_display.draw()  # Draw the FPS

    # Update the objects
    def update(self, dt):
        self.game.update(dt)

    # Terminate the game if the window is closed
    def on_close(self):
        self.game.user_exit = True
        super().on_close()
Ejemplo n.º 14
0
class Game(pg.window.Window):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.frame_rate = 1 / FPS
        self.fps_display = FPSDisplay(self)

        self.load_keyevent_dicts()

        self.wait_for_response = False
        self.update_queue = queue.Queue()

    def load_keyevent_dicts(self):

        self.direction_dict = dict()
        self.direction_dict[key.LEFT] = [-1, 0]
        self.direction_dict[key.RIGHT] = [+1, 0]
        self.direction_dict[key.UP] = [0, 1]
        self.direction_dict[key.DOWN] = [0, -1]

        self.kdict = dict()
        self.kdict["direction"] = [0, 0]

    def connect_to_server(self,
                          playername=PLAYERNAME,
                          address=SERVER_ADDRESS,
                          port=SERVER_PORT):
        conf = dict()
        conf["playername"] = playername
        conf["server_ip"] = address
        conf["server_port"] = port

        self.client = Client(conf)
        self.client.start()
        self.client.send_playername()

    def new_game(self, mapfile):
        self.send_mapdata(mapfile)
        self.client.send_ready(True)

        while not self.client.mapdata:
            print("{}: {}".format(self.client.num_players,
                                  self.client.status_players))
            time.sleep(1)
        print("all player ready!")

        #        print(self.client.mapdata)

        self.world = World(self)
        self.world_drawer = WorldDrawer(self)

#        print(self.world.dump_mapdata())

    def send_mapdata(self, filename):
        with open(filename, "r") as mapfile:
            mapdata = mapfile.readlines()
            self.client.send(nongame_content={"mapdata": mapdata[::-1]})

    def start(self):
        pg.clock.schedule_interval(self.update, self.frame_rate)
        #        self.lock_step_thread = LockStepThread(self)
        #        self.lock_step_thread.start()
        pg.app.run()

    def update(self, dt):
        for obj in self.world.update_objects:
            obj.update(dt)

        if not self.wait_for_response:
            game_content = self.prepare_packet(
            )  # empty list if no action for server
            #            print("DESIRED:\n{}".format(game_content)) if len(updates)>0 else None
            self.client.send(game_content=game_content)
            self.wait_for_response = True

#        elif all(gui_updates_finished):
        else:
            try:
                updates = self.client.recv_queue.popleft()
                #                print("UPDATES:\n{}".format(updates)) if len(updates)>0 else None
                self.world.apply_updates(updates)
                self.wait_for_response = False
            except IndexError:
                pass

    def prepare_packet(self):
        game_content = []

        # player movements
        # player movement can be triggered if either character stands still or
        # if last player movement is already 70% done -> reduces visible lag because of
        # network traffic (rtt)
        if self.world.player.walk_prog_factor == 0 or self.world.player.walk_prog_factor > 0.6:
            dx, dy = self.kdict["direction"]
            # if no movement -> nop, so that other players are allowed to move
            #            if not (dx != 0 and dy != 0):
            if dx != 0 or dy != 0:
                self.world.player.set_image_by_direction(dx, dy)
                px, py = int(self.world.player.x), int(self.world.player.y)
                destx, desty = px + dx, py + dy
                game_content.append(
                    ((px, py), "move", WPLAYER, (destx, desty)))

        # packet prepared
        return game_content

    def quit(self):
        self.client.close()
        pg.app.exit()

    def on_draw(self):
        self.clear()
        self.world_drawer.draw()
        self.fps_display.draw()

    def on_key_press(self, symbol, modifiers):
        if symbol in self.direction_dict.keys():
            self.kdict["direction"] = self.direction_dict[symbol]
        elif symbol == key.ESCAPE:
            self.quit()

    def on_key_release(self, symbol, modifiers):
        if symbol in self.direction_dict.keys():
            if self.kdict["direction"] == self.direction_dict[symbol]:
                self.kdict["direction"] = [0, 0]
Ejemplo n.º 15
0
class Drawer(OldDrawer):
    window = None
    _labels_cache = None
    FONT_SIZE = 16

    def __init__(self, game, show_borders=False):
        self.window = pyglet.window.Window(
            width=self.SCREEN_WIDTH,
            height=self.SCREEN_HEIGHT,
            caption='BATTLE CITY AI',
        )
        glEnable(GL_BLEND)
        self._labels_cache = {}
        # I dunno what this is doing
        # BUT i need this to run pyglet without event loop
        pyglet.app.event_loop._legacy_setup()

        self.fps = FPSDisplay(self.window)
        self.background = pyglet.image.create(self.SCREEN_WIDTH,
                                              self.SCREEN_HEIGHT)
        self.time = 0
        self.game = game
        self.show_borders = show_borders

    @staticmethod
    def _load_pack(name):
        pathfile = path.join(IMAGES_DIR, '%s.png' % name)
        image = pyglet.image.load(pathfile)
        texture = image.get_texture()
        texture.anchor_x = 16
        texture.anchor_y = 16

        def rotate(x):
            new_text = texture.get_transform(rotate=x)
            new_text.anchor_x = 0
            new_text.anchor_y = 0
            return new_text

        return {
            Direction.UP: rotate(0),
            Direction.DOWN: rotate(180),
            Direction.RIGHT: rotate(90),
            Direction.LEFT: rotate(270),
        }

    @staticmethod
    def _load_simple(name):
        pathfile = path.join(IMAGES_DIR, '%s.png' % name)
        return pyglet.image.load(pathfile)

    def render(self):
        self.window.clear()
        super().render()

    def _post_render(self):
        self._render_players()
        self.fps.draw()
        self.window.flip()

    def _support_events(self):
        return

    def _render_background(self):
        self.background.blit(0, 0)

    def bake_static_background(self):
        surface = pyglet.image.create(
            width=self.SCREEN_WIDTH,
            height=self.SCREEN_HEIGHT,
            pattern=SolidColorImagePattern(color=(0x5f, 0x57, 0x4f, 0xff)))

        self._render_solid_colors(surface)
        self._render_walls(surface)
        self._render_coins(surface)
        self.background = surface

    def _render_solid_colors(self, surface):
        black = pyglet.image.create(
            width=self.game.WIDTH,
            height=self.game.HEIGHT,
            pattern=SolidColorImagePattern(color=(0, 0, 0, 0xff)))
        offset = self.OFFSET
        black.blit_to_texture(surface.get_texture().target, 0, offset,
                              self.SCREEN_HEIGHT - self.game.HEIGHT - offset,
                              0)

    def _render_walls(self, surface):
        target = surface.get_texture().target
        for wall in self.game.walls:
            position = wall.position
            xx = position.x % Wall.SIZE
            yy = position.y % Wall.SIZE
            image = self.WALLS[type(wall)]
            region = image.get_region(xx, yy, position.width, position.height)
            region = region.get_image_data()
            region.blit_to_texture(
                target, 0, self.OFFSET + position.x, self.SCREEN_HEIGHT -
                self.OFFSET - position.y - position.height, 0)

    def _render_coins(self, surface):
        image = self.IMAGES['COIN']
        target = surface.get_texture().target
        for coin in self.game.coins:
            position = coin.position
            image.blit_to_texture(
                target, 0, self.OFFSET + position.x, self.SCREEN_HEIGHT -
                self.OFFSET - position.y - position.height, 0)

    def _render_label(self,
                      id: str,
                      label: str,
                      cords,
                      color=(0xff, 0xf1, 0xe8)):
        label_obj = self._labels_cache.get(id)
        text = label_obj and label_obj.text

        if text != label:
            label_obj = pyglet.text.Label(
                label,
                font_name='monospace',
                font_size=self.FONT_SIZE,
                color=color + (0xFF, ),
                x=self.OFFSET_LABELS_X + cords[0],
                y=self.SCREEN_HEIGHT - self.OFFSET_LABELS_Y - cords[1],
            )
            self._labels_cache[id] = label_obj
        label_obj.draw()

    def _blit(self, image_name, monster, rect=None):
        image_pack = self.IMAGES[image_name]

        if isinstance(image_pack, dict):
            image = image_pack[monster.direction]
        else:
            image = image_pack

        position = rect or monster.position
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
        image.blit(
            self.OFFSET + position.x,
            self.SCREEN_HEIGHT - self.OFFSET - position.y - position.height,
        )

    def _draw_rectangle(self, rect, color=(0xFF, 0, 0)):
        x = self.OFFSET + rect.x
        y = self.SCREEN_HEIGHT - self.OFFSET - rect.y
        w = x + rect.width
        h = y - rect.height
        pyglet.graphics.draw(4, pyglet.gl.GL_LINE_LOOP, ('v2f', [
            x,
            y,
            w,
            y,
            w,
            h,
            x,
            h,
        ]), ('c3B', color * 4))
Ejemplo n.º 16
0
class GameWindow(pyglet.window.Window):
    def __init__(self, *args, **kwargs):
        # Refers to pyglet.window.Window
        super().__init__(*args, **kwargs)
        # set the window's location at a certain point, x-pos, y-pos
        self.set_location(400, 100)
        # set the window's frame-rate, this is 60.0 fps
        self.frame_rate = 1 / 60.0
        # Screen or Window is self.
        self.fps_display = FPSDisplay(self)
        # Make fps display bigger.
        self.fps_display.label.font_size = 25

        # Preload the background
        self.car_background = Sprite(preload_image('CarGameBackground.jpg'))
        # Preload the car
        car = preload_image('carFIXED.png')
        # Center the car's rotation at its center.
        center_image(car)
        # Transfer car to a sprite
        sprite_car = pyglet.sprite.Sprite(car)
        self.rotation = 0
        self.car_acceleration = 0
        self.car_max_acceleration = 300
        self.car_max_velocity = 300
        # Initial sprite position, rotation, image
        self.car = GameObject(135, 425, self.rotation, sprite_car)
        self.car_vector_position = Vector2(self.car.position_x,
                                           self.car.position_y)
        self.car_vector_velocity = Vector2(0, 0)

        # Two New Objects that are Circles.
        self.circle = CircleLines(200, 690, 288)
        self.circle2 = CircleLines2(200, 581, 227)

        # Death Counter
        self.death_counter = 0

        # Keys
        self.right = False
        self.left = False
        self.forward = False
        self.back = False

    # KEY PRESS
    def on_key_press(self, symbol, modifiers):
        if symbol == key.RIGHT:
            self.right = True
        if symbol == key.LEFT:
            self.left = True
        if symbol == key.UP:
            self.forward = True
        if symbol == key.DOWN:
            self.back = True
        # Exit Window/Application
        if symbol == key.ESCAPE:
            pyglet.app.exit()

    # KEY RELEASE
    def on_key_release(self, symbol, modifiers):
        if symbol == key.RIGHT:
            self.right = False
        if symbol == key.LEFT:
            self.left = False
        if symbol == key.UP:
            self.forward = False
        if symbol == key.DOWN:
            self.back = False

    # Draw on Window
    def on_draw(self):
        death_label = pyglet.text.Label(str(int(self.death_counter)),
                                        font_name='Times New Roman',
                                        font_size=36,
                                        x=1500,
                                        y=800,
                                        anchor_x='center',
                                        anchor_y='center')
        # Check Collisions and position
        self.check_position()
        # Step 0: Clear the area.
        self.clear()
        # Step 1: Draw the background before the car.
        self.car_background.draw()
        # Step 2: Draw the Sprite. from GameObject, there's a method called draw.
        self.car.draw()
        # Outer
        self.circle.draw()
        # Inner
        self.circle2.draw()
        # Step 3: Draw on display FPS
        self.fps_display.draw()
        # Step 4: Draw the death counter
        death_label.draw()

    def update_car(self, dt):
        self.check_collision()
        self.car.update()
        self.car_acceleration = 50
        if self.forward:
            self.check_velocity()
            self.check_acceleration()
            self.change_velocity(self.car_acceleration, dt)
            self.change_position(dt)

        if not self.forward:
            self.check_velocity()
            self.check_acceleration()
            self.change_velocity_negative(self.car_acceleration, dt)
            self.change_position(dt)

        if self.left:
            self.car.rotation -= 2

        if self.right:
            self.car.rotation += 2

        if self.back:
            self.brake_car(self.car_acceleration, dt)

        self.check_rotation()

    def brake_car(self, acceleration, dt):
        self.car_vector_velocity -= (acceleration * dt * 5, 0)

    def check_acceleration(self):
        if self.car_acceleration >= self.car_max_acceleration:
            self.car_acceleration = self.car_max_acceleration
        if self.car_acceleration <= 0:
            self.car_acceleration = 0

    def change_position(self, dt):
        # Figure out what is going on with the math here.
        self.car_vector_position += self.car_vector_velocity.rotate(
            -self.car.rotation) * dt
        self.car.position_x, self.car.position_y = self.car_vector_position

    def check_collision(self):
        # Pythagorean Theorem
        def get_distance(x1, y1, x2, y2):
            xDistance = x2 - x1
            yDistance = y2 - y1
            return math.floor(
                math.sqrt(math.pow(xDistance, 2) + math.pow(yDistance, 2)))

        # Reset Position and Velocity
        # Enumerates through two lists at the same time, and compares the positions through each sharing index.
        def reset_position_velocity(circleX, circleY):
            for i, number_x in enumerate(circleX):
                number_y = circleY[i]
                distance_from_wall = get_distance(self.car.position_x,
                                                  self.car.position_y,
                                                  number_x, number_y)

                # Check this number to see how well it works with AI
                if distance_from_wall < 7.0:
                    self.car_vector_position = [135, 450]
                    self.car_vector_velocity = [0, 0]
                    self.death_counter += 1

        reset_position_velocity(self.circle.vertices_x, self.circle.vertices_y)
        reset_position_velocity(self.circle2.vertices_x,
                                self.circle2.vertices_y)

    def check_position(self):
        if self.car.position_x < 0:
            self.car.position_x = 0
        if self.car.position_x > 1600:
            self.car.position_x = 1600
        if self.car.position_y > 900:
            self.car.position_y = 900
        if self.car.position_y < 0:
            self.car.position_y = 0

    def change_velocity(self, acceleration, dt):
        self.car_vector_velocity += (acceleration * dt, 0)

    def change_velocity_negative(self, acceleration, dt):
        if self.car_vector_velocity != [0, 0]:
            self.car_vector_velocity -= (acceleration * dt, 0)

    def check_velocity(self):
        self.car_vector_velocity_x, self.car_vector_velocity_y = self.car_vector_velocity

        if self.car_vector_velocity_x < 0:
            self.car_vector_velocity_x = 0
        if self.car_vector_velocity_y < 0:
            self.car_vector_velocity_y = 0
        if self.car_vector_velocity_x > self.car_max_velocity:
            self.car_vector_velocity_x = self.car_max_velocity
        if self.car_vector_velocity_y > self.car_max_velocity:
            self.car_vector_velocity_y = self.car_max_velocity

        self.car_vector_velocity = Vector2(self.car_vector_velocity_x,
                                           self.car_vector_velocity_y)

    def check_rotation(self):
        # Reset rotation degrees so that it doesn't go to a billion.
        if self.car.rotation == 360 or self.car.rotation == -360:
            self.car.rotation = 0

    def update(self, dt):
        # Update car in order of Delta Time
        self.update_car(dt)
Ejemplo n.º 17
0
class GameWindow(pyglet.window.Window):
    def __init__(self, *args, **kwargs):
        super(GameWindow, self).__init__(*args, **kwargs)
        self.set_location(400, 100)
        self.frame_rate = 1 / 60.0
        self.fps_display = FPSDisplay(self)
        self.fps_display.label.font_size = 50
        self.fps_display.label.y = 300

        self.right = False
        self.left = False
        self.player_speed = 300
        self.fire = False
        self.player_fire_rate = 0

        player_spr = pyglet.sprite.Sprite(preload_image('Carrot.png'))
        self.player = GameObject(500, 100, 0, 0, player_spr)

        self.player_laser = preload_image('laser.png')
        self.player_laser_list = []

        self.grass_list = []
        self.grass_img = preload_image('Grass.png')
        for i in range(3):
            self.grass_list.append(
                GameObject(0, i * 675, 0, -200, Sprite(self.grass_img)))

    def on_key_press(self, symbol, modifiers):
        if symbol == key.RIGHT:
            self.right = True
        if symbol == key.LEFT:
            self.left = True
        if symbol == key.SPACE:
            self.fire = True
            #self.player_laser_list.append(GameObject(self.player.posx, self.player.posy, 0, 0, Sprite(self.player_laser)))
        if symbol == key.ESCAPE:
            pyglet.app.exit()

    def on_key_release(self, symbol, modifiers):
        if symbol == key.RIGHT:
            self.right = False
        if symbol == key.LEFT:
            self.left = False
        if symbol == key.SPACE:
            self.fire = False

    def on_draw(self):
        self.clear()
        for grass in self.grass_list:
            grass.draw()
        self.player.draw()
        for lsr in self.player_laser_list:
            lsr.draw()
        self.fps_display.draw()

    def update_player(self, dt):
        self.player.update(dt)
        if self.right and self.player.posx < 1000 - self.player.width:
            self.player.posx += self.player_speed * dt
        if self.left and self.player.posx > 100:
            self.player.posx -= self.player_speed * dt

    def update_player_laser(self, dt):
        for lsr in self.player_laser_list:
            lsr.update(dt)
            lsr.posy += 400 * dt
            if lsr.posy > 700:
                self.player_laser_list.remove(lsr)

    def player_fire(self, dt):
        self.player_fire_rate -= dt
        if self.player_fire_rate <= 0:
            self.player_laser_list.append(
                GameObject(self.player.posx, self.player.posy + 76, 0, 0,
                           Sprite(self.player_laser)))
            self.player_fire_rate += 0.2

    def update_space(self, dt):
        first_grass = self.grass_list[0]
        if first_grass.posy <= -975:
            first_grass = self.grass_list.pop(0)
            last_grass = self.grass_list[-1]
            first_grass.posy = last_grass.posy + 675
            self.grass_list.append(first_grass)

        # positions = ""
        for grass in self.grass_list:
            grass.update(dt)
            # positions += grass.posy
            #grass.posy -=50

    def update(self, dt):
        self.update_player(dt)
        if self.fire:
            self.player_fire(dt)

        self.update_player_laser(dt)
        self.update_space(dt)
Ejemplo n.º 18
0
class Scherm(pyglet.window.Window):
    def __init__(self, *args, **kwargs):
        #inintialiseer schermpje
        super().__init__(*args, **kwargs)

        #fps

        self.fps = FPSDisplay(self)

        self.images = self.load_images(IMAGES)
        self.veld = self.create_veld(
        )  #todo verander de afbeeldingen zodat ze een achtergrond hebben
        self.actief = None
        self.objlist_1 = {
        }  #{(1,1)=obj op deze plaats} dit zou de cirkels kunnen bevatten
        self.objlist_2 = {}
        '''
        #test het is:
        img = "res/images/empty.png"
        self.vakjes = []
        for i in range(10):
            for j in range(10):
                self.vakjes.append(GameObject(i*50,j*50, image=img))
        #self.vakje = GameObject(10, 10, image=img)
        #self.vakje2 = GameObject(10, 10, 50, 50, image=img)
        self.vakjes.append(King(image="res/images/king.png"))
        
        #via een menu kan men het veld kiezen, dit wordt ingelezen uit een bepaalde file
        '''

    #pyglet functions:
    def on_draw(self):
        self.clear()

        #teken layer 0 veld
        self.draw_veld(self.veld)

        #teken layer 1 pionnen en laser
        for q in self.objlist_1.values():
            q.draw()

        #teken layer 2 witte bollen als nodig
        for q in self.objlist_2.values():
            q.draw()

        #draw fps counter
        self.fps.draw()

    def on_mouse_press(self, x, y, button, modifiers):
        vak_x = x // 50
        vak_y = y // 50
        if button == pyglet.window.mouse.RIGHT:
            self.objlist_1[(vak_x,
                            vak_y)] = King(vak_x * 50,
                                           vak_y * 50,
                                           image=self.images['king.png'])
        elif button == pyglet.window.mouse.LEFT:

            #klik ik op een witte bol?

            if self.objlist_2.get((vak_x, vak_y), None) != None:
                #verplaats stuk gelinkt aan deze bol
                self.objlist_2[(vak_x, vak_y)].click(self.objlist_1,
                                                     self.images['circle.png'])
                #verwijder alle witte bollen
                self.objlist_2 = {}
                self.actief = None
            ############

            #klik ik op een speelstuk
            elif self.objlist_1.get(
                (vak_x, vak_y), None) != None:  #vermijd zo keyerror

                #is dit het speelstuk dat ik al aangeklikt had
                if self.objlist_1[(vak_x, vak_y)] == self.actief:
                    self.actief = None
                    self.objlist_2 = {}

                #dit is nu het speelstuk dat ik wil aanklikken
                else:
                    self.objlist_2 = {}
                    self.objlist_1[(vak_x,
                                    vak_y)].click(self.objlist_1,
                                                  self.objlist_2,
                                                  self.images['circle.png'])
                    self.actief = self.objlist_1[(vak_x, vak_y)]

            #self.objlist[(vak_x, vak_y)].click(self.objlist, self.images['circle.png'])

        #self.draw_list.append(GameObject(vak_x*50, vak_y*50, image=self.images['circle.png']))

    def update(self, dt):
        pass

    #game functions:
    def load_images(self, PATH):
        pngs = [i.split("\\") for i in glob.glob(PATH + '*.png')]
        imgs = {}
        for i in pngs:
            imgs[i[1]] = pyglet.image.load(f"{i[0]}/{i[1]}")
        return imgs

    def create_veld(self, rows=10, columns=10):  #, name=None):
        #read from file
        #TODO
        veld = [[
            GameObject(i * 50, j * 50, image=self.images['empty.png'])
            for i in range(columns)
        ] for j in range(rows)]
        return veld

    def draw_veld(self, veld):
        for rij in veld:
            for obj in rij:
                obj.draw()
Ejemplo n.º 19
0
class Game(pyglet.window.Window):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.set_location(100, 100)
        self.set_caption('Pong')
        self.set_mouse_visible(False)
        self.frame_rate = 1 / 60.
        self.fps_display = FPSDisplay(self)
        self.keys = key.KeyStateHandler()

        main_batch = pyglet.graphics.Batch()

        self.ai = True

        self.play_sounds = True
        if self.play_sounds:
            self.sounds = Sounds()

        self.paddle_left = Paddle('left', self.sounds, self.width, self.height,
                                  self.keys, self.ai)
        self.paddle_right = Paddle('right', self.sounds, self.width,
                                   self.height, self.keys)
        self.ball = Ball(self.sounds, self.width, self.height, self.keys)
        self.line = Line(self.width, self.height, self.keys)

        self.score_left = Score('left',
                                self.width,
                                self.height,
                                '0',
                                batch=main_batch)
        self.score_right = Score('right',
                                 self.width,
                                 self.height,
                                 '0',
                                 batch=main_batch)
        score = {'left': 0, 'right': 0}
        self.scores = [score, self.score_left, self.score_right]

        self.game_menu = True
        self.start_game = MenuItem(self.width,
                                   self.height,
                                   "Start Game",
                                   modifier=2)
        self.start_game.bold = True
        self.difficulty = MenuItem(self.width,
                                   self.height,
                                   "Difficulty: ",
                                   modifier=4)
        self.game_difficulty = 'normal'
        self.difficulty.label.text += self.game_difficulty
        self.exit_game = MenuItem(self.width,
                                  self.height,
                                  "Exit Game",
                                  modifier=6)
        self.menu_items = [self.start_game, self.difficulty, self.exit_game]
        self.current_index = 0
        self.current_selection = self.menu_items[0].label

    def draw_menu(self):
        self.start_game.draw()
        self.difficulty.draw()
        self.exit_game.draw()

    def draw_game_objects(self):
        self.fps_display.draw()
        self.paddle_left.draw()
        self.paddle_right.draw()
        self.ball.draw()
        self.line.draw()
        self.score_left.draw()
        self.score_right.draw()

    def on_draw(self):
        self.clear()
        if self.game_menu:
            self.draw_menu()
        else:
            self.draw_game_objects()

    def choose_menu_item(self, symbol, modifier):
        if symbol == key.DOWN:
            self.current_selection.bold = False
            self.current_selection.font_size -= 10
            self.current_index += 1
            if self.current_index > 2:
                self.current_index = 0
            self.current_selection = self.menu_items[self.current_index].label
            self.current_selection.bold = True
            self.current_selection.font_size += 10
        elif symbol == key.UP:
            self.current_selection.bold = False
            self.current_selection.font_size -= 10
            self.current_index -= 1
            if self.current_index < 0:
                self.current_index = 2
            self.current_selection = self.menu_items[self.current_index].label
            self.current_selection.bold = True
            self.current_selection.font_size += 10
        elif self.current_index == 1 and symbol == key.RIGHT:
            self.game_difficulty = 'harder'
            self.current_selection.text = 'Difficulty: ' + self.game_difficulty
        elif self.current_index == 1 and symbol == key.LEFT:
            self.game_difficulty = 'normal'
            self.current_selection.text = 'Difficulty: ' + self.game_difficulty
        elif symbol == key.ENTER:
            if self.current_index == 0:
                self.game_menu = False
            elif self.current_index == 1:
                pass
            elif self.current_index == 2:
                pyglet.app.exit()

    def on_key_press(self, symbol, modifier):
        if self.game_menu:
            self.choose_menu_item(symbol, modifier)
        else:
            if self.keys[key.ESCAPE]:
                pyglet.app.exit()
            self.push_handlers(self.keys)

    def update(self, dt):
        if self.game_menu:
            pass
        else:
            self.ball.update(self.scores)
            self.paddle_left.update(self.ball, self.game_difficulty)
            self.paddle_right.update(self.ball)
class GameWindow(pyglet.window.Window):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.set_location(400, 100)
        self.frame_rate = 1 / 60.0
        self.fps_display = FPSDisplay(self)

        self.right = False
        self.left = False
        self.player_speed = 300

        player_spr = Sprite(preload_image('pixelship.png'))
        self.player = GameObjectClass(500, 100, player_spr)

        self.space_list = []
        self.space_img = preload_image('bluespace-seamless.png')

        for i in range(2):
            self.space_list.append(
                GameObjectClass(
                    0, i * 1060,
                    Sprite(preload_image('bluespace-seamless.png'))))

        for space in self.space_list:
            space.vely = -500

    def on_draw(self):
        self.clear()
        for space in self.space_list:
            space.draw()
        self.player.sprite.draw()
        self.fps_display.draw()

    def update_player(self, dt):
        self.player.update(dt)
        if self.right and self.player.posx < 1000 - self.player.width:
            self.player.posx += self.player_speed * dt
        if self.left and self.player.posx > 100:
            self.player.posx -= self.player_speed * dt

    def update_space(self, dt):
        for space in self.space_list:
            space.update(dt)
            if space.posy <= -1030:
                self.space_list.append(
                    GameObjectClass(0, abs(space.posy),
                                    Sprite(self.space_img)))
                self.space_list.remove(space)
            space.vely = -500

    def on_key_press(self, symbol, modifiers):
        if symbol == key.RIGHT:
            self.right = True
        if symbol == key.LEFT:
            self.left = True
        if symbol == key.ESCAPE:
            pyglet.app.exit()

    def on_key_release(self, symbol, modifiers):
        if symbol == key.RIGHT:
            self.right = False
        if symbol == key.LEFT:
            self.left = False

    def update(self, dt):
        self.player.update(dt)
        self.update_space(dt)
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()
Ejemplo n.º 22
0
class MyWindow(pyglet.window.Window):
    def __init__(self, *args, **kwargs):

        # WINDOW INITIALIZATIONS
        super().__init__(*args, **kwargs)
        self.frame_rate = 1 / 60.0
        self.fps_display = FPSDisplay(self)
        self.fps_display.label.font_size = 50

        # MAKING THE PRIMITIVE DRAWINGS TRANSPARENT
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

        # GAME MENU INITIALIZATIONS
        self.status = GameStatus()
        self.menu = GameMenu(resolution, self.status.game_menu_text)
        self.smenu = SelectionMenu(resolution, self.status.game_selection_text)
        self.cmenu = ControlsMenu()
        self.amenu = AboutMenu()
        self.start_time = time.time()

        # INITIALLY PLAYING THE MENU BG SONG
        bg_player.play()

        # SPACE BG INITIALIZATIONS
        self.space_list = []
        self.space_img = preload_image(space_bg_img)
        for i in range(2):
            self.space_list.append(
                DisplayObjects(0, i * 1080, Sprite(self.space_img)))
        for space in self.space_list:
            space.vel_y = -space_scroll_speed

        # PLAYER INITIALIZATIONS
        # CREATING PLAYER OBJECTS
        self.player1 = DisplayPlayers(p1_pos_x, p1_pos_y, p1_fire_type)
        self.player2 = DisplayPlayers(p2_pos_x, p2_pos_y, p2_fire_type)

        # PLAYER HP QUAD CREATION
        self.player1.hp = Quad(p1_hp_pos, p1_hp_size, p1_hp_color, 'p1')
        self.player2.hp = Quad(p2_hp_pos, p2_hp_size, p2_hp_color, 'p2')

        # PLAYER GAURD QUAD CREATION
        self.player1.gaurd = Quad(p1_gaurd_pos, p1_gaurd_size, p1_gaurd_color,
                                  'p1')
        self.player2.gaurd = Quad(p2_gaurd_pos, p2_gaurd_size, p2_gaurd_color,
                                  'p2')

        # PLAYER DAMAGE HP QUAD CREATION
        self.player1.dhp = Quad(p1_dhp_pos, p1_dhp_size, p1_dhp_color, 'p1')
        self.player2.dhp = Quad(p2_dhp_pos, p2_dhp_size, p2_dhp_color, 'p2')

    def on_resize(self, width, height):
        # CODE FOR SETTING THE ORIGIN TO THE BOTTOM LEFT CORNER
        width = max(1, width)
        height = max(1, height)
        glViewport(0, 0, width, height)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(0, width, 0, height, -1, 1)
        glMatrixMode(GL_MODELVIEW)

    def on_key_press(self, symbol, modifiers):
        if symbol == key.ESCAPE:
            # GETTING BACK FROM OPTIONS AND CREDITS MENU TO MAIN MENU
            if self.status.game_menu:
                if self.status.game_controls:
                    self.status.game_controls = False
                if self.status.game_about:
                    self.status.game_about = False

            # GETTING BACK FROM SELECTION MENU TO MAIN MENU AND SETTING THE REQUIRED VARIABLES TO DEFAULT
            if self.status.game_selection:
                self.status.game_selection = False
                self.status.game_menu = True
                self.status.player1_selected = False
                self.status.player2_selected = False
                self.smenu.update_p1(-self.smenu.p1_nav_ofs)
                self.smenu.p1_nav_ofs = 0
                self.smenu.update_p2(-self.smenu.p2_nav_ofs)
                self.smenu.p2_nav_ofs = 0

            # FOR PAUSING THE GAME
            if self.status.game_running and not self.status.game_paused:
                self.status.game_paused = True
                self.status.game_running = False
                self.status.game_menu = True
                self.menu = GameMenu(resolution, self.status.pause_menu_text)
                # PAUSING THE GAME MUSIC AND PLAYING THE MENU MUSIC
                game_player.pause()
                bg_player.play()

        if symbol == key.ENTER and time.time(
        ) - self.start_time > starting_screen_timeout + 1:
            # IN GAME MAIN MENU
            if self.status.game_menu:

                # FOR ENTERING INTO THE SELECTION MENU
                if not self.status.game_started and self.menu.nav_ofs == 0:
                    self.status.game_selection = True
                    self.status.game_menu = False

                # FOR RESUMING THE GAME WHILE PAUSED
                elif self.status.game_paused and self.menu.nav_ofs == 0:
                    self.status.game_running = True
                    self.status.game_paused = False
                    self.status.game_menu = False
                    # PAUSING THE MENU MUSIC AND PLAYING THE GAME MUSIC
                    bg_player.pause()
                    game_player.play()

                # FOR ENTERING THE CONTROLS MENU
                elif (not self.status.game_started
                      or self.status.game_paused) and self.menu.nav_ofs == 100:
                    self.status.game_controls = True

                # FOR ENTERING THE CREDITS MENU
                elif (not self.status.game_started
                      or self.status.game_paused) and self.menu.nav_ofs == 200:
                    self.status.game_about = True

                # FOR EXITING THE GAME AND ENTERING MAIN MENU
                elif self.status.game_paused and self.menu.nav_ofs == 300:
                    self.reload()

                # FOR EXITING THE GAME
                elif not self.status.game_started and self.menu.nav_ofs == 300:
                    pyglet.app.exit()

            # FOR RELOADING THE GAME AFTER GAME OVER
            if self.status.game_over:
                self.reload()

        # PLAYER 1 KEY PRESS EVENTS
        if symbol == key.D:
            self.player1.right = True
        if symbol == key.A:
            self.player1.left = True
        if symbol == key.W:
            self.player1.up = True

            # IN GAME MAIN MENU
            if self.status.game_menu:
                # FOR NAVIGATING UP IN GAME MENU
                if not self.status.game_running and not self.status.game_over and not self.status.game_controls and not self.status.game_about:
                    if self.menu.nav_ofs > 0:
                        self.menu.update(-self.menu.nav_step)
                        self.menu.nav_ofs -= self.menu.nav_step
                    elif self.menu.nav_ofs == 0:
                        self.menu.nav_ofs = (len(self.status.game_menu_text) -
                                             1) * self.menu.nav_step
                        self.menu.update(
                            ((len(self.status.game_menu_text) - 1) *
                             self.menu.nav_step))

            # IN GAME SELECTION MENU
            if self.status.game_selection:
                # FOR NAVIGATING UP IN SELECTION MENU
                if self.smenu.p1_nav_ofs > 0:
                    self.smenu.update_p1(-self.smenu.nav_step)
                    self.smenu.p1_nav_ofs -= self.smenu.nav_step
                elif self.smenu.p1_nav_ofs == 0:
                    self.smenu.p1_nav_ofs = (
                        len(self.status.game_selection_text) -
                        1) * self.smenu.nav_step
                    self.smenu.update_p1(
                        ((len(self.status.game_selection_text) - 1) *
                         self.smenu.nav_step))

        if symbol == key.S:
            self.player1.down = True

            # IN GAME MAIN MENU
            if self.status.game_menu:
                # FOR NAVIGATING DOWN IN GAME MENU
                if not self.status.game_running and not self.status.game_over and not self.status.game_controls and not self.status.game_about:
                    if self.menu.nav_ofs < (len(self.status.game_menu_text) -
                                            1) * self.menu.nav_step:
                        self.menu.update(self.menu.nav_step)
                        self.menu.nav_ofs += self.menu.nav_step
                    elif self.menu.nav_ofs == (len(self.status.game_menu_text)
                                               - 1) * self.menu.nav_step:
                        self.menu.nav_ofs = 0
                        self.menu.update(-(
                            (len(self.status.game_menu_text) - 1) *
                            self.menu.nav_step))

            # IN GAME SELECTION MENU
            if self.status.game_selection:
                # FOR NAVIGATING DOWN IN SELECTION MENU
                if self.smenu.p1_nav_ofs < (
                        len(self.status.game_selection_text) -
                        1) * self.smenu.nav_step:
                    self.smenu.update_p1(self.menu.nav_step)
                    self.smenu.p1_nav_ofs += self.menu.nav_step
                elif self.smenu.p1_nav_ofs == (
                        len(self.status.game_selection_text) -
                        1) * self.smenu.nav_step:
                    self.smenu.p1_nav_ofs = 0
                    self.smenu.update_p1(-(
                        (len(self.status.game_selection_text) - 1) *
                        self.smenu.nav_step))

        if symbol == key.F and self.status.game_running:

            # TOGGLE FIRE (MANUAL/AUTO)
            if self.player1.fire_type == "auto":
                self.player1.fire_type = "manual"
            else:
                self.player1.fire_type = "auto"

        if symbol == key.SPACE:
            global p1_hp_score, p1_ship

            # FOR FIRING THE LASERS WHILE GAME RUNNING
            if self.status.game_running:
                if self.player1.fire_type == "auto":
                    self.player1.fire = True
                else:
                    self.player1.laser_list.append(
                        Lasers(self.player1.pos_x + 96,
                               self.player1.pos_y + 34, [20, 5], p1_dhp_color))
                    self.player1.laser_sound.play()

            # IN GAME SELECTION MENU
            if self.status.game_selection:

                # FOR SELECTING THE SHIP OF PLAYER 1 AND SETTING THE SELECTED SHIP STATS TO THE PLAYER OBJECT
                if self.smenu.p1_nav_ofs == 0:
                    self.player1.set_stats(p1_ship1_stats)
                    p1_ship = self.status.game_selection_text[0]
                elif self.smenu.p1_nav_ofs == 100:
                    self.player1.set_stats(p1_ship2_stats)
                    p1_ship = self.status.game_selection_text[1]
                elif self.smenu.p1_nav_ofs == 200:
                    self.player1.set_stats(p1_ship3_stats)
                    p1_ship = self.status.game_selection_text[2]

                # CALCULATING THE PLAYER 1 SHIP HP SCORE BASED ON SELECTED SHIP STAT
                p1_hp_score = p1_total_life / self.player1.damage_taken

                # CHECKING FOR PLAYER 2 SHIP SELECTION // IF TRUE START THE GAME
                self.status.player1_selected = True
                if self.status.player2_selected:
                    self.status.game_started = True
                    self.status.game_running = True
                    self.status.game_selection = False
                    # FOR PAUSING THE MENU MUSIC AND PLAYING THE GAME MUSIC
                    bg_player.pause()
                    game_player.play()

        # PLAYER SPECIAL FIRE
        if symbol == key.G and self.status.game_running:
            self.player1.sp_fire = True
            if len(self.player1.sp_laser_list) < 3:
                self.player1.sp_laser_list.append(
                    Lasers(self.player1.pos_x + 96, self.player1.pos_y + 34,
                           [50, 50], [255, 0, 0, 255] * 4))

        # PLAYER 1 GAURDING
        if symbol == key.LSHIFT and self.status.game_running:
            self.player1.gaurding = True

        # PLAYER 2 KEY PRESS EVENTS
        if symbol == key.RIGHT:
            self.player2.right = True
        if symbol == key.LEFT:
            self.player2.left = True
        if symbol == key.UP:
            self.player2.up = True

            # IN GAME SELECTION MENU
            if self.status.game_selection:
                # FOR NAVIGATING UP IN SELECTION MENU
                if self.smenu.p2_nav_ofs > 0:
                    self.smenu.update_p2(-self.smenu.nav_step)
                    self.smenu.p2_nav_ofs -= self.smenu.nav_step
                elif self.smenu.p2_nav_ofs == 0:
                    self.smenu.p2_nav_ofs = (
                        len(self.status.game_selection_text) -
                        1) * self.smenu.nav_step
                    self.smenu.update_p2(
                        ((len(self.status.game_selection_text) - 1) *
                         self.smenu.nav_step))

        if symbol == key.DOWN:
            self.player2.down = True

            # IN GAME SELECTION  MENU
            if self.status.game_selection:
                # FOR NAVIGATING DOWN IN SELECTION MENU
                if self.smenu.p2_nav_ofs < (
                        len(self.status.game_selection_text) -
                        1) * self.smenu.nav_step:
                    self.smenu.update_p2(self.menu.nav_step)
                    self.smenu.p2_nav_ofs += self.menu.nav_step
                elif self.smenu.p2_nav_ofs == (
                        len(self.status.game_selection_text) -
                        1) * self.smenu.nav_step:
                    self.smenu.p2_nav_ofs = 0
                    self.smenu.update_p2(-(
                        (len(self.status.game_selection_text) - 1) *
                        self.smenu.nav_step))

        if symbol == key.NUM_0 and self.status.game_running:

            # TOGGLE FIRE (MANUAL/AUTO)
            if self.player2.fire_type == "auto":
                self.player2.fire_type = "manual"
            else:
                self.player2.fire_type = "auto"

        if symbol == key.P:
            global p2_hp_score, p2_ship

            # FOR FIRING THE LASERS WHILE GAME RUNNING
            if self.status.game_running:
                if self.player2.fire_type == "auto":
                    self.player2.fire = True
                else:
                    self.player2.laser_list.append(
                        Lasers(self.player2.pos_x - 17,
                               self.player2.pos_y + 34, [20, 5], p2_hp_color))
                    self.player2.laser_sound.play()

            # IN GAME SELECTION MENU
            if self.status.game_selection:

                # FOR SELECTING THE SHIP OF PLAYER 2 AND SETTING THE SELECTED SHIP STATS TO THE PLAYER OBJECT
                if self.smenu.p2_nav_ofs == 0:
                    self.player2.set_stats(p2_ship1_stats)
                    p2_ship = self.status.game_selection_text[0]
                elif self.smenu.p2_nav_ofs == 100:
                    self.player2.set_stats(p2_ship2_stats)
                    p2_ship = self.status.game_selection_text[1]
                elif self.smenu.p2_nav_ofs == 200:
                    self.player2.set_stats(p2_ship3_stats)
                    p2_ship = self.status.game_selection_text[2]

                # CALCULATING THE PLAYER 2 SHIP HP SCORE BASED ON SELECTED SHIP STAT
                p2_hp_score = p2_total_life / self.player2.damage_taken
                self.status.player2_selected = True
                if self.status.player1_selected:
                    self.status.game_started = True
                    self.status.game_running = True
                    self.status.game_selection = False
                    # FOR PAUSING THE MENU MUSIC AND PLAYING THE GAME MUSIC
                    bg_player.pause()
                    game_player.play()

        # PLAYER 1 GAURDING
        if symbol == key.RALT and self.status.game_running:
            self.player2.gaurding = True

    def on_key_release(self, symbol, modifiers):

        # PLAYER 1 KEY RELEASE EVENTS
        if symbol == key.D:
            self.player1.right = False
        if symbol == key.A:
            self.player1.left = False
        if symbol == key.W:
            self.player1.up = False
        if symbol == key.S:
            self.player1.down = False
        if symbol == key.SPACE and self.status.game_running:
            if self.player1.fire_type == "auto":
                self.player1.fire = False
        if symbol == key.LSHIFT and self.status.game_running:
            self.player1.gaurding = False
        if symbol == key.G and self.status.game_running:
            self.player1.sp_fire = False

        # PLAYER 1=2 KEY RELEASE EVENTS
        if symbol == key.RIGHT:
            self.player2.right = False
        if symbol == key.LEFT:
            self.player2.left = False
        if symbol == key.UP:
            self.player2.up = False
        if symbol == key.DOWN:
            self.player2.down = False
        if symbol == key.P:
            if self.player2.fire_type == "auto":
                self.player2.fire = False
        if symbol == key.RALT and self.status.game_running:
            self.player2.gaurding = False

    def on_draw(self):
        self.clear()
        # SPACE BG DRAWING
        for space in self.space_list:
            space.draw()

        if time.time() - self.start_time < starting_screen_timeout + 1:
            draw_start_page(time.time() - self.start_time,
                            starting_screen_timeout)

        # GAME MENU DRAWINGS
        elif self.status.game_controls:
            self.cmenu.draw()
        elif self.status.game_about:
            self.amenu.draw()
        elif not self.status.game_running and not self.status.game_over and not self.status.game_selection:
            self.menu.draw()

        # SELECTION MENU DRAWINGS
        if self.status.game_selection:
            self.smenu.draw()
            if self.status.player1_selected:
                pyglet.text.Label("PLAYER 1 SELECTED " + p1_ship,
                                  font_name="Tempus Sans ITC",
                                  font_size=30,
                                  x=300,
                                  y=100,
                                  anchor_x="center",
                                  anchor_y="center",
                                  color=[200, 255, 255, 255],
                                  bold=True).draw()
            if self.status.player2_selected:
                pyglet.text.Label("PLAYER 2 SELECTED " + p2_ship,
                                  font_name="Tempus Sans ITC",
                                  font_size=30,
                                  x=1620,
                                  y=100,
                                  anchor_x="center",
                                  anchor_y="center",
                                  color=[200, 255, 255, 255],
                                  bold=True).draw()

        # DRAWINGS WHILE GAME IS RUNNING
        if self.status.game_running:
            # PLAYER LASER DRAWINGS
            for lsr in self.player1.laser_list:
                lsr.draw()
            for lsr in self.player2.laser_list:
                lsr.draw()

            # PLAYER DRAWINGS
            self.player1.draw(self.status.game_started)
            self.player2.draw(self.status.game_started)

            # PLAYER ENERGY SHIELD DRAWINGS
            if self.player1.gaurding and p1_gaurd_size[0] > 2:
                self.player1.draw_shield(self.player1.sprite.x - 40,
                                         self.player1.sprite.y - 40)
            if self.player2.gaurding and p2_gaurd_pos[0] + 1 < resolution[0]:
                self.player2.draw_shield(self.player2.sprite.x - 20,
                                         self.player2.sprite.y - 40)

            xy = draw_line(self.player1.sprite.x + self.player1.width,
                           self.player2.sprite.x,
                           self.player1.sprite.y + (self.player1.height / 2),
                           self.player2.sprite.y + (self.player2.height / 2))

            for splsr in self.player1.sp_laser_list:
                splsr.draw()

            # PLAYER EXPLOSION DRAWINGS
            for explosion in self.player1.exp_list:
                explosion.draw()
            for explosion in self.player2.exp_list:
                explosion.draw()

        # GAME OVER MENU DRAWINGS
        if self.status.game_over:
            self.menu.menu_bg.draw()
            pyglet.text.Label("GAME OVER",
                              font_name="Tempus Sans ITC",
                              font_size=resx(200),
                              x=resolution[0] / 2,
                              y=resy(resolution[1] / 2) + resy(400),
                              anchor_x="center",
                              anchor_y="center",
                              color=[255, 255, 255, 255],
                              bold=True).draw()
            pyglet.text.Label(winner + " WINS",
                              font_name="Tempus Sans ITC",
                              font_size=resx(100),
                              x=resolution[0] / 2,
                              y=(resolution[1] / 2),
                              anchor_x="center",
                              anchor_y="center",
                              color=[255, 255, 255, 255],
                              bold=True).draw()
            pyglet.text.Label("PRESS ENTER TO RELOAD",
                              font_name="Tempus Sans ITC",
                              font_size=resx(30),
                              x=resolution[0] / 2,
                              y=(resolution[1] / 2) - resy(500),
                              anchor_x="center",
                              anchor_y="center",
                              color=[255, 255, 255, 255],
                              bold=True).draw()

        # FPS LABEL DRAWING
        self.fps_display.draw()

    def update(self, dt):

        # UPDATE SPACE BG
        self.update_space(dt)

        # UPADTE DRAWINGS WHILE GAME  IS RUNNING
        if self.status.game_running and not self.status.game_paused:
            self.update_player(self.player1, p1_base, dt)
            self.update_player(self.player2, p2_base, dt)

            self.player_auto_fire(dt)
            self.update_player_laser(dt)

            self.update_explosion(self.player1)
            self.update_explosion(self.player2)

            self.update_special_laser()

    def update_space(self, dt):

        # FOR SCROLLING SPACE BG
        for space in self.space_list:
            space.update(dt)
            # CHECKING IF THE IMAGE HAS REACHED ITS END BY SCROLLING // IF TRUE THEN REMOVE THE IMAGE FROM THE LIST AND ADD NEW IMAGE ON TOP OF PREVIOUS
            if space.pos_y <= -1080:
                self.space_list.remove(space)
                self.space_list.append(
                    DisplayObjects(0, 1080, Sprite(self.space_img)))
            space.vel_y = -space_scroll_speed

    def update_player(self, player, player_base, dt):

        # PLAYER MOVEMENTS INSIDE PLAYER BASE
        if player.right and player.pos_x < player_base[1] - player.width:
            player.pos_x += player.speed * dt
        if player.left and player.pos_x > player_base[0]:
            player.pos_x -= player.speed * dt
        if player.up and player.pos_y < resolution[1] - player.height - 150:
            player.pos_y += player.speed * dt
        if player.down and player.pos_y > 0:
            player.pos_y -= player.speed * dt

        # PLAYER HP CHECKING AND UPDATING
        self.player1.hp.update(p1_hp_pos, p1_hp_size)
        self.player2.hp.update(p2_hp_pos, p2_hp_size)

        # PLAYER GAURD UPDATING
        self.update_gaurd()

        # PLAYER DAMAGE HP UPDATING
        self.update_dhp()

        # UPDATING PLAYER MOVEMENTS
        player.update(dt)

    def player_auto_fire(self, dt):
        # ADDING LASERS TO THE LASER LIST IIF THE FIRE TYPE IS AUTO
        if self.player1.fire and self.player1.fire_type == "auto":
            self.player1.fire_rate -= dt
            if self.player1.fire_rate <= 0:
                self.player1.laser_list.append(
                    Lasers(self.player1.pos_x + 96, self.player1.pos_y + 34,
                           [20, 5], p1_dhp_color))
                self.player1.laser_sound.play()
                self.player1.fire_rate += 1 - p1_fire_rate
        if self.player2.fire and self.player2.fire_type == "auto":
            self.player2.fire_rate -= dt
            if self.player2.fire_rate <= 0:
                self.player2.laser_list.append(
                    Lasers(self.player2.pos_x - 17, self.player2.pos_y + 34,
                           [20, 5], p2_hp_color))
                self.player2.laser_sound.play()
                self.player2.fire_rate += 1 - p2_fire_rate

    def update_player_laser(self, dt):
        global p2_hp_score, p1_hp_score
        sp = 15
        # UPDATING LASER POSITIONS OF PLAYER 1
        for lsr in self.player1.laser_list:
            lsr.update()
            lsr.pos_x += self.player1.laser_speed * dt
            if lsr.pos_x > lsr.initial_pos_x + self.player1.laser_range:
                self.player1.laser_list.remove(lsr)
            elif self.player2.pos_x + self.player2.width > lsr.pos_x + lsr.size[
                    0] > self.player2.pos_x + sp:
                if self.player2.pos_y < lsr.pos_y + lsr.size[
                        1] and lsr.pos_y < self.player2.pos_y + self.player2.height:
                    if not self.player2.gaurding or (
                            self.player2.gaurding
                            and p2_gaurd_pos[0] >= resolution[0]):
                        self.player1.laser_list.remove(lsr)
                        p2_hp_pos[0] += self.player2.damage_taken
                        self.check_game_status()
                        self.player1.exp_list.append(
                            SpriteAnimation(
                                explosion_img, [4, 5], [480, 384], 0.1,
                                [lsr.pos_x + lsr.size[0] - 48, lsr.pos_y - 48
                                 ]).get_sprite())
                        self.player1.exp_timer.append(explosion_time)
                        exp_sound.play()

        # UPDATING LASER POSITIONS OF PLAYER 2
        for lsr in self.player2.laser_list:
            lsr.update()
            lsr.pos_x -= self.player2.laser_speed * dt
            if lsr.pos_x < lsr.initial_pos_x - self.player2.laser_range:
                self.player2.laser_list.remove(lsr)
            elif self.player1.pos_x < lsr.pos_x < self.player1.pos_x + self.player1.width - sp:
                if self.player1.pos_y < lsr.pos_y < self.player1.pos_y + self.player1.height:
                    if not self.player1.gaurding or (self.player1.gaurding and
                                                     p1_gaurd_size[0] <= 0):
                        self.player2.laser_list.remove(lsr)
                        p1_hp_size[0] -= self.player1.damage_taken
                        self.check_game_status()
                        self.player2.exp_list.append(
                            SpriteAnimation(
                                explosion_img, [4, 5], [480, 384], 0.1,
                                [lsr.pos_x + lsr.size[0] - 48, lsr.pos_y - 48
                                 ]).get_sprite())
                        self.player2.exp_timer.append(explosion_time)
                        exp_sound.play()

    def update_explosion(self, player):
        exploded = False
        for i in range(len(player.exp_timer)):
            player.exp_timer[i] -= 1
            if player.exp_timer[i] <= 0:
                exploded = True
        if exploded:
            player.exp_list.pop(0)
            player.exp_timer.pop(0)

    def update_gaurd(self):
        global p1_gaurd_size, p2_gaurd_size
        # UPADTING GAURD
        self.player1.gaurd.update(p1_gaurd_pos, p1_gaurd_size)
        self.player2.gaurd.update(p2_gaurd_pos, p2_gaurd_size)
        # CHECKING IF PLAYER IS GUARDING // IF TRUE DEPLETE THE GAURD QUAD // ELSE REPLENISH THE GAURD QUAD
        if self.player1.gaurding and p1_gaurd_size[0] > 0:
            p1_gaurd_size[0] -= p1_guard_consumption_rate
        elif p1_gaurd_size[0] < p1_total_gaurd:
            p1_gaurd_size[0] += self.player1.gaurd_regen_rate
        if self.player2.gaurding and p2_gaurd_pos[0] < resolution[0]:
            p2_gaurd_pos[0] += p2_guard_consumption_rate
        elif p2_gaurd_pos[0] > resolution[0] - p2_total_gaurd:
            p2_gaurd_pos[0] -= self.player2.gaurd_regen_rate

    def check_game_status(self):
        global winner, explosion_time
        # CHECKING IF ANY PLAYER HAS WON THE GAME

        if p1_hp_size[0] <= 0:
            self.status.game_running = False
            self.status.game_over = True
            winner = "PLAYER 2"
            self.player1.lost = True
            explosion_time = 25
        if p2_hp_pos[0] >= resolution[0]:
            self.status.game_running = False
            self.status.game_over = True
            winner = "PLAYER 1"
            self.player2.lost = True
            explosion_time = 25

    def reload(self):
        global winner, p1_hp_pos, p1_total_life, p1_hp_size, p1_hp_score, p2_hp_pos, \
            p2_hp_size, p2_total_life, p2_hp_score, explosion_time, p1_gaurd_size, p2_gaurd_pos, p1_dhp_pos, p1_dhp_size, p2_dhp_pos, p2_dhp_size

        # GAME DETAILS
        winner = None

        # PLAYER 1 DETAILS
        p1_total_life = resx(550)
        p1_hp_pos = [0, resy(1000)]
        p1_hp_size = [p1_total_life, resy(20)]
        p1_hp_score = 0
        p1_gaurd_size = [p1_total_gaurd, resy(20)]
        p1_dhp_pos = p1_hp_pos.copy()
        p1_dhp_size = p1_hp_size.copy()

        # PLAYER 2 DETAILS
        p2_total_life = resx(550)
        p2_hp_pos = [resolution[0] - p2_total_life, resy(1000)]
        p2_hp_size = [p2_total_life, resy(20)]
        p2_hp_score = 0
        p2_gaurd_pos = [resolution[0] - p2_total_gaurd, resy(970)]
        p2_dhp_pos = p2_hp_pos.copy()
        p2_dhp_size = p2_hp_size.copy()

        # OTHER DETAILS
        explosion_time = 15  # in ms

        self.status = GameStatus()
        self.menu = GameMenu(resolution, self.status.game_menu_text)
        self.smenu = SelectionMenu(resolution, self.status.game_selection_text)

        # PLAYER INITIALIZATIONS
        self.player1 = DisplayPlayers(p1_pos_x, p1_pos_y, p1_fire_type)

        self.player2 = DisplayPlayers(p2_pos_x, p2_pos_y, p2_fire_type)

        # self.player1.laser_sound.play()
        self.player1.hp = Quad(p1_hp_pos, p1_hp_size, p1_hp_color, 'p1')
        self.player2.hp = Quad(p2_hp_pos, p2_hp_size, p2_hp_color, 'p2')

        self.player1.dhp = Quad(p1_dhp_pos, p1_dhp_size, p1_dhp_color, 'p1')
        self.player2.dhp = Quad(p2_dhp_pos, p2_dhp_size, p2_dhp_color, 'p2')

        self.player1.gaurd = Quad(p1_gaurd_pos, p1_gaurd_size, p1_gaurd_color,
                                  'p1')
        self.player2.gaurd = Quad(p2_gaurd_pos, p2_gaurd_size, p2_gaurd_color,
                                  'p2')

        self.menu = GameMenu(resolution, self.status.game_menu_text)

    def update_dhp(self):
        global p1_dhp_size, p2_dhp_pos
        self.player1.dhp.update(p1_dhp_pos, p1_dhp_size)
        self.player2.dhp.update(p2_dhp_pos, p2_dhp_size)

        if p1_hp_size[0] < p1_dhp_size[0]:
            p1_dhp_size[0] -= 1.5
        if p2_hp_pos[0] > p2_dhp_pos[0]:
            p2_dhp_pos[0] += 1.5

    def track_enemy(self, obj, dest_pos, speed=5):
        x = dest_pos[0] - obj.pos_x
        y = dest_pos[1] - obj.pos_y
        hyp = sqrt((x * x) + (y * y))
        if hyp != 0:
            x /= hyp
            y /= hyp
            obj.pos_x += x * speed
            obj.pos_y += y * speed
            obj.update()

    def update_special_laser(self):
        global p2_hp_score, p1_hp_score
        for splsr in self.player1.sp_laser_list:
            self.track_enemy(splsr,
                             [self.player2.sprite.x, self.player2.sprite.y])
            if self.player2.pos_x + self.player2.width > splsr.pos_x + splsr.size[
                    0] > self.player2.pos_x:
                if self.player2.pos_y < splsr.pos_y + splsr.size[
                        1] and splsr.pos_y < self.player2.pos_y + self.player2.height:
                    if not self.player2.gaurding or (
                            self.player2.gaurding
                            and p2_gaurd_pos[0] >= resolution[0]):
                        self.player1.sp_laser_list.remove(splsr)
                        p2_hp_pos[0] += self.player2.sp_damage_taken
                        self.check_game_status()
                        self.player1.exp_list.append(
                            SpriteAnimation(
                                explosion_img, [4, 5], [480, 384], 0.1, [
                                    splsr.pos_x + splsr.size[0] - 48,
                                    splsr.pos_y - 48
                                ]).get_sprite())
                        self.player1.exp_timer.append(explosion_time)
                        exp_sound.play()
                    else:
                        self.player1.sp_laser_list.remove(splsr)
Ejemplo n.º 23
0
class MyVM(pyglet.window.Window):  #
    def __init__(self, *args, **kwargs):  # constructor
        super().__init__(*args, **kwargs)  # runs constructor from inherited method
        self.set_location(100, 100)
        self.frame_rate = 1 / 160.0  # number of target fps
        self.background_batch = pyglet.graphics.Batch()
        self.character_batch = pyglet.graphics.Batch()
        self.textbox_batch = pyglet.graphics.Batch()
        self.darkness_batch = pyglet.graphics.Batch()
        self.choice_batch = pyglet.graphics.Batch()  # batches from which graphics are going to be drawn
        self.fps_display = FPSDisplay(self)  # display FPS
        self.fps_display.label.y = self.height - 10
        self.fps_display.label.x = 0
        self.fps_display.label.font_size = 10  # position of FPS counter
        self.story_number = 0  # line number from which story CSV should be read
        self.progress_story = True  # status if story should progress or wait for interaction
        self.characters_table = dict()  # dictionary with all characters
        self.wait_animation = False
        # pyglet.font.add_directory("res/font/")
        # pyglet.font.load('Noto Sans') # set custom font (usefull for windows)

        self.box = TextBox(self.width, "", "", 2, self.textbox_batch)  # Prepares textbox used later
        self.box.set_opacity(0)  # hides textbox since in begining we show "main menu"
        self.choice = ChoiceBox(self.height, self.width, "", "", self.choice_batch)  # Prepares choice boxes
        self.choice.set_opacity(0)  # and hides them
        self.story_board = []  # Creates array for story
        with open("res/story/sb.csv", encoding="utf-8") as fh:  # Puts into array story board
            rd = csv.DictReader(fh, delimiter="|")
            for row in rd:
                self.story_board.append(row)
        del fh

        # creates black box to cover screen when needed
        color = (0, 0, 0, 255)
        self.image_pattern = pyglet.image.SolidColorImagePattern(color=color)
        self.image = self.image_pattern.create_image(self.width, self.height)
        self.darkness = GameObject(0, 0, Sprite(self.image, batch=self.darkness_batch))
        self.darkness.set_opacity(0)

        # creates object with initial main menu background
        self.mmBackground = GameObject(0, 0, "bg/mm.jpg", batch=self.background_batch)

    def on_key_press(self, symbol, modifiers):  # overrides actions on key press
        if symbol == key.NUM_1 or symbol == key._1:  # if number 1
            if self.choice.waiting_choice:  # Checks if its waiting for input
                self.choice.waiting_choice = False  # sets its no longer waiting for input
                self.progress_story = True  # sets flag fro story to progress
                self.story_number = int(self.story_board[self.story_number]["set1"])  # jumps to index of chosen choice
                self.choice.set_opacity(0)  # sets choice boxes as invincible
        if symbol == key.NUM_2 or symbol == key._2:  # if number 2 does the same as 1
            if self.choice.waiting_choice:
                self.choice.waiting_choice = False
                self.progress_story = True
                self.story_number = int(self.story_board[self.story_number]["set2"])
                self.choice.set_opacity(0)
        if symbol == key.SPACE:  # if space
            if not self.choice.waiting_choice and not self.wait_animation:  # check if its not waiting for choice
                if self.box.ready:  # checks if text writing has ended
                    self.box.ready = False  # sets flag for text writing
                    self.story_number += 1  # adds one to story index
                    self.progress_story = True  # sets for story to continue
                else:
                    self.box.skip_write()  # invokes skipping of writing and prints out everything
        if symbol == key.ESCAPE:  # if escape
            pyglet.app.exit()  # quits
        pass

    def on_key_release(self, symbol, modifiers):  # nie używane
        pass

    def on_draw(self):  # how to draw, also sets priority of layers
        self.clear()  # cleans screen
        self.background_batch.draw()  # draws background
        self.character_batch.draw()  # draws characters
        self.textbox_batch.draw()  # draws textbox
        self.choice_batch.draw()  # draws choices box
        self.darkness_batch.draw()  # draws darkness
        self.fps_display.draw()  # draw FPS counter

    def update(self, dt):
        self.update_story()  # runs update_story function
        self.box.update(dt)  # runs text box update with time (so the writing speed is relatively consistent)
        self.darkness.update(dt)  # runs darkness layer update with time (so alpha change is relatively consistent)
        if self.darkness.set_ok:  # is darkness finishes alpha change to desired state allows story to progress
            self.darkness.set_ok = False
            self.progress_story = True
            self.wait_animation = False
        for character in self.characters_table:
            self.characters_table[character].update(dt)  # updates characters animation with time (so it moves smoothly)
            if self.characters_table[character].set_ok:  # if characters animation finishes allows story to progress
                self.characters_table[character].set_ok = False
                self.progress_story = True
                self.wait_animation = False

    def update_story(self):  # story progress
        if self.progress_story:  # check if story should progress
            if self.story_number == -1:  # checks if story number isn't -1
                pyglet.app.exit()  # exists game
            current = self.story_board[self.story_number]  # writes what actions are going to happened
            self.progress_story = False  # sets flag

            if int(current['action']) == 0:  # text action
                self.box.set_opacity(255)  # shows textbox
                self.box.change_speaker(current["person"])  # sets person speaking
                self.box.change_text(current["text"], current["value1"])  # sets text
            elif int(current['action']) == 1:  # choice
                self.choice.set_opacity(255)  # shows choice boxes
                self.choice.change_text(current["value1"], current["value2"])  # sets text in them
            elif int(current['action']) == 2:  # just jump
                self.story_number = int(current["value1"])
                self.progress_story = True
            elif int(current['action']) == 3:  # create character
                self.characters_table[current["person"]] = GameObject(
                    int(current["value2"]), 210, f"char/{current['value1']}", self.character_batch)
                self.story_number += 1
                self.progress_story = True
            elif int(current['action']) == 4:  # move character
                self.characters_table[current["person"]].animate_x(int(current["value1"]))
                self.story_number += 1
                self.wait_animation = True
            elif int(current['action']) == 5:  # remove character
                del self.characters_table[current["person"]]
                self.story_number += 1
                self.progress_story = True
            elif int(current['action']) == 6:  # change background
                self.mmBackground.replace_bg(current['value1'])
                self.story_number += 1
                self.progress_story = True
            elif int(current['action']) == 7:  # screen dimming
                self.story_number += 1
                self.wait_animation = True
                if int(current['value1']) == 0:
                    self.darkness.animate_opacity(0)
                elif int(current['value1']) == 1:
                    self.darkness.animate_opacity(255)
            elif int(current['action']) == 8:  # play sound
                sound = pyglet.resource.media(f"res/sfx/{current['value1']}", streaming=False)
                sound.play()
                self.story_number += 1
                self.progress_story = True
            elif int(current['action']) == 9:  # hide text box
                self.box.set_opacity(0)
                self.story_number += 1
                self.progress_story = True
Ejemplo n.º 24
0
class GameWindow(pyglet.window.Window):
    """
    """
    def __init__(self, warpmap, dt_for_physicx, space, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # set window location
        position = Vec2d(300, 50)
        self.set_location(position.x, position.y)
        self.warpmap = warpmap
        self.dt_for_physicx = dt_for_physicx
        self.remain_time_for_updating_physicx = dt_for_physicx
        self.space = space
        # framerate display
        self.fps = FPSDisplay(self)

        ########################################################################
        # self.record_filename = f"/tmp/warp#{4}hz#{self.warpmap.w}#{self.warpmap.h}#{self.warpmap.size}.pkl"
        ########################################################################

    def on_draw(self):
        self.clear()

        ########################################################################
        # Record (dump pickle in file) Warp grid (animation)
        # # 4 Hz
        # if not self.fps.count:
        #     with open(self.record_filename, "ab") as tmp_warp_file:
        #         pickle.dump(self.warpmap.get_web_crossings(), tmp_warp_file)
        ########################################################################

        self.warpmap.draw_debug(draw_flag=True, draw_web_constraints=True)

        self.fps.draw()

    def on_key_press(self, symbol, modifiers):
        if symbol == key.ESCAPE:
            self.quit_game()

    def on_key_release(self, symbol, modifiers):
        pass

    def on_mouse_press(self, x, y, button, modifiers):
        mouse_body.position = x, y
        hit = self.space.point_query_nearest((x, y), 10, pymunk.ShapeFilter())
        if hit is not None:
            global selected
            body = hit.shape.body
            rest_length = mouse_body.position.get_distance(body.position)
            stiffness = 1000
            damping = 10
            selected = pymunk.DampedSpring(mouse_body, body, (0, 0), (0, 0),
                                           rest_length, stiffness, damping)
            self.space.add(selected)

    def on_mouse_release(self, x, y, button, modifiers):
        global selected
        if selected is not None:
            self.space.remove(selected)
            selected = None

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        mouse_body.position = x, y

    def update(self, dt):
        """

        :param dt:
        :return:

        """
        # dt: deltatime from display
        self.remain_time_for_updating_physicx -= dt

        while self.remain_time_for_updating_physicx < 0.0:
            self.warpmap.relax(self.dt_for_physicx)
            self.remain_time_for_updating_physicx += self.dt_for_physicx

    def quit_game(self):
        # http://nullege.com/codes/search/pyglet.app.exit
        pyglet.app.exit()
Ejemplo n.º 25
0
class GameWindowAI(Window):
    def __init__(self):
        super().__init__()
        self.set_size(Const.WIDTH, Const.HEIGHT)
        self.set_caption('Floppy Bird')

        self.score = 0

        self.population = Population(self)
        self.tubes = [Tube()]
        self.background = Sprite(img=Images.BACKGROUND_IMG)
        self.land = Land()

        self.score_label = Label(text=f'Score: {self.score}',
                                 x=Const.WIDTH - 10,
                                 y=Const.HEIGHT - 20,
                                 anchor_x='right',
                                 bold=True)
        self.fps_display = FPSDisplay(self)
        self.fps_display.label.font_size = 12
        self.fps_display.label.color = (0, 255, 0, 255)
        self.fps_display.label.bold = False

        pyglet.clock.schedule_interval(self.on_timer, Const.FRAME_RATE)

    def on_draw(self):
        self.clear()
        self.background.draw()
        for tube in self.tubes:
            tube.draw()
        self.land.draw()
        self.population.draw()
        self.score_label.draw()
        self.fps_display.draw()

    def on_timer(self, dt):
        self.produce_remove_tubes()
        self.population.check_collisions()
        self.population.animate(dt)

        for tube in self.tubes:
            tube.animate(dt)
        self.update_score()

    def update_score(self):
        tube = self.get_closest_tube()

        if Const.BIRD_X > tube.center and not tube.crossed and not self.population.is_done:
            self.score += 1
            self.score_label.text = f'Score: {self.score}'
            tube.crossed = True

    def produce_remove_tubes(self):
        tube = self.tubes[0]
        if tube.half_crossed:
            tube = self.tubes[1]
        if tube.bbox[0][0] < Const.WIDTH / 2 and not tube.half_crossed:
            tube.half_crossed = True
            tube = Tube()
            tube.draw()
            self.tubes.append(tube)

        for tube in self.tubes:
            if tube.bottom_head.x + tube.bottom_head.width < 0:
                self.tubes.remove(tube)

    def get_closest_tube(self):
        for tube in self.tubes:
            if tube.bbox[1][2] > 100:
                return tube

    def replay(self):
        self.tubes = [Tube()]
        self.score = 0
        self.score_label.text = f'Score: {self.score}'
Ejemplo n.º 26
0
class Game:
    def __init__(self, window, keys):
        """
        window: the window for the game to be run in
        keys: <pyglet.window.key.KeyStateHandler> object that handles keys
        """
        self.window = window

        self.keys = keys
        self.mouse_position = Vector2D()

        self.options = Options()
        self.show_fps = True
        self.fps_clock = FPSDisplay(self.window)

        self.player1 = Paddle(self.window, self.keys, 0)
        self.player2 = Paddle(self.window, self.keys, 1)
        self.players = self.player1, self.player2

        self.puck = Puck(self.window)

        self.is_paused = False
        self.is_running = False

        self.menus = {}
        self.last_menu = None
        self.visible_menu = "main_menu"
        self.current_save = None

        self.current_page = 0
        self.load_menu_pages = {}

        self.varsets = {
            "P1COLOR": self.player1.color,
            "P2COLOR": self.player2.color,
            "PUCKCOLOR": self.puck.color
        }
        self.functions = {
            "toggle_fullscreen": self.toggle_fullscreen,
            "toggle_show_fps": self.toggle_show_fps,
            "goto_mainmenu": self.goto_mainmenu,
            "goto_loadmenu": self.goto_loadmenu,
            "goto_options": self.goto_options,
            "unpause_game": self.unpause_game,
            "reset_game": self.full_reset,
            "start_game": self.start_game,
            "pause_game": self.pause_game,
            "load_game": self.load_game,
            "save_game": self.save_game,
            "exit_game": self.exit_game,
            "delete": self.delete_save,
            "go_back": self.go_back
        }

        self.load_menus()

    def _cleanup(self):
        """
        clear some files before closing, so no temp data carries over from one game instance to another
        """
        open("./resources/.temp_options.yaml", "w+").close()
        open("./resources/.temp.yaml", "w+").close()

    def _init_temp_options(self):
        """
        Preps the file that stores unsaved options for writing
        """
        with open("./resources/.temp_options.yaml", "w") as file_:
            file_.write(dump_yaml({"options": Options()}))

    def _print_menu_data(self):
        """
        pprints the data for all the menus
        """
        for filename in listdir("./menus"):
            with open("./menus/" + filename, "r") as file_:
                if "load" in filename: continue
                yaml_data = load_yaml(file_)["menu"]
                print("\nYaml data for file %s" % filename)
                pprint(yaml_data)

    def apply_options(self):
        """
        Applies options from either the save or the temp game options file
        """
        options_menu = self.menus["options"]
        # Sets the options variable to a new Options instance
        self.options = Options(player1_color=options_menu.get_element_by_id(
            "player1_color").get_color(),
                               player2_color=options_menu.get_element_by_id(
                                   "player2_color").get_color(),
                               puck_color=options_menu.get_element_by_id(
                                   "puck_color").get_color(),
                               difficulty=options_menu.get_element_by_id(
                                   "difficulty", "slider").get_value(),
                               is_fullscreen=self.window.fullscreen)
        # Applies the new options
        self.options.apply_settings(self)
        with open("./resources/.temp_options.yaml", "w") as file_:
            # Writes the new options to the temp file
            file_.write(dump_yaml({"options": self.options}))

    def full_reset(self):
        """
        resets the game entirely (scores and positions)
        """
        self.puck.reset()
        for player in self.players:
            player.reset()
            player.score = 0
        if self.is_paused:
            self.unpause_game()

    def mouse_drag(self, x, y, dx, dy, button, mod):
        """
        called when a user drags the mouse with `button` held, passes the event to the menus
        """
        # If there is a menu
        if self.visible_menu:
            # pass if the menu is the loading menu, no sliders
            if self.visible_menu == "load_menu": return 0
            # pass the event to the current menu
            menu = self.menus[self.visible_menu]
            menu.mouse_drag(x, y, dx, dy, button, mod)

    def mouse_pressed(self, x, y, button, mod):
        """
        called when a user clicks on the screen, passes the event to the menus / pages (which are still menus)
        """
        # If there is a current menu, (the game is not running)
        if self.visible_menu:
            # If the current menu is not the loading menu, pass the menu the mouse_pressed event
            if not self.visible_menu == "load_menu":
                menu = self.menus[self.visible_menu]
                menu.mouse_pressed(x, y, button, mod)
            # If the current menu is the loading menu, pass the current page the mouse_pressed event
            else:
                page = self.load_menu_pages[self.current_page]
                page.mouse_pressed(x, y, button, mod)

    def reset(self):
        """
        resets the puck, players' positions
        """
        self.puck.reset()
        [player.reset() for player in self.players]

    def setup(self):
        favicon = load("./resources/favicon.png")
        self.window.set_icon(favicon)
        self.window.set_caption("Pong v1.4")
        self._init_temp_options()
        self.full_reset()

        from os import mkdir
        from os.path import exists
        if not exists("./saves"):
            mkdir("./saves")

    def start_game(self):
        """
        starts the game
        """
        # unpause the game, tell the program the game is running, set the last, current menus, fully reset the game
        self.is_paused = False
        self.is_running = True
        self.last_menu = self.visible_menu
        self.visible_menu = None
        self.full_reset()

    def toggle_show_fps(self, set_=None):
        """
        switches on/of the fps display
        """
        # if no set is given, it toggles
        if set_ == None:
            self.show_fps = not self.show_fps
        # otherwise, if it's a bool or int (True, False; 1, 0), it sets it to the given value
        else:
            assert isinstance(set_, (bool, int)), "set_ must be bool or int"
            self.show_fps = set_

    def go_back(self):
        """
        goes to the previous menu
        """
        # If the menu we're leaving is the options, apply the options
        if self.visible_menu == "options": self.apply_options()
        # go back to the last menu
        self.visible_menu = self.last_menu

    def goto_load_menu_page(self, page_number):
        """
        goes to the page number `page_number`
        """
        # if the page number is -1, go back
        if page_number == -1: self.go_back()
        # if the page number is not in the pages dictionary, raise an error
        if not page_number in self.load_menu_pages.keys():
            raise ValueError("page_number incorrect")
        # set the current page to the new one
        self.current_page = page_number

    def goto_mainmenu(self):
        """
        goes to the main menu
        """
        # pause the game, stop the game, tell the program we aren't playing a game, set the last, current menu vars
        self.is_paused = False
        self.is_running = False
        self.current_save = None
        self.last_menu = self.visible_menu
        self.visible_menu = "main_menu"

    def goto_loadmenu(self):
        """
        goes to the loading menu
        """
        # tell the player if there are no saves in the "./saves/" directory
        if len(listdir("./saves")) == 0:
            print("No saves")
            return 0
        # build the menus
        self.build_load_menus()
        # so we can go back lmaoooo
        if not self.last_menu == self.visible_menu:
            # only set the last menu if it's different
            self.last_menu = self.visible_menu
        self.visible_menu = "load_menu"

    def goto_options(self):
        """
        goes to the options menu
        """
        # pause the game
        self.is_paused = False
        # if the temp options file is empty, initialise the file
        if open("./resources/.temp_options.yaml").read() == '':
            self._init_temp_options()
        # load the options from the temp file or the current save file
        self.load_options()
        # set the last menu
        self.last_menu = self.visible_menu
        self.visible_menu = "options"

    def unpause_game(self):
        """
        unpauses the game / returns to the game from the pause menu
        """
        # tell the game we're playing, unpause, set the last menu
        self.is_running = True
        self.is_paused = False
        self.last_menu = self.visible_menu
        self.visible_menu = None

    def pause_game(self):
        """
        pauses the game / goes to the pause menu
        """
        # tell the game we're not playing, pause the game, set the last menu
        self.is_running = False
        self.is_paused = True
        self.last_menu = self.visible_menu
        self.visible_menu = "pause"

    def toggle_fullscreen(self):
        """
        toggles the fullscreen-ness of the game, obviously
        """
        # save the current options to the temp options file
        self.apply_options()

        # open the temporary file for the player, puck positions
        with open("./resources/.temp.yaml", "w") as file_:
            file_.write(
                dump_yaml({
                    # correct height for the players
                    "player1":
                    self.player1.pos.y / self.window.height,
                    "player2":
                    self.player2.pos.y / self.window.height,
                    # rationalise the position
                    "puck":
                    Vector2D(x=self.puck.pos.x / self.window.width,
                             y=self.puck.pos.y / self.window.height)
                }))
        # toggle the window's fullscreen attribute
        self.window.set_fullscreen(not self.window.fullscreen)
        # reload the menus
        self.load_menus()
        # reload the options
        self.load_options()
        # reset the players (fix the x pos)
        [player.reset() for player in self.players]

        # open the puck, player temp file
        with open("./resources/.temp.yaml", "r") as file_:
            # load the data from yaml
            yaml_data = load_yaml(file_.read())
            # set the player1, 2 y positions / derationalise them
            self.player1.pos.y = yaml_data["player1"] * self.window.height
            self.player2.pos.y = yaml_data["player2"] * self.window.height

            # set the puck pos, derationalise
            self.puck.pos = yaml_data["puck"] * (self.window.width,
                                                 self.window.height)

    def exit_game(self):
        """
        exits the game, performs cleanup
        """
        print("Exiting")
        # close the window
        self.window.close()
        # cleanup
        self._cleanup()
        # exit the program
        sysexit(0)

    def load_options(self):
        """
        Loads either the temp options or the options from the current save
        """
        # get the path for the file, either the temp options file or the current save
        filename = "./resources/.temp_options.yaml" if not self.current_save else f"./saves/{self.current_save}"

        # open the file
        with open(filename, "r") as file_:
            # load the data from yaml
            yaml_data = load_yaml(file_.read())
            # assertions
            try:
                assert isinstance(yaml_data, dict)
                assert "options" in yaml_data.keys()
            except AssertionError:
                raise ImportError("Save file corrupted")
            # set the games options to the loaded options
            self.options = yaml_data["options"]

        # commit the options
        self.options.set_options(self.menus["options"])

    def draw_current_menu(self):
        """
        draws the current menu, obviously
        If the current menu is the loading menu, it draws the current page in that menu
        """
        # if we have a menu up
        if self.visible_menu:
            # if the menu is the loading menu
            if self.visible_menu == "load_menu":
                # draw the current page, check the hovering for the buttons
                page = self.load_menu_pages[self.current_page]
                page.draw()
                for button in page.buttons:
                    if button.contains(self.mouse_position):
                        button.on_hover()
            # otherwise, draw the current menu, pass the mouse pos for hovering
            else:
                # print(self.visible_menu)
                menu = self.menus[self.visible_menu]
                menu.draw()
                for button in menu.buttons:
                    if button.contains(self.mouse_position):
                        button.on_hover()

    def mainloop(self, dt):
        """
        the main gameloop
        draws all the stuff, updates all the stuff
        """
        self.window.clear()

        if self.show_fps:
            self.fps_clock.draw()

        # if the game is running
        if self.is_running:
            # pause the game if the player hits P
            if self.keys[P]:
                self.pause_game()
                self.load_menus()

            # motion, collision, drawing
            self.handle_motion()
            self.handle_collision()
            self.keep_in_bounds()
            self.puck.draw()
            self.puck.update()
            self.draw_scores()
            [player.draw() for player in self.players]
        # if the game is not running and not paused
        elif not self.is_paused:
            # draw the current menu
            self.draw_current_menu()

        # if the game is paused
        if self.is_paused:
            # draw the background, the current menu
            self.puck.draw()
            self.draw_scores()
            [player.draw() for player in self.players]
            self.draw_current_menu()
        # force the game to pause if the current menu is pause
        if self.visible_menu == "pause":
            self.is_paused = True
            # and vice versa
        else:
            self.is_paused = False

    def handle_motion(self):
        """
        handles the controls (moving each player up when they should)
        """
        # player 1 controls - W = UP, S = DOWN
        if self.keys[W]: self.player1.move(10)
        if self.keys[S]: self.player1.move(-10)
        # player 2 controls - UP = UP, DOWN = DOWN
        if self.keys[UP]: self.player2.move(10)
        if self.keys[DOWN]: self.player2.move(-10)

    def handle_collision(self):
        """
        handles the collision between the players and the puck
        kinda bad but its okish
        """
        for player in self.players:
            # this is a fitting comment
            # i wrote this collision algorithm legit like 4 months ago and I don't remember how so I keep reusing it lmao
            if ((self.puck.pos.y - self.puck.h // 2 > player.pos.y -
                 player.h // 2 and self.puck.pos.y + self.puck.h // 2 <
                 player.pos.y + player.h // 2)
                    and not (self.puck.pos.x + self.puck.w // 2 <
                             player.pos.x - player.w // 2 or self.puck.pos.x -
                             self.puck.w // 2 > player.pos.x + player.w // 2)):
                self.puck.vel.x *= -1

    def keep_in_bounds(self):
        """
        handles puck collision with the floor, cieling; handles scoring
        """
        for player in self.players:
            # if it goes too low, reset it to the lowest it'll go
            if player.pos.y < player.h // 2:
                player.pos.y = player.h // 2
            # if it goes too high, reset it to the highest it'll go
            if player.pos.y > self.window.height - player.h // 2:
                player.pos.y = self.window.height - player.h // 2
        # make the puck bounce if it hits the roof or floor
        if (self.puck.pos.y < self.puck.h // 2
                or self.puck.pos.y > self.window.height - self.puck.h // 2):
            self.puck.vel.y *= -1
        # if it goes off to the left, increment player2's score and reset the puck
        if self.puck.pos.x < 0:
            self.reset()
            self.player2.score += 1
        # if it goes off to the right, increment player1's score and reset the puck
        if self.puck.pos.x > self.window.width:
            self.reset()
            self.player1.score += 1

    def draw_scores(self):
        """
        draws each player's score where it should
        """
        # player1 score
        Label(text=str(self.player1.score),
              x=4,
              y=self.window.height - 40,
              font_name="helvetica",
              font_size=36).draw()
        # var to store the position the label needs to be drawn at
        # stays accurate enough till like 100000 ish
        LABEL_X_POS = self.window.width - len(list(str(
            self.player2.score))) * 30
        # player2 score
        Label(text=str(self.player2.score),
              x=LABEL_X_POS,
              y=self.window.height - 40,
              font_name="helvetica",
              font_size=36).draw()

    def load_menus(self):
        """
        loads all the menus from the ./menus/ directory into python objects I can work with
        """
        def get_slider_data(slider):
            """
            returns a tuple that contains all the data in the correct format to create a Slider object with
            """
            # these functions are just really dirty and looked gross to do 20 times so i made them functions
            x, y = slider["x"] * self.window.width, slider[
                "y"] * self.window.height
            w, h = slider["w"] * self.window.width, slider[
                "h"] * self.window.height
            min_, max_ = slider["min"], slider["max"]
            id_ = slider["id"]
            color = [int(num) for num in slider["color"].split(",")]
            return (x, y, w, h, min_, max_, color, id_)

        def get_button_data(button):
            """
            returns a tuple that contains all the data in the correct format to create a Button object with
            """
            x, y = button["x"] * self.window.width, button[
                "y"] * self.window.height
            w, h = button["w"] * self.window.width, button[
                "h"] * self.window.height
            text = button["text"]
            id_ = button["id"]
            function = self.functions[button["function"]]
            color = [int(num) for num in button["color"].split(",")]
            return (x, y, w, h, text, function, id_, color)

        # iterate through each file in the "./menus/" directory
        for filename in listdir("./menus"):
            # open the file
            with open("./menus/" + filename, "r") as file_:
                # load the yaml data
                yaml_data = load_yaml(file_)["menu"]
                # the name of the menu
                menu_name = yaml_data["name"]
                # initialise the menu, buttons, sliders, rgbsliders
                menu = Menu()
                buttons = None
                sliders = None
                rgbsliders = None

                # set vars if they exist
                if "buttons" in yaml_data.keys():
                    buttons = yaml_data["buttons"]
                if "sliders" in yaml_data.keys():
                    sliders = yaml_data["sliders"]
                if "rgbsliders" in yaml_data.keys():
                    rgbsliders = yaml_data["rgbsliders"]

                # if the menu has buttons, make a Button object and add it to the menu
                if buttons:
                    for key in buttons.keys():
                        button = buttons[key]
                        data = get_button_data(button)
                        multiline = button[
                            "multiline"] if "multiline" in buttons.keys(
                            ) else False
                        menu.add_button(MenuButton(*data, multiline=multiline))

                # if the menu has sliders, make a Slider object and add it to the menu
                if sliders:
                    for key in sliders.keys():
                        slider = sliders[key]
                        data = get_slider_data(slider)
                        menu.add_slider(Slider(*data))

                # if the menu has rgbsliders, make an RGBSlider object and add it to the menu
                if rgbsliders:
                    for key in rgbsliders.keys():
                        rgbslider = rgbsliders[key]
                        varset = self.varsets[rgbslider["VARSET"]]
                        RSLIDER = Slider(*get_slider_data(rgbslider["R"]))
                        GSLIDER = Slider(*get_slider_data(rgbslider["G"]))
                        BSLIDER = Slider(*get_slider_data(rgbslider["B"]))
                        id_ = rgbslider["id"]
                        win = rgbslider["window"]
                        window = Rect(win["x"] * self.window.width,
                                      win["y"] * self.window.height,
                                      win["w"] * self.window.height,
                                      win["h"] * self.window.height)
                        LABEL = rgbslider["label"]
                        label = Label(text=LABEL["text"],
                                      x=LABEL["x"] * self.window.width,
                                      y=LABEL["y"] * self.window.height,
                                      anchor_x="center")
                        menu.add_rgbslider(
                            RGBSlider(RSLIDER, GSLIDER, BSLIDER, window, label,
                                      varset, id_))

                # add the menu to the menus dictionary with the key `menu_name`
                self.menus[menu_name] = menu

    def delete_save(self, filename):
        """
        deletes the save
        """
        # delete the save file
        rm("./saves/" + filename)
        # if we don't have any saves, go back
        if len(listdir("./saves")) == 0:
            self.go_back()
            print("No saves")
        # if we clear a page, go to the previous page
        elif len(listdir("./saves")) % 5 == 0:
            self.build_load_menus()
            self.goto_load_menu_page(self.current_page - 1)
        # otherwise, refresh the menu
        else:
            self.build_load_menus()

    def save_game(self):
        """
        saves the game to a file in the ./saves/ directory
        files are named DDMMYY-HR_MIN_SEC.yaml (24 hours for the HR)
        """
        # Generate the save filename from the date / time
        filename = "./saves/" + strftime("%d%m%y-%H_%M_%S") + ".yaml"
        # generate the data to save from the data the game has about the current game :)
        save_data = {
            "puck": {
                "pos": self.puck.pos,
                "vel": self.puck.vel,
                "color": self.puck.color
            },
            "player1": {
                "pos": self.player1.pos,
                "score": self.player1.score,
                "color": self.player1.color
            },
            "player2": {
                "pos": self.player2.pos,
                "score": self.player2.score,
                "color": self.player2.color
            },
            "fullscreen": self.window.fullscreen,
            "show_fps": self.show_fps,
            "options": self.options
        }
        # Save the data to the generated file
        with open(filename, "w") as file_:
            file_.write(dump_yaml(save_data))

        # set the current save variable
        self.current_save = filename.split("/")[2]

    def load_game(self, filename):
        """
        loads the game from file `filename`
        """
        # Raise an error if the file's path is incorrect (not ".yaml", all save files are yaml files)
        if not filename.split('.')[1] == "yaml":
            raise ImportError(
                f"filename extension incorrect {filename.split('.')[1]}")

        def remove_duplicates(a, b):
            """
            removes all items that are in a from b and returns b
            a = [1, 2, 3, 4]
            b = [3, 4, 5, 6]
            c = remove_duplicates(a, b)
            c = [5, 6]
            """
            # raise an error if the given items aren't lists
            if not isinstance(a, list) and not isinstance(b, list):
                raise TypeError("a and b must be lists")

            # iterate over a, check if that item is in b, if it is, remove it from b
            for item in a:
                if item in b:
                    b.remove(item)

            return b

        # open the file
        with open("./saves/" + filename) as file_:
            # load the data from the yaml file
            yaml_data = load_yaml(file_.read())

            # raise an error if the save doesn't have something we need
            assert \
                "player1" and "player2" and "puck" and "fullscreen" and "show_fps" and "options" in yaml_data.keys(), \
                "Error importing the save, key datapoint missing"

            player1, player2 = yaml_data["player1"], yaml_data["player2"]
            puck = yaml_data["puck"]

            # load the options
            self.window.set_fullscreen(yaml_data["fullscreen"])
            self.toggle_show_fps(yaml_data["show_fps"])
            self.options = yaml_data["options"]

            # load the player1 object
            self.player1.pos = player1["pos"]
            self.player1.color = player1["color"]
            self.player1.score = player1["score"]

            # load the player2 object
            self.player2.pos = player2["pos"]
            self.player2.color = player2["color"]
            self.player2.score = player2["score"]

            # load the puck object
            self.puck.pos = puck["pos"]
            self.puck.vel = puck["vel"]
            self.puck.color = puck["color"]
        # set the current save, unpause
        self.current_save = filename
        self.unpause_game()

    def build_load_menus(self):
        """
        builds the load menu pages procedurally
        needs rewritten probably but i'll cross that bridge when i get to it
        """
        # the total number of pages in the menu
        TOTAL_PAGES = (len(listdir("./saves")) / 5)
        # if it's not a whole number
        if TOTAL_PAGES % 1 != 0.0:
            # round it up
            TOTAL_PAGES = int(TOTAL_PAGES) + 1
            EVEN_PAGES = False
        # if it is a whole number (amount of pages % 5 == 0)
        else:
            # Convert the x.0 float into int x
            TOTAL_PAGES = int(TOTAL_PAGES)
            EVEN_PAGES = True
        # make a new page
        page = Menu()

        def commit_page(page, page_number):
            """
            adds the page to the pages array
            """
            # if it's not the first page, add a back button that takes you to the last page you were at (page 2 -> page 1)
            if page_number != 0:
                # last page button
                page.add_button(
                    MenuButton(0.315 * self.window.width,
                               0.14 * self.window.height,
                               h,
                               h,
                               "<",
                               self.goto_load_menu_page,
                               color=MID_GRAY,
                               id_="load_last_page",
                               function_args=page_number - 1))

            # back button
            page.add_button(
                MenuButton(0.500 * self.window.width,
                           0.140 * self.window.height,
                           w,
                           h,
                           "Back",
                           self.go_back,
                           color=MID_GRAY,
                           id_="load_go_back"))

            # if the page isn't the last one, add a forward button (page 1 -> page 2)
            if page_number != TOTAL_PAGES - 1:
                # next page button
                page.add_button(
                    MenuButton(0.685 * self.window.width,
                               0.140 * self.window.height,
                               h,
                               h,
                               ">",
                               self.goto_load_menu_page,
                               color=MID_GRAY,
                               id_="load_next_page",
                               function_args=page_number + 1))

            # add the page to the pages dictionary w/ the page number as the key
            self.load_menu_pages[page_number] = page

        # enumerate the pages & saves sorted by save names
        for index, save in sorted(enumerate(listdir("./saves"))):

            # the page number is the index of the save in "./saves/" floor divided by 5
            # index 8 (the 9th save) = page 2 (8 // 5 = 1 (indexes from 0))
            page_number = index // 5

            # get the x, y, w, h for the save file buttons
            x = 0.50 * self.window.width
            y = load_menu_ratios[index % 5] * self.window.height
            w = 0.25 * self.window.width
            h = 0.10 * self.window.height

            # the x position for the delete button, it uses the y and h from the file button for y, w, and h
            del_x = 0.685 * self.window.width

            # add the delete button to the menu
            page.add_button(
                MenuButton(del_x,
                           y,
                           h,
                           h,
                           "x",
                           self.delete_save,
                           color=MID_GRAY,
                           id_=f"delete game - {save}",
                           function_args=save))
            # add the load button to the menu
            page.add_button(
                MenuButton(x,
                           y,
                           w,
                           h,
                           save.split('.')[0],
                           self.load_game,
                           color=MID_GRAY,
                           id_=f"load_game - {save}",
                           function_args=save))
            # if we fill a menu (5 load buttons, 5 delete buttons), commit the page, make a new page
            if len(page.buttons) == 10:
                commit_page(page, page_number)
                page = Menu()

        # if our pages don't divide evenly, we'll have extra save files to draw,
        # so we commit the remaining page
        if not EVEN_PAGES:
            commit_page(page, page_number)
Ejemplo n.º 27
0
class VideoPlayerWindow(Window):
    def __init__(self, width: int, height: int, src, caption: str,
                 window_fps: int):
        super().__init__(width=width,
                         height=height,
                         caption=caption,
                         resizable=True)
        streamer = Streamer(src=src)

        self.bottom_panel = BottomPanel(relative_x=0,
                                        relative_y=0,
                                        width=self.width,
                                        height=int(self.height * 0.1),
                                        parent=self)
        self.video_panel = VideoPanel(relative_x=0,
                                      relative_y=self.bottom_panel.height,
                                      width=self.width,
                                      height=self.height -
                                      self.bottom_panel.height,
                                      streamer=streamer,
                                      parent=self)

        self.fps_display = FPSDisplay(self)

        # Pause Related
        self.paused = False
        self.paused_text = Label(text='Paused',
                                 font_name='Times New Roman',
                                 font_size=30,
                                 x=int(0.50 * self.width),
                                 y=int(0.98 * self.height),
                                 color=tuple([255, 100, 100] + [255]),
                                 anchor_x='center',
                                 anchor_y='top',
                                 bold=True)

        # Clock Related
        self.window_fps = window_fps
        self._frame_fps = self.video_panel.streamer.get_fps()

    @property
    def x(self) -> int:
        return 0

    @property
    def y(self) -> int:
        return 0

    @property
    def frame_fps(self) -> int:
        return self._frame_fps

    def toggle_pause(self):
        self.paused = not self.paused

    def on_draw(self):
        self.clear()
        self.video_panel.draw()
        self.bottom_panel.draw()
        self.fps_display.draw()
        if self.paused:
            self.paused_text.draw()

    def on_key_press(self, symbol, modifiers):
        if symbol == key.SPACE:
            self.toggle_pause()
        elif symbol == key.ESCAPE:
            self.close()
        elif symbol == key.RIGHT:
            self.video_panel.streamer.fastforward(100)
            self.video_panel.next_frame()
        elif symbol == key.LEFT:
            self.video_panel.streamer.rewind(100)
            self.video_panel.next_frame()

    def on_key_release(self, symbol, modifiers):
        pass

    def on_resize(self, width: int, height: int):
        self._projection.set(width, height, *self.get_framebuffer_size())
        height_prop = self.video_panel._orig_height / (
            self.video_panel._orig_height + self.bottom_panel._orig_height)
        video_panel_height = int(height * height_prop)
        self.video_panel.shape = (width, video_panel_height)
        self.bottom_panel.shape = (width, height - video_panel_height)

        if self.video_panel.frame._image_data is not None:
            if self.video_panel.frame.orig_aspect_ratio >= width / height:
                target_width = width
                target_height = int(target_width /
                                    self.video_panel.frame.orig_aspect_ratio)
                self.video_panel.frame.shape = (target_width, target_height)
                target_x = 0
                target_y = 0.5 * (height - self.bottom_panel.height -
                                  target_height) + self.bottom_panel.height
                self.video_panel.frame.position = (target_x, target_y)
            else:
                target_height = height
                target_width = int(target_height *
                                   self.video_panel.frame.orig_aspect_ratio)
                self.video_panel.frame.shape = (target_width, target_height)
                target_y = self.bottom_panel.height
                target_x = int(0.5 * (width - target_width))
                self.video_panel.frame.position = (target_x, target_y)

    def update_frame(self, dt):
        if not self.paused:
            self.video_panel.next_frame()
        else:
            pass

    def update_window(self, dt):
        pass

    def run(self):
        pyglet.clock.schedule_interval(self.update_frame, 1 / self.frame_fps)
        pyglet.clock.schedule_interval(self.update_window, 1 / self.window_fps)
        pyglet.app.run()
Ejemplo n.º 28
0
class GameWindow(pyglet.window.Window):
    @staticmethod
    def push(pos, rot):
        glPushMatrix()
        glRotatef(-rot[1], 1, 0, 0)
        glRotatef(-rot[0], 0, 1, 0)
        glTranslatef(
            -pos[0],
            -pos[1],
            -pos[2],
        )

    @staticmethod
    def my_projection():
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()

    @staticmethod
    def model_function():
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

    def set2d(self):
        glEnable(GL_BLEND)
        glDisable(GL_DEPTH_TEST)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(0, float(self.width), 0, float(self.height), -1, 1)
        self.model_function()

    def set3d(self):
        glCullFace(GL_BACK)
        glEnable(GL_CULL_FACE)
        glEnable(GL_DEPTH_TEST)
        glDisable(GL_BLEND)

        self.my_projection()
        gluPerspective(70, self.width / self.height, 0.05, 1000)
        self.model_function()

    def set_lock(self, state):
        self.lock = state
        self.set_exclusive_mouse(state)

    lock = False
    mouse_lock = property(lambda self: self.lock, set_lock)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.settings = Settings()['game_window']

        self.set_minimum_size(self.settings['min_size_x'],
                              self.settings['min_size_y'])
        self.keys = key.KeyStateHandler()
        self.push_handlers(self.keys)
        pyglet.clock.schedule(self.update)
        self.how_far = self.settings['chunks']
        self.fps_display = FPSDisplay(self)
        # self.fps_display.label.y = self.height - 50
        # self.fps_display.label.x = self.width - 150
        self.cross = pyglet.image.load('images/cross.png')
        self.label = pyglet.text.Label("",
                                       font_name='Times New Roman',
                                       font_size=18,
                                       x=self.width // 2,
                                       y=40,
                                       anchor_x='center',
                                       anchor_y='center')

        self.model = Model()
        self.y = 0
        position = self.settings['player_start_position']
        player_start_coords = (position['x'], position['y'], position['z'])
        player_start_rotation = (position['rot_x'], position['rot_y'])
        self.player = Player(self.model, player_start_coords,
                             player_start_rotation)

    def on_mouse_press(self, x, y, button, modifiers):
        self.player.mouse_press(button)

    def on_mouse_motion(self, x, y, dx, dy):
        if self.mouse_lock:
            self.player.mouse_motion(dx, dy)

    def on_key_press(self, user_key, mod):
        if user_key == key.ESCAPE:
            self.close()
        elif user_key == key.E:
            self.mouse_lock = not self.mouse_lock

    def update(self, dt):
        # print(self.player.pos[1])
        self.player.update(dt, self.keys)

    def on_draw(self):
        self.clear()
        self.set3d()
        self.push(self.player.pos, self.player.rot)
        x = math.floor(self.player.pos[0] / Settings.get_chunk_size())
        z = math.floor(self.player.pos[2] / Settings.get_chunk_size())
        # _thread.start_new_thread(self.model.draw, (x, z, self.how_far, (self.player.rot[0] + 180) % 360, ))
        self.model.draw(x, z, self.how_far, (self.player.rot[0] + 180) % 360)
        glPopMatrix()
        self.fps_display.draw()
        self.set2d()

        self.label.text = self.player.eq.print_content()
        self.label.draw()

        self.cross.blit(self.width // 2 - 20, self.height // 2 - 20)
Ejemplo n.º 29
0
class MyWindow(pyglet.window.Window):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.set_minimum_size(200, 100)
        self.frame_rate = 1 / 60
        self.fps_display = FPSDisplay(self)
        self.main_batch = pyglet.graphics.Batch()
        pyglet.clock.schedule_interval(self.update, self.frame_rate)
        pyglet.window.Window.switch_to(self)
        self.u = u
        self.g = g
        glClearColor(0.6, 0.7, 0.7, 1.0)
        gluPerspective(45.0, (1200 / 700), 1, -100.0)
        glTranslatef(0.0, 0.0, -(4 * self.u))
        glEnable(GL_PROGRAM_POINT_SIZE)
        glEnable(GL_DEPTH_TEST)
        glLineWidth(4)
        self.frame = Frame(vertices)
        glLineWidth(1)
        self.window_x = 10
        self.window_y = 10
        self.grid = Grid(self.u)
        self.marker = Marker(self.u)
        self.color_rotate = [0, 1, 2, 3, 4, 5]
        # read the text data file
        data_file = open('res/datalist.txt')
        content = data_file.readline()
        data_file.close()
        # strip and split the file and turn it into a list of integers
        datalist = [int(x) for x in content.strip().split(',')]
        # plot the data
        self.scatter_plot = scatter
        self.scatter = ScatterPlot(datalist)

        # self.rotate_axis = 1
        self.equation = []
        self.eq_list = []
        self.active = 0
        self.eq = ''
        self.left = False
        self.right = False
        self.up = False
        self.down = False
        self.forward = False
        self.backward = False
        self.rotatexp = False
        self.rotatexn = False
        self.rotateyp = False
        self.rotateyn = False
        self.rotatezp = False
        self.rotatezn = False
        self.x_rot = 0
        self.y_rot = 0
        self.move = 10  # set the base translation speed

        # start with the greeting panel
        self.rotate_axis = 0
        greet_panel = GreetWindow(100, 100, vsync=True)
        greet_panel.set_location(100, 150)

    def on_key_press(self, symbol, modifiers):  # input handler
        if symbol == key.ESCAPE:
            # exits the app
            pyglet.app.exit()

        if symbol == key.P:
            self.rotate_axis = 0
            # opens the text input panel
            text_panel = TextWindow(100, 100, vsync=True)
            text_panel.set_location(self.window_x, self.window_y - 28)

        if symbol == key.RIGHT:
            self.right = True
        if symbol == key.LEFT:
            self.left = True
        if symbol == key.UP:
            self.up = True
        if symbol == key.DOWN:
            self.down = True
        if symbol == key.Q:
            self.forward = True
        if symbol == key.A:
            self.backward = True

        if symbol == key.W:
            self.rotatexp = True
        if symbol == key.S:
            self.rotatexn = True
        if symbol == key.E:
            self.rotateyp = True
        if symbol == key.D:
            self.rotateyn = True
        if symbol == key.R:
            self.rotatezp = True
        if symbol == key.F:
            self.rotatezn = True

    def on_key_release(self, symbol, modifiers):
        if symbol == key.RIGHT:
            self.right = False
        if symbol == key.LEFT:
            self.left = False
        if symbol == key.UP:
            self.up = False
        if symbol == key.DOWN:
            self.down = False
        if symbol == key.Q:
            self.forward = False
        if symbol == key.A:
            self.backward = False

        if symbol == key.W:
            self.rotatexp = False
        if symbol == key.S:
            self.rotatexn = False
        if symbol == key.E:
            self.rotateyp = False
        if symbol == key.D:
            self.rotateyn = False
        if symbol == key.R:
            self.rotatezp = False
        if symbol == key.F:
            self.rotatezn = False

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        if buttons & mouse.LEFT:
            self.y_rot = dx / 5
            self.x_rot = -dy / 5

        glRotatef(self.x_rot, 1, 0, 0)
        glRotatef(self.y_rot, 0, 1, 0)

    def update_rotate(self):
        q, w, e = 0, 0, 0
        if self.rotatexp == True:
            q = 1
        if self.rotatexn == True:
            q = -1
        if self.rotatexp == False and self.rotatexn == False:
            q = 0.0
        if self.rotateyp == True:
            w = 1
        if self.rotateyn == True:
            w = -1
        if self.rotateyp == False and self.rotateyn == False:
            w = 0
        if self.rotatezp == True:
            e = -1
        if self.rotatezn == True:
            e = 1
        if self.rotatezp == False and self.rotatezn == False:
            e = 0
        return q, w, e

    def update_translate(self):
        r, t, y = 0, 0, 0
        if self.right == True:
            r = 1
        if self.left == True:
            r = -1
        if self.right == False and self.left == False:
            r = 0.0
        if self.up == True:
            t = 1
        if self.down == True:
            t = -1
        if self.up == False and self.down == False:
            t = 0
        if self.forward == True:
            y = -1
        if self.backward == True:
            y = 1
        if self.forward == False and self.backward == False:
            y = 0
        return r, t, y

    def on_mouse_scroll(self, x, y, scroll_x, scroll_y):
        self.z_trans = scroll_y
        glTranslatef(0, 0, self.z_trans)

    def on_draw(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glPointSize(5)  # size of the plot points
        if self.scatter_plot == 1:
            self.scatter.vertices.draw(GL_POINTS)  # to show the scatter plot
        glLineWidth(4)
        self.frame.vertices.draw(GL_LINES)
        glLineWidth(1)
        self.grid.vertices.draw(GL_LINES)
        glPointSize(10)  # size of the axis color points
        self.marker.vertices.draw(GL_POINTS)
        self.main_batch.draw()
        self.fps_display.draw()

    def update(self, dt):
        q, w, e = self.update_rotate()
        r, t, y = self.update_translate()
        glTranslatef(self.move * r * dt, self.move * t * dt,
                     self.move * y * dt)
        glRotatef(dt * 30, q, w, e)
        self.window_x, self.window_y = self.get_location()
        if rotate == 1:
            glRotatef(dt * 15, self.rotate_axis, self.rotate_axis,
                      0)  # to rotate by itself

    def on_resize(self, width, height):
        glViewport(0, 0, width, height)
Ejemplo n.º 30
0
class MyWindow(pyglet.window.Window):
    def __init__(self, *args, **kwargs):
        super(MyWindow, self).__init__(*args, **kwargs)
        #this clear thing affect the background color
        #comment it out to get a black background
        glClearColor(1, 1.0, 1.0, 1)
        self.fps_display = FPSDisplay(self)
        self.car = CarSprite()
        print(self.car.theta)
        self.key_handler = key.KeyStateHandler()

    def on_draw(self):
        self.clear()
        #self.glClear(GL_COLOR_BUFFER_BIT)
        self.car.draw()
        self.fps_display.draw()

        #outer Box
        glBegin(GL_LINES)
        #this color thing affect the lines
        glColor3f(1, 0, 0)
        # create a line, x,y,z
        glVertex3f(40.0, 20.0, 1)
        glVertex3f(40.0, 700, 1)

        glVertex3f(1240.0, 20.0, 1)
        glVertex3f(1240.0, 700.0, 1)

        glVertex3f(40.0, 20.0, 1)
        glVertex3f(1240.0, 20.0, 1)

        glVertex3f(40.0, 700.0, 1)
        glVertex3f(1240.0, 700.0, 1)

        #inner Box
        # create a line, x,y,z
        glVertex3f(240.0, 220.0, 1)
        glVertex3f(240.0, 500.0, 1)

        glVertex3f(1040.0, 220.0, 1)
        glVertex3f(1040.0, 500.0, 1)

        glVertex3f(240.0, 220.0, 1)
        glVertex3f(1040.0, 220.0, 1)

        glVertex3f(240.0, 500.0, 1)
        glVertex3f(1040.0, 500.0, 1)

        glEnd()

    def update(self, dt):
        if self.key_handler[key.LEFT]:
            print('turn left')
            self.car.updateTheta(-self.car.rotation_speed * dt)

        if self.key_handler[key.RIGHT]:
            print('turn right')
            self.car.updateTheta(self.car.rotation_speed * dt)

        if self.key_handler[key.UP]:
            thetaRadian = -math.radians(self.car.getTheta())
            deltaX = math.cos(thetaRadian) * self.car.speed * dt
            deltaY = math.sin(thetaRadian) * self.car.speed * dt
            self.car.updateX(deltaX)
            self.car.updateY(deltaY)
            self.car.updateDeltaX(deltaX)
            self.car.updateDeltaY(deltaY)
            print(str(self.car.getDeltaX()) + ' ' + str(self.car.getDeltaY()))

        if self.key_handler[key.DOWN]:
            thetaRadian = -math.radians(self.car.getTheta())
            deltaX = math.cos(thetaRadian) * self.car.speed * dt
            deltaY = math.sin(thetaRadian) * self.car.speed * dt
            self.car.updateX(-deltaX)
            self.car.updateY(-deltaY)
            self.car.updateDeltaX(-deltaX)
            self.car.updateDeltaY(-deltaY)

        self.car.updateX(self.car.getDeltaX())
        self.car.updateY(self.car.getDeltaY())
        self.car.updateDeltaX(self.car.getDeltaX() * 0.95)
        self.car.updateDeltaY(self.car.getDeltaY() * 0.95)