Exemple #1
0
    def __init__(self, background=None,
                 gravity=None, damping=0, adamping=0,
                 restitution=1, sfriction=0, dfriction=0,
                 bounds=None, max_speed=None,
                 simulation=None):

        self.background = background
        self._render_tree = RenderTree()
        self._input = conf.get_input()

        if simulation:
            self._simulation = simulation
        else:
            self._simulation = Simulation(
                gravity=gravity,
                damping=damping,
                adamping=adamping,
                restitution=restitution,
                sfriction=sfriction,
                dfriction=dfriction,
                max_speed=max_speed,
                bounds=bounds)

        self.is_paused = False
        super(World, self).__init__()
Exemple #2
0
    def __init__(self,
                 background=None,
                 gravity=None,
                 damping=0,
                 adamping=0,
                 rest_coeff=1,
                 sfriction=0,
                 dfriction=0,
                 stop_velocity=1e-6,
                 simulation=None):

        self.background = background
        self._render_tree = RenderTree()

        if simulation:
            self.simulation = simulation
        else:
            self.simulation = Simulation(gravity=gravity,
                                         damping=damping,
                                         adamping=adamping,
                                         rest_coeff=rest_coeff,
                                         sfriction=sfriction,
                                         dfriction=dfriction,
                                         stop_velocity=stop_velocity)

        # Controle de callbacks
        self.is_paused = False
        super(World, self).__init__()
Exemple #3
0
    def __init__(self, button_center, mouse_pos):
        RenderTree.__init__(self)
        vertices = []
        x = button_center[0]
        y = button_center[1]
        vertices.append((x, y + 1))
        vertices.append((x + mouse_pos[0], y + mouse_pos[1]))
        vertices.append((x + mouse_pos[0], y + mouse_pos[1] - 2))
        vertices.append((x, y - 1))

        self.pointer = Poly(vertices, color='white')
        self.add(self.pointer)
Exemple #4
0
    def __init__(self, background=None,
                 gravity=None, damping=0, adamping=0,
                 restitution=1, friction=0,
                 bounds=None, max_speed=None,
                 simulation=None):

        self.background = background
        self._render_tree = RenderTree()
        self._objects = []

        if simulation:
            self._simulation = simulation
        else:
            self._simulation = Simulation(
                gravity=gravity,
                damping=damping,
                adamping=adamping,
                restitution=restitution,
                friction=friction,
                max_speed=max_speed,
                bounds=bounds)

        self.is_paused = False

        # Populate world with user-customizable init
        self.init()

        # Saves instance
        self._last_instances.append(weakref.ref(self))

        # Connect signals
        self.autoconnect()
Exemple #5
0
    def __init__(self, background=None,
                 gravity=None, damping=0, adamping=0,
                 restitution=1, friction=0,
                 bounds=None, max_speed=None,
                 simulation=None, force_init=True):

        if force_init:
            conf.init()
            conf.show_screen()
        self.background = background
        self._render_tree = RenderTree()
        self._input = conf.get_input()

        if simulation:
            self._simulation = simulation
        else:
            self._simulation = Simulation(
                gravity=gravity,
                damping=damping,
                adamping=adamping,
                restitution=restitution,
                friction=friction,
                max_speed=max_speed,
                bounds=bounds)

        self.is_paused = False
        super(World, self).__init__()

        # Inicia e popula o mundo
        self.init()
Exemple #6
0
    def __init__(self,
                 background=None,
                 gravity=None,
                 damping=0,
                 adamping=0,
                 restitution=1,
                 friction=0,
                 bounds=None,
                 max_speed=None,
                 simulation=None):

        self.background = background
        self._render_tree = RenderTree()
        self._objects = []

        if simulation:
            self._simulation = simulation
        else:
            self._simulation = Simulation(gravity=gravity,
                                          damping=damping,
                                          adamping=adamping,
                                          restitution=restitution,
                                          friction=friction,
                                          max_speed=max_speed,
                                          bounds=bounds)

        self.is_paused = False

        # Populate world with user-customizable init
        self.init()

        # Saves instance
        self._last_instances.append(weakref.ref(self))

        # Connect signals
        self.autoconnect()
Exemple #7
0
class World(Listener, collections.MutableSequence):
    """
    Combines physical simulation with display.
    """

    # Simulation properties
    background = colorproperty('background', 'white')
    gravity = delegate_to('_simulation')
    damping = delegate_to('_simulation')
    adamping = delegate_to('_simulation')
    time = delegate_to('_simulation', readonly=True)

    # Special properties
    @lazy
    def add(self):
        return ObjectFactory(self)

    @lazy
    def track(self):
        return Tracker(self)

    @lazy
    def _mainloop(self):
        return conf.get_mainloop()

    @lazy
    def _input(self):
        return conf.get_input()

    _last_instances = []

    def __init__(self, background=None,
                 gravity=None, damping=0, adamping=0,
                 restitution=1, friction=0,
                 bounds=None, max_speed=None,
                 simulation=None):

        self.background = background
        self._render_tree = RenderTree()
        self._objects = []

        if simulation:
            self._simulation = simulation
        else:
            self._simulation = Simulation(
                gravity=gravity,
                damping=damping,
                adamping=adamping,
                restitution=restitution,
                friction=friction,
                max_speed=max_speed,
                bounds=bounds)

        self.is_paused = False

        # Populate world with user-customizable init
        self.init()

        # Saves instance
        self._last_instances.append(weakref.ref(self))

        # Connect signals
        self.autoconnect()

    def __len__(self):
        return len(self._objects)

    def __iter__(self):
        return iter(self._objects)

    def __getitem__(self, i):
        return self._objects[i]

    def __delitem__(self, i):
        self.remove(self._objects[i])

    def __setitem__(self, key, value):
        raise IndexError('cannot replace objects in world')

    def _add(self, obj, layer=0):
        """
        Adds object to the world.
        """

        if isinstance(obj, (tuple, list)):
            for obj in obj:
                self.add(obj, layer=layer)
        else:
            self._render_tree.add(obj, layer)
            if isinstance(obj, Body):
                self._simulation.add(obj)
                obj.world = self
            self._objects.append(obj)

    def insert(self, idx, obj):
        raise IndexError('cannot insert objects at specific positions. '
                         'Please user world.add()')

    def append(self, obj, layer=0):
        """
        Alias to World.add()
        """

        self.add(obj, layer)

    def remove(self, obj):
        """
        Remove object from the world.
        """

        if getattr(obj, 'world', None) is self:
            if obj in self._render_tree:
                self._render_tree.remove(obj)
            self._simulation.remove(obj)
            obj.world = None
        else:
            self._render_tree.remove(obj)
        self._objects.remove(obj)

    def init(self):
        """
        Executed after initialization.

        Should be overridden by sub-classes in order to populate the world with
        default objects during its creation. The default implementation does
        nothing.
        """

    def pause(self):
        """
        Pause physics simulation.
        """

        self.is_paused = True

    def resume(self):
        """
        Resume paused physics simulation.
        """

        self.is_paused = False

    def toggle_pause(self):
        """
        Toggles paused state.
        """

        self.is_paused = not self.is_paused

    def update(self, dt):
        """
        Main update routine.
        """

        if not self.is_paused:
            self._simulation.update(dt)

    def run(self, timeout=None, **kwds):
        """
        Runs simulation until the given timeout expires.

        Args:
            timeout (float):
                Maximum duration of simulation (in seconds). Leave None to
                run the simulation indefinitely.
        """

        conf.init()
        conf.show_screen()
        self._mainloop.run(self, timeout=timeout, **kwds)

    def start(self, **kwds):
        """
        Non-blocking version of World.run().

        Starts simulation in a separate thread. This must be supported by the
        backend (pygame, for instance, does).
        """

        if hasattr(self, '_thread'):
            try:
                self._thread.join(0)
            except TimeoutError:
                pass

        self._thread = threading.Thread(target=self.run, kwargs=kwds)
        self._thread.start()

    def stop(self):
        """
        Stops simulation.
        """

        # Forces thread to stop
        try:
            self._thread.join(0)
            del self._thread
        except (AttributeError, TimeoutError):
            pass
        self._mainloop.stop()

    def render_tree(self):
        """
        Return the render tree.
        """

        return self._render_tree
Exemple #8
0
class World(EventDispatcher):
    '''Classe Mundo: coordena todos os objetos com uma física definida e
    resolve a interação entre eles.
    '''
    def __init__(self,
                 background=None,
                 gravity=None,
                 damping=0,
                 adamping=0,
                 rest_coeff=1,
                 sfriction=0,
                 dfriction=0,
                 stop_velocity=1e-6,
                 simulation=None):

        self.background = background
        self._render_tree = RenderTree()

        if simulation:
            self.simulation = simulation
        else:
            self.simulation = Simulation(gravity=gravity,
                                         damping=damping,
                                         adamping=adamping,
                                         rest_coeff=rest_coeff,
                                         sfriction=sfriction,
                                         dfriction=dfriction,
                                         stop_velocity=stop_velocity)

        # Controle de callbacks
        self.is_paused = False
        super(World, self).__init__()

    background = color_property('background', 'white')

    # Propriedades do objeto Simulation #######################################
    @property
    def gravity(self):
        return self.simulation.gravity

    @gravity.setter
    def gravity(self, value):
        self.simulation.gravity = value

    @property
    def damping(self):
        return self.simulation.damping

    @damping.setter
    def damping(self, value):
        self.simulation.damping = value

    @property
    def adamping(self):
        return self.simulation.adamping

    @adamping.setter
    def adamping(self, value):
        self.simulation.adamping = value

    @property
    def time(self):
        return self.simulation.time

    # Gerenciamento de objetos ################################################
    def add(self, obj, layer=0):
        '''Adiciona um novo objeto ao mundo.

        Exemplos
        --------

        >>> obj = AABB((-10, 10, -10, 10))
        >>> world = World()
        >>> world.add(obj, layer=1)
        '''

        # Verifica se trata-se de uma lista de objetos
        if isinstance(obj, (tuple, list)):
            for obj in obj:
                self.add(obj, layer=layer)
            return

        # Adiciona na lista de renderização
        if getattr(obj, 'is_drawable', False):
            self._render_tree.add(obj, layer)
        else:
            self._render_tree.add(obj.visualization, layer)
            self.simulation.add(obj)

    def remove(self, obj):
        '''Descarta um objeto do mundo'''

        if getattr(obj, 'is_drawable', False):
            drawable = obj.visualization
            self._render_tree.remove(obj)
            self.simulation.remove(obj)
        else:
            self._render_tree.remove(obj)

    # Controle de eventos #####################################################
    # Delegações
    long_press = signal('long-press', 'key', delegate='simulation')
    key_up = signal('key-up', 'key', delegate='simulation')
    key_down = signal('key-down', 'key', delegate='simulation')
    mouse_motion = signal('mouse-motion', delegate='simulation')
    mouse_click = signal('mouse-click', 'button', delegate='simulation')

    # Eventos privados
    frame_enter = signal('frame-enter')
    frame_skip = signal('frame-skip', num_args=1)
    collision = signal('collision', num_args=1)

    # TODO: collision_pair = signal('collision-pair', 'obj1', 'obj2',
    # num_args=1)

    # Simulação de Física #####################################################
    def pause(self):
        '''Pausa a simulação de física'''

        self.is_paused = True

    def unpause(self):
        '''Resume a simulação de física'''

        self.is_paused = False

    def toggle_pause(self):
        '''Alterna o estado de pausa da simulação'''

        self.is_paused = not self.is_paused

    def update(self, dt):
        '''Rotina principal da simulação de física.'''

        self.trigger('frame-enter')
        if self.is_paused:
            return
        self.simulation.update(dt)
        self._render_tree.update(dt)

        return self.simulation.time

    # Laço principal ##########################################################
    def run(self, timeout=None, real_time=True):
        '''Roda a simulação de física durante o tempo 'timeout' especificado.

        O parâmetro `real_time` especifica se o tempo considerado consiste no
        tempo real ou no tempo de simulação.'''

        conf._mainloop_object.run(self, timeout=timeout)

    def stop(self):
        '''Finaliza o laço principal de simulação'''

        conf._mainloop_object.stop()

    def set_next_state(self, value):
        '''Passa a simulação para o próximo estado'''

        pass

    def get_render_tree(self):
        return self._render_tree

    ###########################################################################
    #                     Criação de objetos especiais
    ###########################################################################
    def set_bounds(self, *args, **kwds):
        '''Cria contorno'''

        # Processa argumentos
        hard = kwds.get('hard', True)
        delta = kwds.get('delta', 10000)
        use_poly = kwds.get('use_poly', False)
        color = kwds.get('color', 'black')

        if len(args) == 4:
            xmin, xmax, ymin, ymax = args
        elif len(args) == 1:
            xmin, xmax, ymin, ymax = args[0]
        elif not args:
            if 'width' not in kwds:
                raise TypeError('not enougth parameters to set boundaries')

            W, H = conf.get_window_shape()
            value = kwds.pop('width')
            try:
                N = len(value)
                if N == 2:
                    dx, dy = value
                    xmin, xmax = dx, W - dx
                    ymin, ymax = dy, H - dy
                elif N == 4:
                    dx, dy, dx1, dy1 = value
                    xmin, xmax = dx, W - dx1
                    ymin, ymax = dy, H - dy1
                else:
                    raise ValueError('width can have 1, 2 or 4 values')
            except TypeError:
                dx = dy = value
                xmin, xmax = dx, W - dx
                ymin, ymax = dy, H - dy
        else:
            raise TypeError('invalid number of positional arguments')

        assert xmin < xmax and ymin < ymax, 'invalid bounds'
        maker = Rectangle if use_poly else AABB
        up = maker(bbox=(xmin - delta, xmax + delta, ymax, ymax + delta))
        down = maker(bbox=(xmin - delta, xmax + delta, ymin - delta, ymin))
        left = maker(bbox=(xmin - delta, xmin, ymin, ymax))
        right = maker(bbox=(xmax, xmax + delta, ymin, ymax))
        for box in [up, down, left, right]:
            box.make_static()
        self.add(down)
        self.add(up)
        self.add(left)
        self.add(right)
        self._bounds = (left, right, up, down)
        self._hard_bounds = hard
Exemple #9
0
class World(Listener, collections.MutableSequence):
    """
    Combines physical simulation with display.
    """

    # Simulation properties
    background = colorproperty('background', 'white')
    gravity = delegate_to('_simulation')
    damping = delegate_to('_simulation')
    adamping = delegate_to('_simulation')
    time = delegate_to('_simulation', readonly=True)

    # Special properties
    @lazy
    def add(self):
        return ObjectFactory(self)

    @lazy
    def track(self):
        return Tracker(self)

    @lazy
    def _mainloop(self):
        return conf.get_mainloop()

    @lazy
    def _input(self):
        return conf.get_input()

    _last_instances = []

    def __init__(self,
                 background=None,
                 gravity=None,
                 damping=0,
                 adamping=0,
                 restitution=1,
                 friction=0,
                 bounds=None,
                 max_speed=None,
                 simulation=None):

        self.background = background
        self._render_tree = RenderTree()
        self._objects = []

        if simulation:
            self._simulation = simulation
        else:
            self._simulation = Simulation(gravity=gravity,
                                          damping=damping,
                                          adamping=adamping,
                                          restitution=restitution,
                                          friction=friction,
                                          max_speed=max_speed,
                                          bounds=bounds)

        self.is_paused = False

        # Populate world with user-customizable init
        self.init()

        # Saves instance
        self._last_instances.append(weakref.ref(self))

        # Connect signals
        self.autoconnect()

    def __len__(self):
        return len(self._objects)

    def __iter__(self):
        return iter(self._objects)

    def __getitem__(self, i):
        return self._objects[i]

    def __delitem__(self, i):
        self.remove(self._objects[i])

    def __setitem__(self, key, value):
        raise IndexError('cannot replace objects in world')

    def _add(self, obj, layer=0):
        """
        Adds object to the world.
        """

        if isinstance(obj, (tuple, list)):
            for obj in obj:
                self.add(obj, layer=layer)
        else:
            self._render_tree.add(obj, layer)
            if isinstance(obj, Body):
                self._simulation.add(obj)
                obj.world = self
            self._objects.append(obj)

    def insert(self, idx, obj):
        raise IndexError('cannot insert objects at specific positions. '
                         'Please user world.add()')

    def append(self, obj, layer=0):
        """
        Alias to World.add()
        """

        self.add(obj, layer)

    def remove(self, obj):
        """
        Remove object from the world.
        """

        if getattr(obj, 'world', None) is self:
            if obj in self._render_tree:
                self._render_tree.remove(obj)
            self._simulation.remove(obj)
            obj.world = None
        else:
            self._render_tree.remove(obj)
        self._objects.remove(obj)

    def init(self):
        """
        Executed after initialization.

        Should be overridden by sub-classes in order to populate the world with
        default objects during its creation. The default implementation does
        nothing.
        """

    def pause(self):
        """
        Pause physics simulation.
        """

        self.is_paused = True

    def resume(self):
        """
        Resume paused physics simulation.
        """

        self.is_paused = False

    def toggle_pause(self):
        """
        Toggles paused state.
        """

        self.is_paused = not self.is_paused

    def update(self, dt):
        """
        Main update routine.
        """

        if not self.is_paused:
            self._simulation.update(dt)

    def run(self, timeout=None, **kwds):
        """
        Runs simulation until the given timeout expires.

        Args:
            timeout (float):
                Maximum duration of simulation (in seconds). Leave None to
                run the simulation indefinitely.
        """

        conf.init()
        conf.show_screen()
        self._mainloop.run(self, timeout=timeout, **kwds)

    def start(self, **kwds):
        """
        Non-blocking version of World.run().

        Starts simulation in a separate thread. This must be supported by the
        backend (pygame, for instance, does).
        """

        if hasattr(self, '_thread'):
            try:
                self._thread.join(0)
            except TimeoutError:
                pass

        self._thread = threading.Thread(target=self.run, kwargs=kwds)
        self._thread.start()

    def stop(self):
        """
        Stops simulation.
        """

        # Forces thread to stop
        try:
            self._thread.join(0)
            del self._thread
        except (AttributeError, TimeoutError):
            pass
        self._mainloop.stop()

    def render_tree(self):
        """
        Return the render tree.
        """

        return self._render_tree
Exemple #10
0
class World(EventDispatcher):

    '''Classe Mundo: coordena todos os objetos com uma física definida e
    resolve a interação entre eles.
    '''

    def __init__(self, background=None,
                 gravity=None, damping=0, adamping=0,
                 restitution=1, sfriction=0, dfriction=0,
                 bounds=None, max_speed=None,
                 simulation=None):

        self.background = background
        self._render_tree = RenderTree()
        self._input = conf.get_input()

        if simulation:
            self._simulation = simulation
        else:
            self._simulation = Simulation(
                gravity=gravity,
                damping=damping,
                adamping=adamping,
                restitution=restitution,
                sfriction=sfriction,
                dfriction=dfriction,
                max_speed=max_speed,
                bounds=bounds)

        self.is_paused = False
        super(World, self).__init__()

    background = color_property('background', 'white')

    # Propriedades do objeto Simulation #######################################
    gravity = delegate_to('_simulation.gravity')
    damping = delegate_to('_simulation.damping')
    adamping = delegate_to('_simulation.adamping')
    time = delegate_to('_simulation.time', read_only=True)

    # Gerenciamento de objetos ################################################
    def add(self, obj, layer=0):
        '''Adiciona um novo objeto ao mundo.

        Exemplos
        --------

        >>> obj = AABB(-10, 10, -10, 10)
        >>> world = World()
        >>> world.add(obj, layer=1)
        >>> obj in world
        True

        Os objetos podem ser removidos com o método remove()

        >>> world.remove(obj)
        '''

        # Verifica se trata-se de uma lista de objetos
        if isinstance(obj, (tuple, list)):
            for obj in obj:
                self.add(obj, layer=layer)
            return

        # Adiciona na lista de renderização
        self._render_tree.add(obj, layer)
        if isinstance(obj, Body):
            self._simulation.add(obj)

    def remove(self, obj):
        '''Descarta um objeto do mundo'''

        self._render_tree.remove(obj)
        if isinstance(obj, Body):
            self._simulation.remove(obj)

    def __contains__(self, obj):
        return obj in self._render_tree or obj in self._simulation

    # Controle de eventos #####################################################
    # Delegações
    long_press = signal('long-press', 'key', delegate_to='_input')
    key_up = signal('key-up', 'key', delegate_to='_input')
    key_down = signal('key-down', 'key', delegate_to='_input')
    mouse_motion = signal('mouse-motion', delegate_to='_input')
    mouse_button_up = \
        signal('mouse-button-up', 'button', delegate_to='_input')
    mouse_button_down = \
        signal('mouse-button-down', 'button', delegate_to='_input')
    mouse_long_press = \
        signal('mouse-long-press', 'button', delegate_to='_input')

    # Eventos privados
    frame_enter = signal('frame-enter')
    frame_skip = signal('frame-skip', num_args=1)
    collision = signal('collision', num_args=1)
    # TODO: collision_pair = signal('collision-pair', 'obj1', 'obj2',
    # num_args=1)

    # Simulação de Física #####################################################
    def pause(self):
        '''Pausa a simulação de física'''

        self.is_paused = True

    def unpause(self):
        '''Resume a simulação de física'''

        self.is_paused = False

    def toggle_pause(self):
        '''Alterna o estado de pausa da simulação'''

        self.is_paused = not self.is_paused

    def update(self, dt):
        '''Rotina principal da simulação de física.'''

        self.trigger('frame-enter')
        if self.is_paused:
            return
        self._simulation.update(dt)
        return self._simulation.time

    # Laço principal ##########################################################
    def run(self, timeout=None, real_time=True, **kwds):
        '''Roda a simulação de física durante o tempo 'timeout' especificado.

        O parâmetro `real_time` especifica se o tempo considerado consiste no
        tempo real ou no tempo de simulação.'''

        conf.get_mainloop().run(self, timeout=timeout, **kwds)

    def stop(self):
        '''Finaliza o laço principal de simulação'''

        conf.get_mainloop().stop()

    def set_next_state(self, value):
        '''Passa a simulação para o próximo estado'''

        pass

    def get_render_tree(self):
        return self._render_tree

    ###########################################################################
    #                     Criação de objetos especiais
    ###########################################################################
    def add_bounds(self, *args, **kwds):
        '''Cria um conjunto de AABB's que representa uma região fechada.

        Parameters
        ----------

        '''

        # Processa argumentos
        hard = kwds.get('hard', True)
        delta = kwds.get('delta', 10000)
        use_poly = kwds.get('use_poly', False)
        color = kwds.get('color', 'black')

        if len(args) == 4:
            xmin, xmax, ymin, ymax = args
        elif len(args) == 1:
            xmin, xmax, ymin, ymax = args[0]
        elif not args:
            if 'width' not in kwds:
                raise TypeError('not enougth parameters to set boundaries')

            W, H = conf.get_window_shape()
            value = kwds.pop('width')
            try:
                N = len(value)
                if N == 2:
                    dx, dy = value
                    xmin, xmax = dx, W - dx
                    ymin, ymax = dy, H - dy
                elif N == 4:
                    dx, dy, dx1, dy1 = value
                    xmin, xmax = dx, W - dx1
                    ymin, ymax = dy, H - dy1
                else:
                    raise ValueError('width can have 1, 2 or 4 values')
            except TypeError:
                dx = dy = value
                xmin, xmax = dx, W - dx
                ymin, ymax = dy, H - dy
        else:
            raise TypeError('invalid number of positional arguments')

        assert xmin < xmax and ymin < ymax, 'invalid bounds'
        maker = Rectangle if use_poly else AABB
        up = maker(bbox=(xmin - delta, xmax + delta, ymax, ymax + delta))
        down = maker(bbox=(xmin - delta, xmax + delta, ymin - delta, ymin))
        left = maker(bbox=(xmin - delta, xmin, ymin, ymax))
        right = maker(bbox=(xmax, xmax + delta, ymin, ymax))
        for box in [up, down, left, right]:
            box.make_static()
            assert box._invmass == 0.0
        self.add([up, down, left, right])
        self._bounds = (left, right, up, down)
        self._hard_bounds = hard

    ###########################################################################
    #                         Funções úteis
    ###########################################################################
    def register_energy_tracker(self, auto_connect=True, ratio=True):
        '''Retorna uma função que rastreia a energia total do mundo a cada
        frame e imprime sempre que houver mudança na energia total.

        O comportamento padrão é imprimir a razão entre a energia inicial e a
        atual. Caso ``ratio=False`` imprime o valor da energia em notação
        científica.

        A função resultante é conectada automaticamente ao evento
        "frame-enter", a não ser que ``auto_conect=False``.
        '''

        last = [None]

        if ratio:
            def energy_tracker():
                total = self._simulation.energy_ratio()
                if (last[0] is None) or (abs(total - last[0]) > 1e-6):
                    last[0] = total
                    print('Energia total / energia inicial:', total)

        else:
            def energy_tracker():
                raise NotImplementedError

        if auto_connect:
            self.listen('frame-enter', energy_tracker)

        return energy_tracker
Exemple #11
0
    def __init__(self):
        RenderTree.__init__(self)
        self.linha_externa = Rectangle(TAM_LINHA_EXTERNA, color = 'white')
        self.linha_interna = Rectangle(TAM_LINHA_INTERNA, color = 'green')

        self.background = Rectangle((0, SCREEN_WIDTH, 0, SCREEN_HEIGHT), color = 'red')
        self.tabuleiro = Rectangle(TAM_TABULEIRO, color = 'green')

        self.garea_esquerda_linha = Rectangle(TAM_GRANDE_AREA_ESQUERDA_LINHA, color = 'white')
        self.garea_esquerda = Rectangle(TAM_GRANDE_AREA_ESQUERDA, color = 'green')

        self.garea_direita_linha = Rectangle(TAM_GRANDE_AREA_DIREITA_LINHA, color = 'white')
        self.garea_direita = Rectangle(TAM_GRANDE_AREA_DIREITA, color = 'green')

        self.peq_area_esquerda_linha = Rectangle(TAM_PEQ_AREA_ESQUERDA_LINHA, color = 'white')
        self.peq_area_esquerda = Rectangle(TAM_PEQ_AREA_ESQUERDA, color = 'green')

        self.peq_area_direita_linha = Rectangle(TAM_PEQ_AREA_DIREITA_LINHA, color = 'white')
        self.peq_area_direita = Rectangle(TAM_PEQ_AREA_DIREITA, color = 'green')

        self.circulo_central_grande_linha = Circle(RAIO_CIRCULO_CENTRAL, pos= (SCREEN_WIDTH/2, SCREEN_HEIGHT/2), color = 'white')
        self.circulo_central_grande = Circle(RAIO_CIRCULO_CENTRAL - LINHA_ESPESSURA, pos= (SCREEN_WIDTH/2, SCREEN_HEIGHT/2), color = 'green')

        self.circulo_central_peq = Circle(RAIO_BOLINHA, pos= (SCREEN_WIDTH/2, SCREEN_HEIGHT/2), color = 'white')

        self.circulo_esquerda_linha = Circle(RAIO_CIRCULO_CENTRAL, pos= (TAM_GRANDE_AREA_ESQUERDA[1], SCREEN_HEIGHT/2), color = 'white')
        self.circulo_esquerda = Circle(RAIO_CIRCULO_CENTRAL - LINHA_ESPESSURA, pos= (TAM_GRANDE_AREA_ESQUERDA[1], SCREEN_HEIGHT/2), color = 'green')

        self.circulo_direita_linha = Circle(RAIO_CIRCULO_CENTRAL, pos= (TAM_GRANDE_AREA_DIREITA[0], SCREEN_HEIGHT/2), color = 'white')
        self.circulo_direita = Circle(RAIO_CIRCULO_CENTRAL - LINHA_ESPESSURA, pos= (TAM_GRANDE_AREA_DIREITA[0], SCREEN_HEIGHT/2), color = 'green')

        self.reta_centro = Rectangle(TAM_RETA_CENTRO, color='white')

        self.marca_penalti_esquerda = Circle(RAIO_BOLINHA, pos=(W_DIFF + DIST_PENALTI ,SCREEN_HEIGHT/2), color='white')
        self.marca_penalti_direita = Circle(RAIO_BOLINHA, pos=(TAB_WIDTH - DIST_PENALTI, SCREEN_HEIGHT/2), color='white')

        self.add(self.background)
        self.add(self.tabuleiro)
        self.add(self.linha_externa)
        self.add(self.linha_interna)

        self.add(self.circulo_esquerda_linha)
        self.add(self.circulo_esquerda)

        self.add(self.circulo_direita_linha)
        self.add(self.circulo_direita)

        self.add(self.garea_esquerda_linha)
        self.add(self.garea_esquerda)

        self.add(self.garea_direita_linha)
        self.add(self.garea_direita)

        self.add(self.peq_area_esquerda_linha)
        self.add(self.peq_area_esquerda)

        self.add(self.peq_area_direita_linha)
        self.add(self.peq_area_direita)

        self.add(self.circulo_central_grande_linha)
        self.add(self.circulo_central_grande)
        self.add(self.circulo_central_peq)

        self.add(self.marca_penalti_esquerda)
        self.add(self.marca_penalti_direita)

        self.add(self.reta_centro)
Exemple #12
0
class World(EventDispatcher):

    '''Classe Mundo: coordena todos os objetos com uma física definida e
    resolve a interação entre eles.
    '''

    def __init__(self, background=None,
                 gravity=None, damping=0, adamping=0,
                 rest_coeff=1, sfriction=0, dfriction=0,
                 bounds=None, max_speed=None,
                 simulation=None):

        self.background = background
        self._render_tree = RenderTree()
        self._input = conf.get_input()

        if simulation:
            self._simulation = simulation
        else:
            self._simulation = Simulation(
                gravity=gravity,
                damping=damping,
                adamping=adamping,
                rest_coeff=rest_coeff,
                sfriction=sfriction,
                dfriction=dfriction,
                max_speed=max_speed,
                bounds=bounds)

        self.is_paused = False
        super(World, self).__init__()

    background = color_property('background', 'white')

    # Propriedades do objeto Simulation #######################################
    gravity = delegate_to('_simulation.gravity')
    damping = delegate_to('_simulation.damping')
    adamping = delegate_to('_simulation.adamping')
    time = delegate_to('_simulation.time', read_only=True)

    # Gerenciamento de objetos ################################################
    def add(self, obj, layer=0):
        '''Adiciona um novo objeto ao mundo.

        Exemplos
        --------

        >>> obj = AABB(-10, 10, -10, 10)
        >>> world = World()
        >>> world.add(obj, layer=1)
        '''

        # Verifica se trata-se de uma lista de objetos
        if isinstance(obj, (tuple, list)):
            for obj in obj:
                self.add(obj, layer=layer)
            return

        # Adiciona na lista de renderização
        self._render_tree.add(obj.visualization, layer)
        if isinstance(obj, Dynamic):
            self._simulation.add(obj)

    def remove(self, obj):
        '''Descarta um objeto do mundo'''

        if getattr(obj, 'is_drawable', False):
            drawable = obj.visualization
            self._render_tree.remove(obj)
            self._simulation.remove(obj)
        else:
            self._render_tree.remove(obj)

    # Controle de eventos #####################################################
    # Delegações
    long_press = signal('long-press', 'key', delegate_to='_input')
    key_up = signal('key-up', 'key', delegate_to='_input')
    key_down = signal('key-down', 'key', delegate_to='_input')
    mouse_motion = signal('mouse-motion', delegate_to='_input')
    mouse_click = signal('mouse-click', 'button', delegate_to='_input')

    # Eventos privados
    frame_enter = signal('frame-enter')
    frame_skip = signal('frame-skip', num_args=1)
    collision = signal('collision', num_args=1)
    # TODO: collision_pair = signal('collision-pair', 'obj1', 'obj2',
    # num_args=1)

    # Simulação de Física #####################################################
    def pause(self):
        '''Pausa a simulação de física'''

        self.is_paused = True

    def unpause(self):
        '''Resume a simulação de física'''

        self.is_paused = False

    def toggle_pause(self):
        '''Alterna o estado de pausa da simulação'''

        self.is_paused = not self.is_paused

    def update(self, dt):
        '''Rotina principal da simulação de física.'''

        self.trigger('frame-enter')
        if self.is_paused:
            return
        self._simulation.update(dt)
        self._render_tree.update(dt)

        return self._simulation.time

    # Laço principal ##########################################################
    def run(self, timeout=None, real_time=True):
        '''Roda a simulação de física durante o tempo 'timeout' especificado.

        O parâmetro `real_time` especifica se o tempo considerado consiste no
        tempo real ou no tempo de simulação.'''

        conf.get_mainloop().run(self, timeout=timeout)

    def stop(self):
        '''Finaliza o laço principal de simulação'''

        conf.get_mainloop().stop()

    def set_next_state(self, value):
        '''Passa a simulação para o próximo estado'''

        pass

    def get_render_tree(self):
        return self._render_tree

    ###########################################################################
    #                     Criação de objetos especiais
    ###########################################################################
    def set_bounds(self, *args, **kwds):
        '''Cria contorno'''

        # Processa argumentos
        hard = kwds.get('hard', True)
        delta = kwds.get('delta', 10000)
        use_poly = kwds.get('use_poly', False)
        color = kwds.get('color', 'black')

        if len(args) == 4:
            xmin, xmax, ymin, ymax = args
        elif len(args) == 1:
            xmin, xmax, ymin, ymax = args[0]
        elif not args:
            if 'width' not in kwds:
                raise TypeError('not enougth parameters to set boundaries')

            W, H = conf.get_window_shape()
            value = kwds.pop('width')
            try:
                N = len(value)
                if N == 2:
                    dx, dy = value
                    xmin, xmax = dx, W - dx
                    ymin, ymax = dy, H - dy
                elif N == 4:
                    dx, dy, dx1, dy1 = value
                    xmin, xmax = dx, W - dx1
                    ymin, ymax = dy, H - dy1
                else:
                    raise ValueError('width can have 1, 2 or 4 values')
            except TypeError:
                dx = dy = value
                xmin, xmax = dx, W - dx
                ymin, ymax = dy, H - dy
        else:
            raise TypeError('invalid number of positional arguments')

        assert xmin < xmax and ymin < ymax, 'invalid bounds'
        maker = Rectangle if use_poly else AABB
        up = maker(bbox=(xmin - delta, xmax + delta, ymax, ymax + delta))
        down = maker(bbox=(xmin - delta, xmax + delta, ymin - delta, ymin))
        left = maker(bbox=(xmin - delta, xmin, ymin, ymax))
        right = maker(bbox=(xmax, xmax + delta, ymin, ymax))
        for box in [up, down, left, right]:
            box.make_static()
        self.add(down)
        self.add(up)
        self.add(left)
        self.add(right)
        self._bounds = (left, right, up, down)
        self._hard_bounds = hard