Esempio n. 1
0
    def render_game_over_screen(self):
        self.game_over_menu = GenericMenu(
            title=f"Game over! {self.game.winner.name} wins!",
            frame_color=(0, 0, 0, 0.5),
            title_pos=(0, 0, 0.55),
        )
        self.game_over_menu.show()

        self.text = {
            'stat_names':
            OnscreenText(
                text='Points\n',
                style=1,
                fg=(1, 1, 1, 1),
                shadow=(0, 0, 0, 0.5),
                pos=(self.left_most, self.top_most - self.row_spacing),
                scale=self.stat_font_size,
            ),
        }
        for i, player in enumerate(self.game.players):
            self.text[player.name] = OnscreenText(
                text=f"{player.name}\n{player.points}",
                style=1,
                fg=(1, 1, 1, 1),
                shadow=(0, 0, 0, 0.5),
                pos=(self.left_most + self.col_spacing * (i + 1),
                     self.top_most),
                scale=self.stat_font_size,
            )
Esempio n. 2
0
    def render_camera_load_buttons(self):
        self.cam_load_slots = GenericMenu(
            title="Release key with moused hovered over desired save slot",
            frame_color=(0, 0, 0, 0.2),
            title_pos=(0, 0, 0.45),
        )

        pos = -1.2
        for slot in range(1, 10):
            exists = True if f'save_{slot}' in self.player_cam.states else False
            button = self.cam_load_slots.add_button(
                text=(f'{slot}', f'{slot}', 'load' if exists else 'empty',
                      f'{slot}'),
                command=lambda: None,
                scale=0.1,
                text_scale=0.6,
                frameSize=(-1.2, 1.2, -1.2, 1.2),
                frameColor=(0.3, 0.6, 0.6, 1.0) if exists else
                (0.8, 0.8, 0.8, 1.0),
            )
            button.setPos((pos, 0, 0.25))
            button.bind(DGG.WITHIN,
                        self.update_load_selection,
                        extraArgs=[slot])
            button.bind(DGG.WITHOUT,
                        self.update_load_selection,
                        extraArgs=[None])
            pos += 0.3

        self.cam_load_slots.show()
Esempio n. 3
0
class GameOverMode(Mode):
    col_spacing = 0.25
    row_spacing = 0.04
    stat_font_size = 0.04
    left_most = -0.33
    top_most = 0.4
    keymap = {
        action.quit: False,
    }

    def enter(self):
        self.mouse.show()
        self.mouse.absolute()

        self.task_action('escape', action.quit, True)
        self.render_game_over_screen()

    def exit(self):
        self.game_over_menu.hide()
        for text in self.text.values():
            text.hide()

        del self.game_over_menu
        del self.text

    def render_game_over_screen(self):
        self.game_over_menu = GenericMenu(
            title=f"Game over! {self.game.winner.name} wins!",
            frame_color=(0, 0, 0, 0.5),
            title_pos=(0, 0, 0.55),
        )
        self.game_over_menu.show()

        self.text = {
            'stat_names':
            OnscreenText(
                text='Points\n',
                style=1,
                fg=(1, 1, 1, 1),
                shadow=(0, 0, 0, 0.5),
                pos=(self.left_most, self.top_most - self.row_spacing),
                scale=self.stat_font_size,
            ),
        }
        for i, player in enumerate(self.game.players):
            self.text[player.name] = OnscreenText(
                text=f"{player.name}\n{player.points}",
                style=1,
                fg=(1, 1, 1, 1),
                shadow=(0, 0, 0, 0.5),
                pos=(self.left_most + self.col_spacing * (i + 1),
                     self.top_most),
                scale=self.stat_font_size,
            )
Esempio n. 4
0
    def create_standby_screen(self):
        self.standby_screen = GenericMenu(frame_color=(0.3,0.3,0.3,1))
        self.standby_screen.add_image(ani.logo_paths['default'], pos=(0,0,0), scale=(0.5, 1, 0.44))

        text = OnscreenText(
            text = 'GUI standing by...',
            style = 1,
            fg = (1, 1, 1, 1),
            parent = self.standby_screen.titleMenu,
            align = TextNode.ALeft,
            pos = (-1.55,0.93),
            scale = 0.8*ani.menu_text_scale,
        )
Esempio n. 5
0
    def enter(self):
        self.mouse.hide()
        self.mouse.relative()
        self.mouse.track()

        self.shot_sim_overlay = GenericMenu(
            title='Calculating shot...',
            frame_color=(0, 0, 0, 0.4),
            title_pos=(0, 0, -0.2),
        )

        self.add_task(self.run_simulation,
                      'run_simulation',
                      taskChain='simulation')

        self.task_action('escape', action.quit, True)
        self.task_action('mouse1', action.zoom, True)
        self.task_action('mouse1-up', action.zoom, False)
        self.task_action('a', action.aim, True)
        self.task_action('v', action.move, True)
        self.task_action('v-up', action.move, False)
        self.task_action('h', action.show_help, True)

        self.add_task(self.calculate_view_task, 'calculate_view_task')
Esempio n. 6
0
    def shot_enter(self):
        self.mouse.hide()
        self.mouse.relative()
        self.mouse.track()

        self.shot_sim_overlay = GenericMenu(
            title='Calculating shot...',
            frame_color=(0, 0, 0, 0.4),
            title_pos=(0, 0, -0.2),
        )
        self.shot_sim_overlay.show()

        self.cue_stick.set_object_state_as_render_state()

        self.add_task(self.run_simulation,
                      'run_simulation',
                      taskChain='simulation')

        self.task_action('escape', action.quit, True)
        self.task_action('mouse1', action.zoom, True)
        self.task_action('mouse1-up', action.zoom, False)
        self.task_action('a', action.aim, True)
        self.task_action('v', action.move, True)
        self.task_action('v-up', action.move, False)
        self.task_action('r', action.restart_ani, True)
        self.task_action('r-up', action.restart_ani, False)
        self.task_action('z', action.undo_shot, True)
        self.task_action('z-up', action.undo_shot, False)
        self.task_action('f', action.fine_control, True)
        self.task_action('f-up', action.fine_control, False)
        self.task_action('arrow_left', action.rewind, True)
        self.task_action('arrow_left-up', action.rewind, False)
        self.task_action('arrow_right', action.fast_forward, True)
        self.task_action('arrow_right-up', action.fast_forward, False)

        self.add_task(self.quit_task, 'quit_task')
Esempio n. 7
0
class ShotViewer(Interface):
    is_game = False

    def __init__(self, *args, **kwargs):
        Interface.__init__(self, *args, **kwargs)
        self.create_standby_screen()
        self.create_instructions()
        self.create_title('')

        self.stop()


    def create_title(self, title):
        self.title_node = OnscreenText(
            text = title,
            pos = (-1.55, -0.93),
            scale = ani.menu_text_scale*0.7,
            fg = (1,1,1,1),
            align = TextNode.ALeft,
            parent = aspect2d,
        )
        self.title_node.hide()


    def create_instructions(self):
        self.instructions = OnscreenText(
            text = "Press <escape> to exit",
            pos = (-1.55, 0.93),
            scale = ani.menu_text_scale*0.7,
            fg = (1,1,1,1),
            align = TextNode.ALeft,
            parent = aspect2d,
        )
        self.instructions.hide()


    def create_standby_screen(self):
        self.standby_screen = GenericMenu(frame_color=(0.3,0.3,0.3,1))
        self.standby_screen.add_image(ani.logo_paths['default'], pos=(0,0,0), scale=(0.5, 1, 0.44))

        text = OnscreenText(
            text = 'GUI standing by...',
            style = 1,
            fg = (1, 1, 1, 1),
            parent = self.standby_screen.titleMenu,
            align = TextNode.ALeft,
            pos = (-1.55,0.93),
            scale = 0.8*ani.menu_text_scale,
        )


    def show(self, shot_or_shots=None, title=''):

        if shot_or_shots is None:
            # No passed shots. This is ok if self.shots has already been defined, but will complain
            # otherwise
            if not len(self.shots):
                raise ConfigError("ShotViewer.show :: No shots passed and no shots set.")
        else:
            # Create a new SystemCollection based on type of shot_or_shots
            if issubclass(type(shot_or_shots), System):
                self.shots = SystemCollection()
                self.shots.append(shot_or_shots)
            elif issubclass(type(shot_or_shots), SystemCollection):
                self.shots = shot_or_shots

        if self.shots.active is None:
            self.shots.set_active(0)

        self.standby_screen.hide()
        self.instructions.show()
        self.create_title(title)
        self.title_node.show()
        self.init_help_page()
        self.help_hint.hide()
        self.mouse = Mouse()
        self.init_system_nodes()
        self.init_hud()

        params = dict(
            init_animations = True,
            single_instance = True,
        )
        self.change_mode('shot', enter_kwargs=params)

        self.player_cam.load_state('last_scene', ok_if_not_exists=True)

        self.taskMgr.run()


    def stop(self):
        self.standby_screen.show()
        self.instructions.hide()
        self.title_node.hide()
        base.graphicsEngine.renderFrame()
        base.graphicsEngine.renderFrame()

        self.taskMgr.stop()


    def finalizeExit(self):
        self.stop()
Esempio n. 8
0
class CalculateMode(Mode):
    keymap = {
        action.move: False,
        action.quit: False,
        action.zoom: False,
        action.show_help: False,
    }

    def enter(self):
        self.mouse.hide()
        self.mouse.relative()
        self.mouse.track()

        self.shot_sim_overlay = GenericMenu(
            title='Calculating shot...',
            frame_color=(0, 0, 0, 0.4),
            title_pos=(0, 0, -0.2),
        )

        self.add_task(self.run_simulation,
                      'run_simulation',
                      taskChain='simulation')

        self.task_action('escape', action.quit, True)
        self.task_action('mouse1', action.zoom, True)
        self.task_action('mouse1-up', action.zoom, False)
        self.task_action('a', action.aim, True)
        self.task_action('v', action.move, True)
        self.task_action('v-up', action.move, False)
        self.task_action('h', action.show_help, True)

        self.add_task(self.calculate_view_task, 'calculate_view_task')

    def exit(self):
        self.remove_task('calculate_view_task')
        self.shot_sim_overlay.hide()

    def calculate_view_task(self, task):
        if not 'run_simulation' in self.tasks:
            # simulation calculation is finished
            self.change_mode('shot', enter_kwargs=dict(init_animations=True))
        elif self.keymap[action.zoom]:
            self.zoom_camera_calculate()
        elif self.keymap[action.move]:
            self.move_camera_calculate()
        else:
            if task.time > ani.rotate_downtime:
                # Prevents shot follow through from moving camera
                self.rotate_camera_calculate()
            else:
                # Update mouse positions so there is not a big jump
                self.mouse.touch()

            if task.time > 0.25:
                self.shot_sim_overlay.show()

        return task.cont

    def run_simulation(self, task):
        """Run a pool simulation"""
        self.shots.active.simulate(continuize=False, quiet=False)
        self.game.process_shot(self.shots.active)

        self.remove_task('run_simulation')

        return task.done

    def zoom_camera_calculate(self):
        with self.mouse:
            s = -self.mouse.get_dy() * ani.zoom_sensitivity

        self.player_cam.node.setPos(
            pt.autils.multiply_cw(self.player_cam.node.getPos(), 1 - s))

    def move_camera_calculate(self):
        with self.mouse:
            dxp, dyp = self.mouse.get_dx(), self.mouse.get_dy()

        h = self.player_cam.focus.getH() * np.pi / 180 + np.pi / 2
        dx = dxp * np.cos(h) - dyp * np.sin(h)
        dy = dxp * np.sin(h) + dyp * np.cos(h)

        self.player_cam.focus.setX(self.player_cam.focus.getX() +
                                   dx * ani.move_sensitivity)
        self.player_cam.focus.setY(self.player_cam.focus.getY() +
                                   dy * ani.move_sensitivity)

    def rotate_camera_calculate(self):
        fx, fy = ani.rotate_sensitivity_x, ani.rotate_sensitivity_y

        with self.mouse:
            alpha_x = self.player_cam.focus.getH() - fx * self.mouse.get_dx()
            alpha_y = max(
                min(0,
                    self.player_cam.focus.getR() + fy * self.mouse.get_dy()),
                -90)

        self.player_cam.focus.setH(alpha_x)  # Move view laterally
        self.player_cam.focus.setR(alpha_y)  # Move view vertically
Esempio n. 9
0
class CamLoadMode(Mode):
    keymap = {
        action.quit: False,
        action.cam_load: True,
    }

    def enter(self):
        if self.last_mode == 'aim':
            self.last_mode = 'view'
        self.mouse.show()
        self.mouse.absolute()
        self.mouse.track()
        self.selection = None

        self.task_action('escape', action.quit, True)
        self.task_action('2', action.cam_load, True)
        self.task_action('2-up', action.cam_load, False)

        self.render_camera_load_buttons()
        self.add_task(self.cam_load_task, 'cam_load_task')

    def render_camera_load_buttons(self):
        self.cam_load_slots = GenericMenu(
            title="Release key with moused hovered over desired save slot",
            frame_color=(0, 0, 0, 0.2),
            title_pos=(0, 0, 0.45),
        )

        pos = -1.2
        for slot in range(1, 10):
            exists = True if f'save_{slot}' in self.player_cam.states else False
            button = self.cam_load_slots.add_button(
                text=(f'{slot}', f'{slot}', 'load' if exists else 'empty',
                      f'{slot}'),
                command=lambda: None,
                scale=0.1,
                text_scale=0.6,
                frameSize=(-1.2, 1.2, -1.2, 1.2),
                frameColor=(0.3, 0.6, 0.6, 1.0) if exists else
                (0.8, 0.8, 0.8, 1.0),
            )
            button.setPos((pos, 0, 0.25))
            button.bind(DGG.WITHIN,
                        self.update_load_selection,
                        extraArgs=[slot])
            button.bind(DGG.WITHOUT,
                        self.update_load_selection,
                        extraArgs=[None])
            pos += 0.3

        self.cam_load_slots.show()

    def update_load_selection(self, state, coords):
        self.selection = state

    def exit(self):
        if self.selection:
            self.player_cam.load_state(name=f'save_{self.selection}',
                                       ok_if_not_exists=True)

        self.remove_task('cam_load_task')
        self.mouse.touch()
        self.cam_load_slots.hide()

    def cam_load_task(self, task):
        if not self.keymap[action.cam_load]:
            enter_kwargs = dict(
                load_prev_cam=True) if self.last_mode == 'aim' else {}
            self.change_mode(self.last_mode, enter_kwargs=enter_kwargs)

        return task.cont
Esempio n. 10
0
class Handler(object):
    def __init__(self):

        self.modes = {
            'menu': {
                'enter': self.menu_enter,
                'exit': self.menu_exit,
                'keymap': {
                    action.exit: False,
                    action.new_game: False,
                }
            },
            'aim': {
                'enter': self.aim_enter,
                'exit': self.aim_exit,
                'keymap': {
                    action.fine_control: False,
                    action.quit: False,
                    action.stroke: False,
                    action.view: False,
                    action.zoom: False,
                    action.elevation: False,
                    action.english: False,
                },
            },
            'stroke': {
                'enter': self.stroke_enter,
                'exit': self.stroke_exit,
                'keymap': {
                    action.fine_control: False,
                    action.stroke: True,
                },
            },
            'view': {
                'enter': self.view_enter,
                'exit': self.view_exit,
                'keymap': {
                    action.aim: False,
                    action.fine_control: False,
                    action.move: True,
                    action.quit: False,
                    action.zoom: False,
                },
            },
            'shot': {
                'enter': self.shot_enter,
                'exit': self.shot_exit,
                'keymap': {
                    action.aim: False,
                    action.fine_control: False,
                    action.move: False,
                    action.toggle_pause: False,
                    action.undo_shot: False,
                    action.restart_ani: False,
                    action.quit: False,
                    action.zoom: False,
                    action.rewind: False,
                    action.fast_forward: False,
                },
            },
        }

        # Store the above as default states
        self.action_state_defaults = {}
        for mode in self.modes:
            self.action_state_defaults[mode] = {}
            for a, default_state in self.modes[mode]['keymap'].items():
                self.action_state_defaults[mode][a] = default_state

        self.mode = None
        self.keymap = None

    def update_key_map(self, action_name, action_state):
        self.keymap[action_name] = action_state

    def task_action(self, keystroke, action_name, action_state):
        """Add action to keymap to be handled by tasks"""

        self.accept(keystroke, self.update_key_map,
                    [action_name, action_state])

    def change_mode(self, mode, exit_kwargs={}, enter_kwargs={}):
        assert mode in self.modes

        self.end_mode(**exit_kwargs)

        # Build up operations for the new mode
        self.mode = mode
        self.keymap = self.modes[mode]['keymap']
        self.modes[mode]['enter'](**enter_kwargs)

    def end_mode(self, **kwargs):
        # Stop watching actions related to mode
        self.ignoreAll()

        # Tear down operations for the current mode
        if self.mode is not None:
            self.modes[self.mode]['exit'](**kwargs)
            self.reset_action_states()

    def menu_enter(self):
        self.mouse.show()
        self.mouse.absolute()
        self.show_menu('main')

        self.task_action('escape', action.exit, True)
        self.task_action('escape-up', action.exit, False)
        self.task_action('n', action.new_game, True)
        self.task_action('n-up', action.new_game, False)

        self.add_task(self.menu_task, 'menu_task')

    def menu_exit(self):
        self.hide_menus()
        self.remove_task('menu_task')

    def aim_enter(self):
        self.mouse.hide()
        self.mouse.relative()
        self.mouse.track()

        self.cue_stick.show_nodes()
        self.cue_stick.get_node('cue_stick').setX(0)
        self.cam.update_focus(self.balls['cue'].get_node('ball').getPos())

        self.task_action('escape', action.quit, True)
        self.task_action('f', action.fine_control, True)
        self.task_action('f-up', action.fine_control, False)
        self.task_action('mouse1', action.zoom, True)
        self.task_action('mouse1-up', action.zoom, False)
        self.task_action('s', action.stroke, True)
        self.task_action('v', action.view, True)
        self.task_action('b', action.elevation, True)
        self.task_action('b-up', action.elevation, False)
        self.task_action('e', action.english, True)
        self.task_action('e-up', action.english, False)

        self.add_task(self.aim_task, 'aim_task')
        self.add_task(self.quit_task, 'quit_task')

    def aim_exit(self):
        self.remove_task('aim_task')
        self.remove_task('quit_task')

        self.cue_stick.hide_nodes()

        self.cam.store_state('aim', overwrite=True)

    def stroke_enter(self):
        self.mouse.hide()
        self.mouse.relative()
        self.mouse.track()

        self.cue_stick.track_stroke()
        self.cue_stick.show_nodes()

        self.task_action('f', action.fine_control, True)
        self.task_action('f-up', action.fine_control, False)
        self.task_action('s', action.stroke, True)
        self.task_action('s-up', action.stroke, False)

        self.add_task(self.stroke_task, 'stroke_task')

    def stroke_exit(self):
        self.remove_task('stroke_task')
        self.cam.store_state('stroke', overwrite=True)
        self.cam.load_state('aim')

    def view_enter(self):
        self.mouse.hide()
        self.mouse.relative()
        self.mouse.track()

        self.task_action('escape', action.quit, True)
        self.task_action('mouse1', action.zoom, True)
        self.task_action('mouse1-up', action.zoom, False)
        self.task_action('a', action.aim, True)
        self.task_action('v', action.move, True)
        self.task_action('v-up', action.move, False)

        self.add_task(self.view_task, 'view_task')
        self.add_task(self.quit_task, 'quit_task')

    def view_exit(self):
        self.remove_task('view_task')
        self.remove_task('quit_task')

    def shot_enter(self):
        self.mouse.hide()
        self.mouse.relative()
        self.mouse.track()

        self.shot_sim_overlay = GenericMenu(
            title='Calculating shot...',
            frame_color=(0, 0, 0, 0.4),
            title_pos=(0, 0, -0.2),
        )
        self.shot_sim_overlay.show()

        self.cue_stick.set_object_state_as_render_state()

        self.add_task(self.run_simulation,
                      'run_simulation',
                      taskChain='simulation')

        self.task_action('escape', action.quit, True)
        self.task_action('mouse1', action.zoom, True)
        self.task_action('mouse1-up', action.zoom, False)
        self.task_action('a', action.aim, True)
        self.task_action('v', action.move, True)
        self.task_action('v-up', action.move, False)
        self.task_action('r', action.restart_ani, True)
        self.task_action('r-up', action.restart_ani, False)
        self.task_action('z', action.undo_shot, True)
        self.task_action('z-up', action.undo_shot, False)
        self.task_action('f', action.fine_control, True)
        self.task_action('f-up', action.fine_control, False)
        self.task_action('arrow_left', action.rewind, True)
        self.task_action('arrow_left-up', action.rewind, False)
        self.task_action('arrow_right', action.fast_forward, True)
        self.task_action('arrow_right-up', action.fast_forward, False)

        self.add_task(self.quit_task, 'quit_task')

    def shot_exit(self, keep=True):
        """Exit shot mode

        Parameters
        ==========
        keep : bool, True
            If True, the system state will be set to the end state of the shot. Otherwise,
            the system state will be returned to the start state of the shot.
        """

        self.shot.finish_animation()
        self.shot.ball_animations.finish()

        if keep:
            self.shot.cue.reset_state()
            self.shot.cue.set_render_state_as_object_state()

            for ball in self.shot.balls.values():
                ball.reset_angular_integration()
        else:
            self.cam.load_state('stroke')
            for ball in self.shot.balls.values():
                if ball.history.is_populated():
                    ball.set(
                        rvw=ball.history.rvw[0],
                        s=ball.history.s[0],
                        t=0,
                    )
                ball.set_render_state_as_object_state()
                ball.history.reset_history()

        self.shot.cue.update_focus()

        self.remove_task('shot_view_task')
        self.remove_task('shot_animation_task')
        self.remove_task('quit_task')
        self.shot = None

    def reset_action_states(self):
        for key in self.keymap:
            self.keymap[key] = self.action_state_defaults[self.mode][key]