Ejemplo n.º 1
0
class Corpse(pygame.sprite.Sprite):
    """ generic class for everything """
    def __init__(self, source):
        """ image should be a spritesheet of square sprites """
        pygame.sprite.Sprite.__init__(self)
        self.source = source
        self.image = pygame.image.load(self.source.death_image).convert_alpha()
        #self.rect = Rect(coords[0], coords[1], self.image.get_height(), self.image.get_height())
        self.rect = source.rect
        self.screen = self.source.screen
        self.death_animator = Animator(self.screen, self.image, self.rect)
        self.countdown = self.death_animator.frame_count
        self.dir = (0,0)
        self.alive = True
        self.facing_right = True

    def update(self):
        if (self.countdown > 0):
            self.death_animator.move = (self.death_animator.move+1)%self.death_animator.frame_count
            self.death_animator.goto(self.dir)
            self.countdown -= 1
            self.draw()
        else:
            self.kill()

    def draw(self):
        self.rect = self.screen.blit(
                self.image, 
                self.rect, 
                self.rect
                )
Ejemplo n.º 2
0
    def load_log_file(self, file_name):
        self.scene = Graphics_scene(self)
        self.visualizer_view.setScene(self.scene)

        self.session = Session()
        self.road_network = Network()
        self.animator = Animator(self.scene)
        self.city = City(self.animator)

        if file_name.endswith(".gz"):
            input_file = GzipFile(file_name)
        elif file_name.endswith(".bz2"):
            input_file = BZ2File(file_name)
        else:
            input_file = open(file_name, 'r')
        for line in input_file:
            if self.session.parse(line):
                continue
            if self.road_network.parse(line):
                continue
            if self.city.parse(line):
                continue
        input_file.close()

        self.road_network.resolve()
        self.scene.draw_road_network(self.road_network)

        self.set_ready_to_run(file_name)
Ejemplo n.º 3
0
    def __init__(self, master, init_size=(WINDOW_WIDTH, WINDOW_HEIGHT)):
        '''
        Arguments:
            master: a tk.Tk object that manages the window
            init_size: a tuple of two non-negative integers representing the
            initial size of the game window (width, height) in pixels

        Creates and populates all of the GUI elements of the game.
        '''
        self.master = master
        self.width, self.height = init_size
        self.master.geometry(f'{self.width}x{self.height}')

        self.create_widgets()
        self.create_menu_buttons()
        self.animator = Animator(self)
        self.master.bind('<Key>', self.key_handler)

        # Whether a game square has been clicked
        self.square_clicked = None

        # A GameState object
        self.game_state = gs.GameState()
        # A stack of game states, for the purpose of undoing moves
        self.state_stack = []
        # Number of moves made, undos do not reset
        self.moves = 0

        self.send_message('Hello! To start playing, please load a puzzle file.'+
            ' Many pre-built examples are included.' +
            ' For more info, such as keybinds, see readme.txt.')
Ejemplo n.º 4
0
def main():
    env = BasicGridEnvironment(50, 50)
    env.addCell(BasicCell(RandomActor()), randLocation=True)
    env.addCell(BasicCell(RandomActor()), randLocation=True)
    env.addCell(BasicCell(RandomActor()), randLocation=True)

    a = Animator(env)
    a.animate()
Ejemplo n.º 5
0
    def __init__(self, calanfpga):
        Animator.__init__(self, calanfpga)
        self.snapshots = self.settings.snapshots

        self.n_inputs = len(self.snapshots)
        self.figure = CalanFigure(n_plots=self.n_inputs, create_gui=True)
        for i, snapshot in enumerate(self.snapshots):
            self.figure.create_axis(i, SnapshotAxis, 
                self.settings.snap_samples, snapshot)
Ejemplo n.º 6
0
 def __init__(self):
     self.animator = Animator(looking_at=(0, 0, 0),
                              looking_from=(0, -50, -50),
                              up_vector=(0, 0, 1),
                              latitude=45.0,
                              longitude=45.0,
                              distance=(50 * sqrt(2.0)))
     self.spherical = False
     self.prepare_args()
Ejemplo n.º 7
0
    def __init__(self, ent, anim):
        'ent can be None if all of the entity manipulating methods (below) are overridden.'
        self.ent = ent
        self.stats = StatSet()
        self.stats.hp = 1

        self._animator = Animator()
        self._anim = anim
        self.direction = dir.DOWN  # as good as any
        self.interruptable = True  # if false, no state changes will occur
        self.invincible = False
        self.state = self.defaultState()
Ejemplo n.º 8
0
 def __init__(self, ent, anim):
     # ent can be None if all of the entity manipulating methods are
     # overidden.
     self.ent = ent
     self.stats = StatSet()
     self.stats.hp = 1
     self._animator = Animator()
     self._anim = anim
     self.direction = dir.DOWN  # arbitrary
     self.interruptable = True  # if false, no state changes will occur
     self.invincible = False
     self._state = self.defaultState().next
Ejemplo n.º 9
0
 def __init__(self, source):
     """ image should be a spritesheet of square sprites """
     pygame.sprite.Sprite.__init__(self)
     self.source = source
     self.image = pygame.image.load(self.source.death_image).convert_alpha()
     #self.rect = Rect(coords[0], coords[1], self.image.get_height(), self.image.get_height())
     self.rect = source.rect
     self.screen = self.source.screen
     self.death_animator = Animator(self.screen, self.image, self.rect)
     self.countdown = self.death_animator.frame_count
     self.dir = (0,0)
     self.alive = True
     self.facing_right = True
Ejemplo n.º 10
0
 def __init__(self, source, image, coords):
     """ image should be a spritesheet of square sprites """
     pygame.sprite.Sprite.__init__(self)
     self.source = source
     self.image = pygame.image.load(image).convert_alpha()
     self.rect = Rect(coords[0], coords[1], self.image.get_height(),
                      self.image.get_height())
     self.screen = self.source.screen
     self.move_animator = Animator(self.screen, self.image, self.rect)
     self.m_image = self.image.subsurface(self.move_animator.crop_init)
     self.mask = pygame.mask.from_surface(self.m_image)
     self.dir = (0, 0)
     self.alive = True
     self.speed = 1
Ejemplo n.º 11
0
class AnimatedElement(Element):
    """Класс анимированного элемента в окне"""

    def __init__(self, path, position, animator_options=None):
        super().__init__()
        self.animator = Animator(path, animator_options)  # создаем аниматор
        self.position = position  # позиция
        self.rect = self.animator.next_()[0].get_rect(
            topleft=position)  # определяем прямоугольник

    def show(self, surf):
        """Отображение на поверхности"""
        image, shift = self.animator.next_()
        surf.blit(image,
                  (self.position[0] + shift[0], self.position[1] + shift[1]))
Ejemplo n.º 12
0
class Object(pygame.sprite.Sprite):
    """ generic class for everything """
    def __init__(self, source, image, coords):
        """ image should be a spritesheet of square sprites """
        pygame.sprite.Sprite.__init__(self)
        self.source = source
        self.image = pygame.image.load(image).convert_alpha()
        self.rect = Rect(coords[0], coords[1], self.image.get_height(),
                         self.image.get_height())
        self.screen = self.source.screen
        self.move_animator = Animator(self.screen, self.image, self.rect)
        self.m_image = self.image.subsurface(self.move_animator.crop_init)
        self.mask = pygame.mask.from_surface(self.m_image)
        self.dir = (0, 0)
        self.alive = True
        self.speed = 1

    def destroy(self):
        self.dir = (0, 0)
        self.alive = False
        self.kill()
        del self
        pygame.event.post(userevents.death_event())

    def move(self, coords):
        self.dir = (coords[0], coords[1])

    def draw(self):
        self.rect = self.screen.blit(self.image, self.rect, self.rect)

    def turnaround(self, point):
        pass

    def update(self):
        if (self.alive):
            self.rect = self.move_animator.goto(self.dir)
            self.mask = self.move_animator.current_mask
        else:
            self.destroy()

    def moveOnce(self, coords):
        self.rect = self.move_animator.goto(coords)

    def get_pos(self):
        x = (self.rect.centerx)
        y = (self.rect.centery)
        r = (x, y)
        return r
Ejemplo n.º 13
0
    def getAnimatorViews(self):
        """
        Return a list of the animator views defined by the layout.
        If there is more than one animator view in the current
        application layout, each one can be accessed via its own element
        in the list. For example, if there are 3 animator views in the
        GUI, the following sequence of commands can be used to display a
        different channel in each one: 

            a = v.getAnimatorViews()
            a[0].setChannel(1)
            a[1].setChannel(110)
            a[2].setChannel(5)

        Returns
        -------
        list
            A list of Animator objects.
        """
        commandStr = "getAnimatorViews"
        animatorViewsList = self.con.cmdTagList(commandStr)
        animatorViews = []
        if (animatorViewsList[0] != ""):
            for av in animatorViewsList:
                animatorView = Animator(av, self.con)
                animatorViews.append(animatorView)
        return animatorViews
Ejemplo n.º 14
0
 def __init__(self):
     self.animator = Animator(looking_at=(0,0,0),
                              looking_from=(0,-50,-50),
                              up_vector=(0,0,1),
                              latitude=45.0,
                              longitude=45.0,
                              distance=(50*sqrt(2.0)))
     self.spherical = False
     self.prepare_args()
Ejemplo n.º 15
0
    def restart(self):
        self.grid = Grid(self.size)
        self.animator = Animator(self.grid, self.fps)
        self.score = 0
        self.over = False
        self.won = False
        self.logger = self.grid.logger

        self.add_start_tiles(2)
        self.game_loop()
Ejemplo n.º 16
0
    def start_animation(self, track, scene_num, *args):

        # print " "
        # print "STARTING ANIMATION"
        # print " "

        my_animator = Animator(*track)
        my_animator.loop = True
        self.animations[scene_num] = my_animator

        try:
            self.layers[scene_num].opacity = 0  # or 0 to start off
            my_animator.do(self.layers[scene_num])
            if platform == 'ios' or platform == 'android':
                self.app.appix_base.solid_layer.add_widget(self.layers[scene_num])
            else:
                self.app.main_stage.ids["content_preview"].add_widget(self.layers[scene_num])
        except AttributeError:
            "this was an attribute error"
            pass
Ejemplo n.º 17
0
    def __init__(self, size, debug_mode, fps):
        self.size = size
        self.debug_mode = debug_mode
        self.grid = Grid(self.size)
        self.fps = fps
        self.animator = Animator(self.grid, self.fps)
        self.score = 0
        self.over = False
        self.won = False
        self.logger = self.grid.logger

        self.add_start_tiles(2)
Ejemplo n.º 18
0
    def build(self):
        #initializing the elements from the .kv file
        self.designElements = DesignElements()
        self.main_carousel = self.designElements.ids['crsMain']
        self.btn_set_file_path = self.designElements.ids['btnSetFilepath']
        self.lbl_file_path = self.designElements.ids['lblFilePath']
        self.btn_refresh_members = self.designElements.ids['btnRefreshMembers']
        self.lbl_members_count = self.designElements.ids['lblMembersCount']
        self.im_group_pic = self.designElements.ids['imGroup']
        self.btn_next_group_pic = self.designElements.ids['btnNextGroup']
        self.lbl_news = self.designElements.ids['lblNews']
        self.lay_rules = self.designElements.ids['layRules']

        #the json store where permanent data is stored
        self.app_data_name = 'AppData.json'

        #creating the members carousel, to access it later in members carousel
        self.members_carousel = Carousel(direction='bottom', loop='True')

        #binding buttons with their callbacks
        self.btn_set_file_path.bind(on_press=self.showSetFilepathPopup)
        self.btn_refresh_members.bind(on_press=self.refreshCallback)
        self.btn_next_group_pic.bind(on_press=partial(self.changeGroupPic))

        #loading the currently stored data (if there is any)
        self.loadDataPath()

        #initialising the animator
        self.animator = Animator()

        #setting up the members by adding them into an array and then filling
        # the array in the method
        self.members = []
        self.refresh()

        #initialising the errors class // Not Functional at the moment
        self.error = Error()

        #kivy thing
        return self.designElements
Ejemplo n.º 19
0
    def __init__(self, dpi: int, 
                 figsize: Tuple[int], interval: int) -> None:
        """
        The constructor.

        Parameters:
         dpi: dots per inches, which controls the resolution.
         fisize: tuple of two ints, which sets the size of the plot.
         animation_interval: set the animation interval in milliseconds
         between each animation frame.
        """
        Animator.__init__(self, dpi, figsize, interval)
        ax = self.figure.add_subplot(1, 1, 1)
        # self.t = np.linspace(-np.pi, np.pi, 256)
        if "Number of points" in config.config:
            n = config.config["Number of points"]
            self.t = np.linspace(-np.pi, np.pi, n)
        else:
            self.t = np.linspace(-np.pi, np.pi, 1024)
        ax.grid()
        if "function" in config.config:
            f = config.config["function"]
            self.function = FunctionRtoR(f, abc.x)
            ax.set_title("f(x) = %s" % (f))
        else:
            self.function = FunctionRtoR("sin(x)", abc.x)
            ax.set_title("f(x) = sin(x)")
        default_values = self.function.get_default_values()
        self.params = (default_values[key] for key in default_values)
        self.y = self.function(self.t, *self.params)
        ax.set_xlim(np.amin(self.t), np.amax(self.t))
        ax.set_xlabel("x")
        if "Plot Colour" in config.config:
            color = config.config["Plot Colour"]
            line, = ax.plot(self.t, self.y, color=color)
        else:
            line, = ax.plot(self.t, self.y)
        self.line = line
Ejemplo n.º 20
0
class GameObject:
    def __init__(self, path, position, name):
        self.position = position  # позиция
        self.name = name  # имя объекта
        self.animator = Animator('Sprites/' + path)  # аниматор

    def show(self, surf):
        """Отображение объекта"""
        image, shift = self.animator.next_()
        # получаем следущий кадр анимации и смещение
        # отображаем его на поверхность с учетом смещения
        surf.blit(
            image,
            apply((self.position[0] * TILE + shift[0],
                   self.position[1] * TILE + shift[1])))
Ejemplo n.º 21
0
    def getLinkedAnimators(self):
        """
        Get the animators that are linked to this image view.

        Returns
        -------
        list
            A list of Animator objects.
        """
        resultList = self.con.cmdTagList("getLinkedAnimators",
                                         imageView=self.getId())
        linkedAnimatorViews = []
        if (resultList[0] != ""):
            for animator in resultList:
                linkedAnimatorView = Animator(animator, self.con)
                linkedAnimatorViews.append(linkedAnimatorView)
        return linkedAnimatorViews
Ejemplo n.º 22
0
    def add_random_ghost_animation(self, room_id, path_id, start_position):

        ghost_path = "Well Escape tiles/ghostTiles/"
        ghost_sprite_sheet = random.choice(
            loadSave.load_files_form_directory(ghost_path, ".png"))
        # Animation_data -> [animator, room_id, path_id, start_cell_id, end_cell_id, forwards, (current position)]
        animation_data = [
            # Todo turn magic numbers in animations into constants
            Animator(ghost_sprite_sheet, library.scaleNum, 3, 7, 0.85),
            room_id,
            path_id,
            0,
            1,
            True,
            start_position
        ]

        self.ghost_sprite_animations.append(animation_data)
Ejemplo n.º 23
0
class Camera(object):
    """An object to control the camera"""
    def __init__(self):
        self.animator = Animator(looking_at=(0,0,0),
                                 looking_from=(0,-50,-50),
                                 up_vector=(0,0,1),
                                 latitude=45.0,
                                 longitude=45.0,
                                 distance=(50*sqrt(2.0)))
        self.spherical = False
        self.prepare_args()
    def prepare_args(self):
        anim = self.animator
        if self.spherical:
            d = anim['distance']
            theta = radians(anim['longitude'])
            phi = radians(anim['latitude'])
            r = d * cos(phi)
            dz = d * sin(phi)
            dx = r * cos(theta)
            dy = r * sin(theta)
            x0,y0,z0 = anim['looking_at']
            up_r = - sin(phi)
            up = (up_r * cos(theta), up_r * sin(theta), cos(phi))
            anim['looking_from'] = (x0+dx, y0+dy, z0+dz)
            anim['up_vector'] = up
        self.lookat_args = (tuple(anim['looking_from']) +
                            tuple(anim['looking_at']) +
                            tuple(anim['up_vector']))
    def setup(self):
        glLoadIdentity()
        gluLookAt(*self.lookat_args)
    def look_at(self, pos, steps=0):
        """Point the camera.
           If a number of steps specified, step() will turn the camera
           in that many steps.
        """
        self.animator.change('looking_at',pos,steps)
        self.prepare_args()
    def look_from(self, pos, steps=0):
        """Move the camera.
        If a number of steps specified, step() will move the camera in that
        many steps.
        """
        self.animator.change('looking_from',pos,steps)
        self.spherical = False
        self.prepare_args()
    def look_from_spherical(self,lat,long,dist,steps=0):
        """Move the camera, using spherical coordinates"""
        if not self.spherical:
            x,y,z = self.animator['looking_from']
            x0,y0,z0 = self.animator['looking_at']
            dx,dy,dz = x-x0, y-y0, z-z0
            distance = sqrt(dx*dx + dy*dy + dz*dz)
            self.animator['distance'] = distance
            longitude = degrees(atan2(y0,x0))
            latitude = degrees(atan2(z0,sqrt(x0*x0+y0*y0)))
            self.animator['latitude'] = latitude
            self.animator['longitude'] = longitude
        self.animator.change('latitude',lat,steps)
        self.animator.change('longitude',long,steps)
        self.animator.change('distance',dist,steps)
        self.spherical = True
    def choose_up(self,vec,steps=0):
        """Choose the subjective 'up' vector"""
        self.animator.change('up_vector',vec,steps)
        self.prepare_args()
    def step(self,ms):
        """Move and point the camera"""
        changed = not(self.animator.finished())
        self.animator.step(ms)
        if changed:
            self.prepare_args()
    def ready(self):
        return self.animator.finished()
Ejemplo n.º 24
0
from nonlinear import NonLinear
from animator import Animator
import numpy as np

RG = NonLinear()

RG.dx = 0.1
RG.dy = 0.1
x = np.arange(-10, 10, RG.dy)
y = np.arange(-10, 10, RG.dy)
RG.x, RG.y = np.meshgrid(x, y)

RG.dz = 0.02
RG.z = np.arange(0, 6, RG.dz)

# RG.eta = 0.25065
RG.eta = 0.3
RG.a0 = np.exp(-RG.eta * (RG.x**2 + RG.y**2))

RG.kappa = 1
RG.integrate()

filename = 'repulse.mp4'

anim = Animator(RG)
anim.start_animation(filename)

devnull = open(os.devnull, 'w')
subprocess.call(['mpv', filename], stdout=devnull, stderr=devnull)
Ejemplo n.º 25
0
from nonlinear import NonLinear
from animator import Animator
import numpy as np

RG = NonLinear()

RG.dt = 0.1
RG.times = np.arange(-10, 10, RG.dt)

RG.dz = 0.02
RG.z = np.arange(0, 50, RG.dz)

RG.T0 = 2
RG.a0 = np.exp(-RG.times**2 / RG.T0**2)

RG.integrate('c')

anim = Animator(RG)
anim.start_animation()
Ejemplo n.º 26
0
 def __init__(self, path, position, animator_options=None):
     super().__init__()
     self.animator = Animator(path, animator_options)  # создаем аниматор
     self.position = position  # позиция
     self.rect = self.animator.next_()[0].get_rect(
         topleft=position)  # определяем прямоугольник
Ejemplo n.º 27
0
 def animator(self):
     return Animator(self)
Ejemplo n.º 28
0
    grid[(positions[:, 0] / grid_spacing).astype(int),
         (positions[:, 1] / grid_spacing).astype(int)] = np.arange(num_balls)

    # Create a good sorting solution using morton indexing
    print 'Creating morton index...grid size is' , grid_size
    index_array = np.arange(grid_size*grid_size, dtype=np.int)
    index_matrix = index_array.reshape((grid_size, grid_size))
    zorder(index_matrix)
    zordered_indices = index_matrix.ravel()

    assert set(zordered_indices) == set(index_array) # Make sure the set of all values has not been changed
    print 'Morton assertion passed!'
    print 'Done!'

    # A matplotlib-based animator object
    animator = Animator(positions, radius * 2)

    # simulation/animation time variablees
    physics_step = 1.0 / 100  # estimate of real-time performance of simulation
    anim_step = 1.0 / 30  # FPS
    total_time = 0

    frame_count = 0

    # SUBPROBLEM 4: uncomment the code below.
    # preallocate locks for objects
    locks_ptr = preallocate_locks(num_balls)

    num_to_record = 100
    num_recorded = 0
    list_of_fps = []
Ejemplo n.º 29
0
 def __init__(self, path, position, name):
     self.position = position  # позиция
     self.name = name  # имя объекта
     self.animator = Animator('Sprites/' + path)  # аниматор
Ejemplo n.º 30
0
    velocities = np.random.uniform(-0.25, 0.25,
                                   (num_balls, 2)).astype(np.float32)

    # Initialize grid indices:
    #
    # Each square in the grid stores the index of the object in that square, or
    # -1 if no object.  We don't worry about overlapping objects, and just
    # store one of them.
    grid_spacing = radius / np.sqrt(2.0)
    grid_size = int((1.0 / grid_spacing) + 1)
    grid = -np.ones((grid_size, grid_size), dtype=np.uint32)
    grid[(positions[:, 0] / grid_spacing).astype(int),
         (positions[:, 1] / grid_spacing).astype(int)] = np.arange(num_balls)

    # A matplotlib-based animator object
    animator = Animator(positions, radius * 2)

    # simulation/animation time variablees
    physics_step = 1.0 / 100  # estimate of real-time performance of simulation
    anim_step = 1.0 / 30  # FPS
    total_time = 0

    frame_count = 0

    # SUBPROBLEM 4: uncomment the code below.
    # preallocate locks for objects
    locks_ptr = preallocate_locks(num_balls)

    while True:
        with Timer() as t:
            update(positions, velocities, grid, radius, grid_size, locks_ptr,
Ejemplo n.º 31
0
    def __init__(self):

        # Initialize node, animator and state
        rospy.init_node('waypoint_planner', anonymous=True)
        self.animator = Animator(self)
        self.state = states.SteadyState(self)

        # Publisher/Subscriber variables
        self.car_speed = 0
        self.lane_heading = FloatMsgSmoother(10, 0)
        self.lane_width = 3  # meters
        self.lane_center_offset = FloatMsgSmoother(3, 0)
        self.lane_curvature = []
        self.lane_change = "none"
        self.left_lane_type = 0
        self.right_lane_type = 0
        self.obstacles = [0, 0, 0, 0, 0]

        self.obstacle_flags = [0, 0, 0, 0, 0]
        self.obstacle_detect_time = [0, 0, 0, 0, 0]
        self.saved_obstacle_pos = [0, 0, 0, 0, 0]
        self.obst_removal_time = [0, 0, 0, 0, 0]
        self.time_set = [0, 0, 0, 0, 0]
        self.obstacle_dist = [0, 0, 0, 0, 0]

        self.objects_detected = [False, False, False]

        self.odom_msg_received = False
        self.car_position = [0, 0]
        self.car_position_temp = [0, 0]

        self.car_heading = 0

        self.critical_waypoints = []
        self.curvature_waypoints = []
        self.position_history = []
        self.position_history_counter = 0
        self.stop_sign_distance = 25000.0
        self.horiz_line_distance = -1

        # Waypoint generation class members
        self.DISTANCE_BETWEEN_POINTS = 3  # meters

        # Animator class constants
        self.POSITION_HIST_DIST = 3  # meters
        self.POSITION_HIST_LENGTH = 100

        # Logging
        self.logger = logging.getLogger("planner")
        self.logger.setLevel(logging.DEBUG)

        handler = logging.StreamHandler(sys.stdout)
        FORMAT = '%(message)s'
        handler.setFormatter(logging.Formatter(FORMAT))
        self.logger.addHandler(handler)

        self.logger.info("Waypoint planner initialized.\n")

        # Subscribers
        self.car_speed_sub = rospy.Subscriber('/autodrive_sim/output/speed',
                                              Float32, self.car_speed_callback)

        self.lane_heading_sub = rospy.Subscriber(
            '/lane_detection/lane_heading', Float32,
            self.lane_heading_callback)
        self.lane_width_sub = rospy.Subscriber('/lane_detection/lane_width',
                                               Float32,
                                               self.lane_width_callback)
        self.lane_center_offset_sub = rospy.Subscriber(
            '/lane_detection/lane_center_offset', Float32,
            self.lane_center_offset_callback)
        self.lane_curvature_sub = rospy.Subscriber(
            '/lane_detection/lane_curvature', Float32MultiArray,
            self.lane_curvature_callback)
        self.lane_change_sub = rospy.Subscriber(
            '/lane_detection/lane_change/TEST', String,
            self.lane_change_callback)
        self.left_lane_type_sub = rospy.Subscriber(
            '/lane_detection/left_lane_type', Float32,
            self.left_lane_type_callback)
        self.right_lane_type_sub = rospy.Subscriber(
            '/lane_detection/right_lane_type', Float32,
            self.right_lane_type_callback)
        self.obstacle_sub = rospy.Subscriber('/lane_occupation',
                                             Int8MultiArray,
                                             self.obstacle_callback)
        self.obstacle_dist_sub = rospy.Subscriber('/obstacle_distance',
                                                  Float32MultiArray,
                                                  self.obstacle_dist_callback)

        self.car_heading_sub = rospy.Subscriber(
            '/autodrive_sim/output/heading', Float32,
            self.car_heading_callback)
        # self.self_objects_vector_sub = rospy.Subscriber('/lane_occupation', ByteMultiArray, self.detected_objects_callback)
        self.odom_sub = rospy.Subscriber("/odom", Odometry, self.odom_callback)
        self.position_sub = rospy.Subscriber('/autodrive_sim/output/position',
                                             Float32MultiArray,
                                             self.position_callback)
        self.stop_sign_dist_sub = rospy.Subscriber(
            '/sign_detection/stop_sign_distance', Float32,
            self.stop_sign_dist_callback)
        self.horiz_line_dist_sub = rospy.Subscriber(
            '/lane_detection/stop_line_distance', Float32,
            self.horiz_line_dist_callback)

        # Publisher
        self.waypoints_pub = rospy.Publisher('/autodrive_sim/output/waypoints',
                                             Float32MultiArray,
                                             queue_size=1)
        self.stop_dist_pub = rospy.Publisher('/waypoint_planner/stop_distance',
                                             Float32,
                                             queue_size=1)
        self.speed_factor = rospy.Publisher('/waypoint_planner/speed_factor',
                                            Float32MultiArray,
                                            queue_size=1)
        self.horizontal_line_activate_pub = rospy.Publisher(
            '/waypoint_planner/horizontal_line_detection', Bool, queue_size=1)
        self.lane_angle_pub = rospy.Publisher('/waypoint_planner/lane_angle',
                                              Float32,
                                              queue_size=1)
Ejemplo n.º 32
0
class WaypointPlanner:
    """generates waypoints using data from object detection and lane detection"""
    def __init__(self):

        # Initialize node, animator and state
        rospy.init_node('waypoint_planner', anonymous=True)
        self.animator = Animator(self)
        self.state = states.SteadyState(self)

        # Publisher/Subscriber variables
        self.car_speed = 0
        self.lane_heading = FloatMsgSmoother(10, 0)
        self.lane_width = 3  # meters
        self.lane_center_offset = FloatMsgSmoother(3, 0)
        self.lane_curvature = []
        self.lane_change = "none"
        self.left_lane_type = 0
        self.right_lane_type = 0
        self.obstacles = [0, 0, 0, 0, 0]

        self.obstacle_flags = [0, 0, 0, 0, 0]
        self.obstacle_detect_time = [0, 0, 0, 0, 0]
        self.saved_obstacle_pos = [0, 0, 0, 0, 0]
        self.obst_removal_time = [0, 0, 0, 0, 0]
        self.time_set = [0, 0, 0, 0, 0]
        self.obstacle_dist = [0, 0, 0, 0, 0]

        self.objects_detected = [False, False, False]

        self.odom_msg_received = False
        self.car_position = [0, 0]
        self.car_position_temp = [0, 0]

        self.car_heading = 0

        self.critical_waypoints = []
        self.curvature_waypoints = []
        self.position_history = []
        self.position_history_counter = 0
        self.stop_sign_distance = 25000.0
        self.horiz_line_distance = -1

        # Waypoint generation class members
        self.DISTANCE_BETWEEN_POINTS = 3  # meters

        # Animator class constants
        self.POSITION_HIST_DIST = 3  # meters
        self.POSITION_HIST_LENGTH = 100

        # Logging
        self.logger = logging.getLogger("planner")
        self.logger.setLevel(logging.DEBUG)

        handler = logging.StreamHandler(sys.stdout)
        FORMAT = '%(message)s'
        handler.setFormatter(logging.Formatter(FORMAT))
        self.logger.addHandler(handler)

        self.logger.info("Waypoint planner initialized.\n")

        # Subscribers
        self.car_speed_sub = rospy.Subscriber('/autodrive_sim/output/speed',
                                              Float32, self.car_speed_callback)

        self.lane_heading_sub = rospy.Subscriber(
            '/lane_detection/lane_heading', Float32,
            self.lane_heading_callback)
        self.lane_width_sub = rospy.Subscriber('/lane_detection/lane_width',
                                               Float32,
                                               self.lane_width_callback)
        self.lane_center_offset_sub = rospy.Subscriber(
            '/lane_detection/lane_center_offset', Float32,
            self.lane_center_offset_callback)
        self.lane_curvature_sub = rospy.Subscriber(
            '/lane_detection/lane_curvature', Float32MultiArray,
            self.lane_curvature_callback)
        self.lane_change_sub = rospy.Subscriber(
            '/lane_detection/lane_change/TEST', String,
            self.lane_change_callback)
        self.left_lane_type_sub = rospy.Subscriber(
            '/lane_detection/left_lane_type', Float32,
            self.left_lane_type_callback)
        self.right_lane_type_sub = rospy.Subscriber(
            '/lane_detection/right_lane_type', Float32,
            self.right_lane_type_callback)
        self.obstacle_sub = rospy.Subscriber('/lane_occupation',
                                             Int8MultiArray,
                                             self.obstacle_callback)
        self.obstacle_dist_sub = rospy.Subscriber('/obstacle_distance',
                                                  Float32MultiArray,
                                                  self.obstacle_dist_callback)

        self.car_heading_sub = rospy.Subscriber(
            '/autodrive_sim/output/heading', Float32,
            self.car_heading_callback)
        # self.self_objects_vector_sub = rospy.Subscriber('/lane_occupation', ByteMultiArray, self.detected_objects_callback)
        self.odom_sub = rospy.Subscriber("/odom", Odometry, self.odom_callback)
        self.position_sub = rospy.Subscriber('/autodrive_sim/output/position',
                                             Float32MultiArray,
                                             self.position_callback)
        self.stop_sign_dist_sub = rospy.Subscriber(
            '/sign_detection/stop_sign_distance', Float32,
            self.stop_sign_dist_callback)
        self.horiz_line_dist_sub = rospy.Subscriber(
            '/lane_detection/stop_line_distance', Float32,
            self.horiz_line_dist_callback)

        # Publisher
        self.waypoints_pub = rospy.Publisher('/autodrive_sim/output/waypoints',
                                             Float32MultiArray,
                                             queue_size=1)
        self.stop_dist_pub = rospy.Publisher('/waypoint_planner/stop_distance',
                                             Float32,
                                             queue_size=1)
        self.speed_factor = rospy.Publisher('/waypoint_planner/speed_factor',
                                            Float32MultiArray,
                                            queue_size=1)
        self.horizontal_line_activate_pub = rospy.Publisher(
            '/waypoint_planner/horizontal_line_detection', Bool, queue_size=1)
        self.lane_angle_pub = rospy.Publisher('/waypoint_planner/lane_angle',
                                              Float32,
                                              queue_size=1)

    def car_speed_callback(self, msg):
        """Processes speed messages from gps"""
        self.car_speed = msg.data

    def lane_heading_callback(self, msg):
        """Processes heading messages from lane detection"""
        limit = np.pi / 7
        heading = np.clip(msg.data, -limit, limit)
        self.lane_heading.add_value(heading)

        self.lane_angle_pub.publish(self.lane_angle())

    def lane_width_callback(self, msg):
        """Processes width messages from lane detection"""
        self.lane_width = msg.data

    def lane_center_offset_callback(self, msg):
        """Processes lane offset messages from lane detection"""
        limit = 1.5
        center = np.clip(msg.data, -limit, limit)
        self.lane_center_offset.add_value(center)

    def lane_curvature_callback(self, msg):
        """Processes lane curvature messages from lane detection"""
        self.lane_curvature = msg.data

    def lane_change_callback(self, msg):
        """Testing purposes, initiates lane change"""
        self.lane_change = msg.data

    def left_lane_type_callback(self, msg):
        """Processes left lane type messages from lane detection"""
        self.left_lane_type = msg.data

    def right_lane_type_callback(self, msg):
        """Processes right lane type messages from lane detection"""
        self.right_lane_type = msg.data

    def obstacle_callback(self, msg):
        """processes object vector from object detection"""
        self.obstacles = msg.data

    def obstacle_dist_callback(self, msg):
        """processes object vector from object detection"""
        self.obstacle_dist = msg.data

    def odom_callback(self, msg):
        """Processes messages from the odometry topic"""
        self.odom_msg_received = True
        pos = msg.pose.pose.position
        new_position = np.array([pos.x, pos.y])
        self.update_position_history(new_position)
        self.car_position = new_position
        self.car_position_temp = new_position

        ori = msg.pose.pose.orientation
        orientation_list = [ori.x, ori.y, ori.z, ori.w]
        (roll, pitch, yaw) = euler_from_quaternion(orientation_list)
        self.car_heading = yaw

    def stop_sign_dist_callback(self, msg):
        """Processes distance messages from sign detection"""
        self.stop_sign_distance = msg.data

    def horiz_line_dist_callback(self, msg):
        """Processes distance messages from horizontal line detector"""
        self.horiz_line_distance = msg.data

    def car_heading_callback(self, msg):
        """processes lane offset messages from lane detection"""
        self.car_heading = msg.data

    def position_callback(self, msg):
        """processes lane offset messages from lane detection"""
        new_position = np.array([msg.data[0], msg.data[1]])
        self.update_position_history(new_position)

    def detected_objects_callback(self, msg):
        """processes object vector from object detection"""
        for i in range(0, 3):
            if msg.data[i] == 1:
                self.objects_detected[i] = True
            else:
                self.objects_detected[i] = False

    def update_position_history(self, new_position):
        """Updates the car's position history with the given new position"""
        if len(self.position_history) == 0:
            self.position_history.append(new_position)
        else:
            if self.magnitude(self.position_history[-1],
                              new_position) > self.POSITION_HIST_DIST:
                while len(self.position_history) > self.POSITION_HIST_LENGTH:
                    self.position_history.pop(0)
                self.position_history.append(self.car_position)
        #self.car_position = new_position

    def magnitude(self, point1, point2):
        mag_vec = point2 - point1
        return np.linalg.norm(mag_vec)

    def lane_angle(self):
        """returns the current lane heading in a global frame in radians"""
        lane_global_angle = self.car_heading + (self.lane_heading.value())
        return lane_global_angle

    def point_behind_car(self, point):
        """Checks whether a point has been passed by the car"""
        # Car position
        Cx = self.car_position[0]
        Cy = self.car_position[1]

        # Lane angle offset
        angle = self.lane_angle()
        Tx = Cx + np.sin(angle)
        Ty = Cy - np.cos(angle)

        # Point behind car
        Px = point[0]
        Py = point[1]

        determinant = (Tx - Cx) * (Py - Cy) - (Ty - Cy) * (Px - Cx)
        return determinant < 0

    def rotate_waypoint(self, point):
        px, py = point
        angle_vec = (math.cos(self.car_heading), math.sin(self.car_heading))
        new_x = angle_vec[0] * px - angle_vec[1] * py
        new_y = angle_vec[1] * px + angle_vec[0] * py
        return np.array([new_x, new_y])

    def generate_waypoints(self):
        """generates and publishes waypoints to the control teams"""
        self.critical_waypoints = []

        # Add points in front of the car

        angle_scale_factor = 3
        angle = math.atan(self.lane_heading.value()) / angle_scale_factor
        last_point = np.array([0, 0])
        for i in range(1, 6):
            new_angle = angle * i
            new_point = np.array([math.cos(new_angle),
                                  math.sin(new_angle)
                                  ]) * self.DISTANCE_BETWEEN_POINTS
            new_point += last_point
            last_point = new_point

            new_point = self.rotate_waypoint(new_point)

            center_offset_value = self.lane_center_offset.value() / 3.5
            center_offset_point = np.array([0, center_offset_value])
            new_point += self.rotate_waypoint(center_offset_point)

            new_point += self.car_position
            self.critical_waypoints.append(new_point)

        self.publish_waypoints()

    def publish_waypoints(self):
        """Formats and publishes waypoints message to control teams"""
        msg = Float32MultiArray()

        # Append the car's position as the first waypoint
        #msg.data.append(self.car_position[0])
        #msg.data.append(self.car_position[1])

        # Append the critical waypoints
        for waypoint in self.critical_waypoints:
            #print "Adding Waypoint To Publish: " + str(len(msg.data))
            msg.data.append(waypoint[0])
            msg.data.append(waypoint[1])

        # Finally append the curvature waypoints (curently none)
        for waypoint in self.curvature_waypoints:
            msg.data.append(waypoint[0])
            msg.data.append(waypoint[1])

        self.waypoints_pub.publish(msg)

    def wait_for_sensor_msgs(self):
        """Waits for sensor messages to be published at least once"""
        self.logger.debug("Waiting for sensor msgs...")
        while True:
            if rospy.is_shutdown():
                sys.exit(0)
            elif self.odom_msg_received:  #and len(self.lane_curvature) > 0:
                self.logger.debug("Sensor msgs received!")
                break

    def waypoint_lanechange(self, Vc):  # Vc is current velocity in (m/s)

        if Vc < 4:
            Vc = 4

        Mlat = 0.4  # m/s^2
        r = (Vc**2) / Mlat  # circle radius

        yf1 = 5.0  # single lane : meter (final y w.r.t initial point y = 0;)
        yf2 = 7.0  # double lane

        dx1 = np.sqrt(
            (2 * (yf1 / 2) * r) -
            (yf1 / 2)**2)  # Longitudinal distance to the middle point of LC
        dx2 = np.sqrt((2 * (yf2 / 2) * r) - (yf2 / 2)**2)

        y1_left = []

        # Single lane change
        dx = dx1
        x1 = np.linspace(0, int(dx * 2),
                         int(dx + 1 + 5))  # x position for single lane change
        y1_left = np.zeros(int(dx + 1 + 5))
        y1_right = np.zeros(int(dx + 1 + 5))

        for i in range(1, len(x1), 1):
            if i < len(x1) - 5:
                if (x1[i] < dx):
                    y1_left[i] = r - np.sqrt(
                        r**2 - x1[i]**2)  # left lane change(single)
                    y1_right[i] = -y1_left[i]  # right lane change(single)
                    k = i
                else:
                    y1_left[i] = yf1 - r + np.sqrt(r**2 - x1[i]**2 +
                                                   2 * x1[i] * (2 * dx) -
                                                   (2 * dx)**2)
                    y1_right[i] = -y1_left[i]
                    k = i
            else:
                y1_left[i] = y1_left[k]
                y1_right[i] = -y1_left[i]  # right lane change(single)

    # Double lane change
        dx = dx2
        x2 = np.linspace(0, int(dx * 2),
                         int(dx + 1 + 5))  # x position for double lane change
        y2_left = np.zeros(int(dx + 1 + 5))
        y2_right = np.zeros(int(dx + 1 + 5))

        for i in range(1, len(x2), 1):
            if i < len(x2) - 5:
                if (x2[i] < dx):
                    y2_left[i] = r - np.sqrt(
                        r**2 - x2[i]**2)  # right lane change(double)
                    y2_right[i] = -y2_left[i]  # right lane change(double)
                    k = i
                else:
                    y2_left[i] = yf2 - r + np.sqrt(r**2 - x2[i]**2 +
                                                   2 * x2[i] * (2 * dx) -
                                                   (2 * dx)**2)
                    y2_right[i] = -y2_left[i]
                    k = i
            else:
                y2_left[i] = y2_left[k]
                y2_right[i] = -y2_left[i]  # right lane change(single)

        #r1 = [dx1, x1, y1_left ,y1_right]
        #r2 = [dx2, x2, y2_left, y2_right]
        #print r1
        #print r2

        return [dx1, dx2, x1, x2, y1_left, y2_left]

    def scenario(self, current_lane, dis_object_0, dis_object_1, dis_object_2,
                 v, minimum_d_1, minimum_d_2):
        #dis_object_i is the distance of object in lane i from car
        #dis_object_i is negative when there is no object in lane i

        #minimum_d_1, minimum_d_2, x1, x2, y1_left, y2_left = Waypoint_LaneChange(v)
        stop = False
        bias = 11
        possible_scenarios = [-1, -1, -1]

        print "min dist " + str(minimum_d_2)

        #Potential scenarios when the car is in lane 0 (left most lane):
        if current_lane == 0 and dis_object_0 < 0:
            possible_scenarios[0] = 3000
            print('A')
            return ([stop, possible_scenarios])
        elif current_lane == 0 and dis_object_0 > 0:
            if dis_object_0 < minimum_d_1 / 2 + bias - 2:
                stop = True
                print(minimum_d_1 / 2 + bias - 2)
                print(dis_object_0)
                print('B')
                return ([stop, possible_scenarios])

            if dis_object_0 > minimum_d_1 / 2 + bias:
                #if dis_object_0 > minimum_d_1:
                print('C_1')
                possible_scenarios[0] = 5000

            else:
                #check for potential lane change from 0 to 1:
                if dis_object_1 < 0:
                    print('C_2')
                    possible_scenarios[1] = 2000
                elif dis_object_1 > 0 and dis_object_1 > 3 / 2 * minimum_d_1 + 2 * bias:
                    print(dis_object_1)
                    print('C_3')
                    possible_scenarios[1] = dis_object_1 + 10

                #check for potential lane change from 0 to 2:
                if dis_object_1 > 3 * minimum_d_2 / 4 + bias and (
                        dis_object_2 < 0 or dis_object_2 >
                        minimum_d_1 / 2 + minimum_d_2 + 2 * bias):
                    print('C_4')
                    possible_scenarios[2] = dis_object_1

            print('C')
            return ([stop, possible_scenarios])

        #Potential scenarios when the car is in lane 1:
        elif current_lane == 1 and dis_object_1 < 0:
            possible_scenarios[1] = 3000
            print('D')
            return ([stop, possible_scenarios])
        elif current_lane == 1 and dis_object_1 > 0:
            if dis_object_1 < minimum_d_1 / 2 + bias - 2:
                stop = True
                print('E')
                return ([stop, possible_scenarios])

            if dis_object_1 > minimum_d_1 / 2 + bias:
                #if dis_object_1 > minimum_d_1:
                possible_scenarios[1] = 5000

            else:
                #check for potential lane change from 1 to 0:
                if dis_object_0 < 0:
                    possible_scenarios[0] = 2500
                elif dis_object_0 > 0 and dis_object_0 > 3 / 2 * minimum_d_1 + 2 * bias:
                    possible_scenarios[0] = dis_object_0 + 10

                #check for potential lane change from 1 to 2:
                if dis_object_2 < 0:
                    possible_scenarios[2] = 2000
                elif dis_object_2 > 0 and dis_object_2 > 3 / 2 * minimum_d_1 + 2 * bias:
                    possible_scenarios[2] = dis_object_2 + 10

            print('F')
            return ([stop, possible_scenarios])

        ##Potential scenarios when the car is in lane 2:
        if current_lane == 2 and dis_object_2 < 0:
            possible_scenarios[2] = 3000
            print('G')
            return ([stop, possible_scenarios])
        elif current_lane == 2 and dis_object_2 > 0:
            if dis_object_2 < minimum_d_1 / 2 + bias - 2:
                stop = True
                print('H')
                return ([stop, possible_scenarios])

            if dis_object_2 > minimum_d_1 / 2 + bias:
                #if dis_object_2 > minimum_d_1:
                possible_scenarios[2] = 5000

            else:
                #check for potential lane change from 2 to 1:
                if dis_object_1 < 0:
                    possible_scenarios[1] = 2000
                elif dis_object_1 > 0 and dis_object_1 > 3 / 2 * minimum_d_1 + 2 * bias:
                    possible_scenarios[1] = dis_object_1 + 10

                #check for potential lane change from 2 to 0:
                if dis_object_1 > 3 * minimum_d_2 / 4 + bias and (
                        dis_object_0 < 0 or dis_object_0 >
                        minimum_d_1 / 2 + minimum_d_2 + 2 * bias):
                    possible_scenarios[0] = dis_object_1

            print('I')
            return ([stop, possible_scenarios])

    '''
    def scenario(self, current_lane, dis_object_0, dis_object_1, dis_object_2, v):
        #dis_object_i is the distance of object in lane i
        #dis_object_i is negative when there is no object in lane i
        
        minimum_d_1, minimum_d_2 = self.dis_velo(v)
        
        stop = False
        bias = 5
        possible_scenarios = [-1, -1, -1]
        
        #Potential scenarios when the car is in lane 0 (left most lane):
        if current_lane == 0 and dis_object_0 < 0:
            possible_scenarios[0] = 3000
            return([stop, possible_scenarios])
        elif current_lane == 0 and dis_object_0 > 0: 
            if dis_object_0 < minimum_d_1:
                stop = True
                return([stop, possible_scenarios])
            
            possible_scenarios[0] = 5000
            
            #check for potential lane change from 0 to 1:
            if dis_object_1 < 0:
                possible_scenarios[1] = 2000
            elif dis_object_1 > 0 and dis_object_1 > 3/2*minimum_d_1 + 2*bias:
                possible_scenarios[1] = dis_object_1
            
            #check for potential lane change from 0 to 2:
            if dis_object_1 < 0  and (dis_object_2 < 0 or dis_object_2 > minimum_d_1+minimum_d_2+bias):
                possible_scenarios[1] = dis_object_2
            
            elif dis_object_1 > minimum_d_2/2 + bias and (dis_object_2 < 0 or dis_object_2 > minimum_d_1+minimum_d_2+bias):
                possible_scenarios[1] = dis_object_1
            
            return([stop, possible_scenarios])

        
        #Potential scenarios when the car is in lane 1:
        elif current_lane == 1 and dis_object_1 < 1:
            possible_scenarios[1] = 3000
            return([stop, possible_scenarios])
        
        elif current_lane == 1 and dis_object_1 > 0:
            if dis_object_1 < minimum_d_1/2+bias:
                stop = True
                return([stop, possible_scenarios])
            
            possible_scenarios[1] = 5000
            
            #check for potential lane change from 1 to 0:
            if dis_object_0 < 0:
                possible_scenarios[0] = 2000
            elif dis_object_0 > 0 and dis_object_0 > 3/2*minimum_d_1 + 2*bias:
                possible_scenarios[0] = dis_object_1 + dis_object_0        
        
            #check for potential lane change from 1 to 2:
            if dis_object_2 < 0:
                possible_scenarios[2] = 2000
            elif dis_object_2 > 0 and dis_object_2 > 3/2*minimum_d_1 + 2*bias:
                possible_scenarios[2] = dis_object_1 + dis_object_2
            
            return([stop, possible_scenarios])

                
        ##Potential scenarios when the car is in lane 2:
        elif current_lane == 2 and dis_object_2 < 0:
            possible_scenarios[2] = 3000
            return([stop, possible_scenarios])

        elif current_lane == 2 and dis_object_2 > 0: 
            if dis_object_2 < minimum_d_1:
                stop = True
                return([stop, possible_scenarios])
            
            possible_scenarios[2] = 5000
            
            #check for potential lane change from 2 to 1:
            if dis_object_1 < 0:
                possible_scenarios[1] = 2000
            elif dis_object_1 > 0 and dis_object_1 > 3/2*minimum_d_1 + 2*bias:
                possible_scenarios[1] = dis_object_2 + dis_object_1

            #check for potential lane change from 2 to 0:
            if dis_object_1 < 0  and (dis_object_0 < 0 or dis_object_0 > minimum_d_1+minimum_d_2+bias):
                possible_scenarios[0] = dis_object_0
            
            elif dis_object_1 > minimum_d_2/2 + bias and (dis_object_0 < 0 or dis_object_0 > minimum_d_1+minimum_d_2+bias):
                possible_scenarios[0] = dis_object_1
            
            return([stop, possible_scenarios])
    '''

    def run(self):
        # Wait for sensor messages to prime
        self.wait_for_sensor_msgs()

        rate = rospy.Rate(20)
        while not rospy.is_shutdown():
            # Enter new state
            self.state.enter_state()
            new_state = None

            # Main state loop
            while new_state is None:
                if rospy.is_shutdown():
                    return
                self.state.run_state()
                self.animator.render()
                rate.sleep()
                new_state = self.state.check_transitions()

            # Exit current state
            self.state.exit_state()
            self.state = new_state
Ejemplo n.º 33
0
class GameManager(object):
    def __init__(self, size, debug_mode, fps):
        self.size = size
        self.debug_mode = debug_mode
        self.grid = Grid(self.size)
        self.fps = fps
        self.animator = Animator(self.grid, self.fps)
        self.score = 0
        self.over = False
        self.won = False
        self.logger = self.grid.logger

        self.add_start_tiles(2)

    def restart(self):
        self.grid = Grid(self.size)
        self.animator = Animator(self.grid, self.fps)
        self.score = 0
        self.over = False
        self.won = False
        self.logger = self.grid.logger

        self.add_start_tiles(2)
        self.game_loop()

    def add_start_tiles(self, n):
        for _ in range(n):
            self.add_random_tile()

    def add_random_tile(self):
        if self.grid.cells_available():
            value = 2 if random() < 0.9 else 4
            tile = Tile(self.grid.random_available_cell(), value=value)

            self.grid.insert_tile(tile)

    def prepare_tiles(self):
        def callback(x, y, tile):
            if tile:
                tile.merged_from = None
                tile.save_position()
        self.grid.for_each_cell(callback)

    def move_tile(self, tile, cell):
        self.logger.add_log('~ move {} to {}'.format(tile, cell))
        self.grid.cells[tile.pos.x][tile.pos.y] = None
        self.grid.cells[cell.x][cell.y] = tile
        tile.update_pos(cell)

    def move(self, direction):
        if self.over:
            return

        vector = GameManager.get_vector(direction)
        traversals = self.build_traversals(vector)
        moved = False

        self.prepare_tiles()

        for x in traversals['x']:
            for y in traversals['y']:
                cell = Vector(x, y)
                tile = self.grid.cell_content(cell)

                if tile:
                    positions = self.find_farther_position(cell, vector)
                    next_tile = self.grid.cell_content(positions['next'])

                    if (next_tile and next_tile.value == tile.value and
                            not next_tile.merged_from):
                        merged = Tile(positions['next'], tile.value * 2)
                        merged.merged_from = [tile, next_tile]

                        self.logger.add_log('+ merge {} and {}'.format(tile, next_tile))

                        self.grid.insert_tile(merged)
                        self.grid.remove_tile(tile)

                        tile.update_pos(positions['next'])

                        self.score += merged.value

                        if merged.value == 2048:
                            self.won = True
                    else:
                        self.move_tile(tile, positions['farthest'])

                    if cell != tile.pos:
                        moved = True
        if moved:
            self.add_random_tile()

            if not self.move_available():
                self.over = True

    @staticmethod
    def get_vector(direction):
        dirs = [Vector(0, -1),  # left
                Vector(1, 0),   # down
                Vector(0, 1),   # right
                Vector(-1, 0)]   # up
        return dirs[direction]

    def build_traversals(self, vector):
        traversals = {'x': [], 'y': []}

        for pos in range(self.size):
            traversals['x'].append(pos)
            traversals['y'].append(pos)

        if vector.x == 1:
            traversals['x'].reverse()
        if vector.y == 1:
            traversals['y'].reverse()

        return traversals

    def find_farther_position(self, cell, vector):
        def do(_cell):
            return _cell, _cell + vector

        previous, cell = do(cell)
        while self.grid.within_bounds(cell) and self.grid.cells_available(cell):
            previous, cell = do(cell)

        return {
            'farthest': previous,
            'next': cell
        }

    def move_available(self):
        return self.grid.cells_available() or self.tile_matches_available()

    def tile_matches_available(self):
        for x in range(self.size):
            for y in range(self.size):
                tile = self.grid.cell_content(Vector(x, y))

                if tile:
                    for d in range(4):
                        vector = GameManager.get_vector(d)
                        cell = tile.pos + vector
                        if not self.grid.within_bounds(cell):
                            continue

                        other = self.grid.cell_content(cell)
                        if not other or other.value == tile.value:
                            return True
        return False

    def show_game_stats(self):
        print('WASD - control, q - quit', end='\t')
        print('Score: {}\n'.format(self.score))

    def game_loop(self):
        directions = {'a': 0, 's': 1, 'd': 2, 'w': 3}

        while True:
            if self.over:
                self.animator.show_grid()
                self.show_game_stats()
                print('\aGAME OVER')
                print('Restart? ', end='')
                if yes_no_prompt():
                    self.restart()
                else:
                    print('(-_o) /')
                break
            self.animator.show_grid()
            self.show_game_stats()
            if self.debug_mode:
                self.logger.print_logs()

            command = get_command()

            while command != 'q':
                if command in 'wasd':
                    self.move(directions[command])
                    break
                else:
                    print('try to use WASD')
                    command = get_command()
            if command == 'q':
                print('Quit? ', end='')
                if yes_no_prompt():
                    print('(-_o) /')
                    break
Ejemplo n.º 34
0
from matplotlib import animation
from mpl_toolkits.mplot3d import Axes3D

from animator import Animator
from cardioid import Cardioid
from circlegenerator import CircleGenerator
from doublefolium import DoubleFolium
from figureeigth import FigureEight
from lissajous import Lissajous
import matplotlib.pyplot as plt
from nephroid import Nephroid
from polar import Polar
from projection import RectangleProjection
from rhodonea import Rhodonea
from sextic import Sextic
from tricuspoid import Tricuspoid
from trifolium import Trifolium

numpoints = 100
Animator(DoubleFolium(), numpoints)('doublefolium.mp4')
Animator(Sextic(), numpoints)('sextic.mp4')
Animator(Lissajous(3, 2), numpoints)('lissajous.mp4')
Animator(Trifolium(), numpoints)('trifolium.mp4')
Animator(Tricuspoid(), numpoints)('tricuspoid.mp4')
Animator(Cardioid(), numpoints)('cardioid.mp4')
Animator(Nephroid(), numpoints)('nephroid.mp4')
Animator(Rhodonea(5), numpoints)('rhodonea5.mp4')
Animator(Rhodonea(3), numpoints)('rhodonea3.mp4')
Animator(Rhodonea(5), numpoints)('rhodonea6.mp4')
Animator(FigureEight(), numpoints)('figure8.mp4')
Ejemplo n.º 35
0
class Controller(QtGui.QDockWidget,
                 ui_controller.Ui_controller):
    def __init__(self, parent, visualizer_view, status_bar):
        super(Controller, self).__init__(parent)
        self.parent = parent
        self.setupUi(self)

        self.visualizer_view = visualizer_view
        self.status_bar = status_bar

    @QtCore.pyqtSignature("int")
    def on_frame_number_spin_box_valueChanged(self, frame_number):
        self.frame_number_slider.setValue(frame_number)
        if frame_number > self.session.warm_up_time:
            self.warm_up_status_label.setText('<span style="color: green;">Warm-up completed</span>')
        else:
            self.warm_up_status_label.setText('<strong style="color: red;">Warming up</strong>')
        self.set_time_display(frame_number)
        self.animator.go_to_frame_number(frame_number)

    @QtCore.pyqtSignature("int")
    def on_frame_number_slider_valueChanged(self, frame_number):
        self.frame_number_spin_box.setValue(frame_number)

    def set_time_display(self, frame_number):
        elapsed = frame_number * self.session.frame_interval
        time = self.start_time.addMSecs(elapsed)

        hour = time.hour()
        if hour >= 12:
            self.am_or_pm_push_button.setChecked(True)
        else:
            self.am_or_pm_push_button.setChecked(False)
            # In 12-hour time, the 0th hour is not spoken; in its place is the 12th hour.
            if hour == 0:
                hour = 12
        self.hour_spin_box.setValue(hour)
        self.minute_spin_box.setValue(time.minute())
        self.second_spin_box.setValue(time.second())
        self.fraction_second_spin_box.setValue(time.msec() / self.session.frame_interval)
        #print "%02d:%02d:%02d.%d %s" % (time.hour(), time.minute(), time.second(),
        #                                time.msec() / self.session.frame_interval,
        #                                "AM" if self.am_or_pm_push_button.isChecked() else "PM")

    @QtCore.pyqtSignature("int")
    def on_hour_spin_box_valueChanged(self, hour):
        self.set_frame_number()

    @QtCore.pyqtSignature("int")
    def on_minute_spin_box_valueChanged(self, hour):
        self.set_frame_number()

    @QtCore.pyqtSignature("int")
    def on_second_spin_box_valueChanged(self, hour):
        self.set_frame_number()

    @QtCore.pyqtSignature("int")
    def on_fraction_second_spin_box_valueChanged(self, hour):
        self.set_frame_number()

    @QtCore.pyqtSignature("bool")
    def on_am_or_pm_push_button_toggled(self, state):
        if state:
            self.am_or_pm_push_button.setText("PM")
        else:
            self.am_or_pm_push_button.setText("AM")
        self.set_frame_number()

    def set_frame_number(self):
        hour = self.hour_spin_box.value()
        minute = self.minute_spin_box.value()
        second = self.second_spin_box.value()
        milli_second = self.fraction_second_spin_box.value() * self.session.frame_interval
        if self.am_or_pm_push_button.isChecked():
            if hour != 12:
                hour += 12
        elif hour == 12:
            hour -= 12

        time = QtCore.QTime(hour, minute, second, milli_second)
        elapsed = self.start_time.msecsTo(time)
        elapsed /= self.session.frame_interval

        if elapsed < 0:
            elapsed = 0
            self.set_time_display(elapsed)
        elif elapsed > self.session.total_run_time:
            elapsed = self.session.total_run_time - 1
            self.set_time_display(elapsed)
        self.frame_number_spin_box.setValue(elapsed)
        #print "setting frame number to %d" % elapsed

    @QtCore.pyqtSignature("int")
    def on_playback_speed_slider_valueChanged(self, speed):
        self.set_playback_speed(speed)

    def set_playback_speed(self, speed):
        if speed == 0:
            self.playback_speed_line_edit.setText(u"1\u00d7")
            self.playback_speed_description_label.setText("real-time")
            self.interval = self.session.frame_interval
        elif speed > 0:
            factor = speed + 1
            self.playback_speed_line_edit.setText(u"%d\u00d7" % factor)
            self.playback_speed_description_label.setText("quick-time")
            self.interval = self.session.frame_interval / factor
        else:
            factor = -speed + 1
            self.playback_speed_line_edit.setText(u"\u00f7%d" % factor)
            self.playback_speed_description_label.setText("slow-motion")
            self.interval = self.session.frame_interval * factor

    @QtCore.pyqtSignature("")
    def on_load_file_push_button_clicked(self):
        file_name = QtGui.QFileDialog.getOpenFileName(self.parent, "Choose file to load", ".")
        if len(file_name):
            self.load_log_file(str(file_name))

    def load_log_file(self, file_name):
        self.scene = Graphics_scene(self)
        self.visualizer_view.setScene(self.scene)

        self.session = Session()
        self.road_network = Network()
        self.animator = Animator(self.scene)
        self.city = City(self.animator)

        if file_name.endswith(".gz"):
            input_file = GzipFile(file_name)
        elif file_name.endswith(".bz2"):
            input_file = BZ2File(file_name)
        else:
            input_file = open(file_name, 'r')
        for line in input_file:
            if self.session.parse(line):
                continue
            if self.road_network.parse(line):
                continue
            if self.city.parse(line):
                continue
        input_file.close()

        self.road_network.resolve()
        self.scene.draw_road_network(self.road_network)

        self.set_ready_to_run(file_name)

    def set_ready_to_run(self, file_name):
        self.log_file_name_line_edit.setText(file_name)
        # Show the agents at frame 0.
        self.animator.go_to_frame_number(0)

        self.start_time = QtCore.QTime(self.session.start_hour, self.session.start_minute,
                                       self.session.start_second)
        last_frame_number = self.session.total_run_time
        self.frame_number_spin_box.setValue(0)
        self.frame_number_spin_box.setMaximum(last_frame_number - 1)
        self.last_frame_number_spin_box.setMaximum(last_frame_number + 1)
        self.last_frame_number_spin_box.setValue(last_frame_number)
        self.warm_up_time_line_edit.setText("%d (frames)" % self.session.warm_up_time)
        self.frame_number_slider.setMaximum(last_frame_number + 1)
        if last_frame_number / self.frame_number_slider.tickInterval() < 20:
            self.frame_number_slider.setTickPosition(QtGui.QSlider.TicksAbove)
        else:
            self.frame_number_slider.setTickPosition(QtGui.QSlider.NoTicks)
        self.set_time_display(0)
        end_time = self.start_time.addMSecs(last_frame_number * self.session.frame_interval)
        self.end_time_line_edit.setTime(end_time)
        self.set_playback_speed(self.playback_speed_slider.value())

        self.frame_number_spin_box.setEnabled(True)
        self.frame_number_slider.setEnabled(True)
        self.hour_spin_box.setEnabled(True)
        self.minute_spin_box.setEnabled(True)
        self.second_spin_box.setEnabled(True)
        self.fraction_second_spin_box.setEnabled(True)
        self.am_or_pm_push_button.setEnabled(True)
        self.playback_speed_slider.setEnabled(True)
        self.stop_or_go_push_button.setEnabled(True)

    @QtCore.pyqtSignature("bool")
    def on_stop_or_go_push_button_toggled(self, state):
        button = self.stop_or_go_push_button
        if button.isChecked():
            button.setText("Stop")
            self.switch_to_running_mode()
        else:
            button.setText("Go")
            self.switch_to_paused_mode()

    def switch_to_running_mode(self):
        self.frame_number_spin_box.setEnabled(False)
        self.frame_number_slider.setEnabled(False)
        self.hour_spin_box.setEnabled(False)
        self.minute_spin_box.setEnabled(False)
        self.second_spin_box.setEnabled(False)
        self.fraction_second_spin_box.setEnabled(False)
        self.am_or_pm_push_button.setEnabled(False)
        self.load_file_push_button.setEnabled(False)
        self.is_running = True
        QtCore.QTimer.singleShot(self.interval, self.run)

    def switch_to_paused_mode(self):
        self.is_running = False
        self.frame_number_spin_box.setEnabled(True)
        self.frame_number_slider.setEnabled(True)
        self.hour_spin_box.setEnabled(True)
        self.minute_spin_box.setEnabled(True)
        self.second_spin_box.setEnabled(True)
        self.fraction_second_spin_box.setEnabled(True)
        self.am_or_pm_push_button.setEnabled(True)
        self.load_file_push_button.setEnabled(True)

    def run(self):
        self.frame_number_spin_box.stepUp()

        if self.is_running:
            QtCore.QTimer.singleShot(self.interval, self.run)
Ejemplo n.º 36
0
    def visualize_dbs(self,
                      n_epochs,
                      prop,
                      property_perc,
                      alternate,
                      animation_name='anim'):

        X_train_noisy_sc = StandardScaler().fit_transform(self.X_train_noisy)

        print('Creating animations...', end='')
        animator = Animator(X_train_noisy_sc,
                            self.y_train,
                            prop,
                            property_perc,
                            alternate,
                            n_epochs,
                            interval=100)

        criterion, weights_boosting = init_exponential_loss(X_train_noisy_sc)

        dbs_rand, train_losses_rand, train_accs_rand, \
        test_accs_rand, subsets_rand = self.toy_run_recompute(
            self.model_clean, self.X_train_noisy, self.y_train, self.X_test_noisy, self.y_test, n_epochs,
            criterion=criterion, prop=prop, property_perc=property_perc,
            most=True, random=True, alternate=False)
        dbs_top, train_losses_top, train_accs_top, \
        test_accs_top, subsets_top = self.toy_run_recompute(
            self.model_clean, self.X_train_noisy, self.y_train, self.X_test_noisy, self.y_test, n_epochs,
            criterion=criterion, prop=prop, property_perc=property_perc,
            most=True, random=False, alternate=alternate)
        dbs_bottom, train_losses_bottom, train_accs_bottom, \
        test_accs_bottom, subsets_bottom = self.toy_run_recompute(
            self.model_clean, self.X_train_noisy, self.y_train, self.X_test_noisy, self.y_test, n_epochs,
            criterion=criterion, prop=prop, property_perc=property_perc,
            most=False, random=False, alternate=alternate)
        dbs_all, train_losses_all, train_accs_all, \
        test_accs_all, subsets_all = self.toy_run_recompute(
            self.model_clean,
            self.X_train_noisy, self.y_train, self.X_test_noisy, self.y_test, n_epochs,
            criterion=criterion, prop=prop, property_perc=1.0,
            most=False, random=True, alternate=False)

        dbs = [dbs_rand, dbs_top, dbs_bottom, dbs_all]
        train_accs = [
            train_accs_rand, train_accs_top, train_accs_bottom, train_accs_all
        ]
        test_accs = [
            test_accs_rand, test_accs_top, test_accs_bottom, test_accs_all
        ]

        self.y_train = convert_labels(self.y_train, [-1, 1], [0, 1])
        self.y_valid = convert_labels(self.y_valid, [-1, 1], [0, 1])
        self.y_test = convert_labels(self.y_test, [-1, 1], [0, 1])
        criterion = nn.BCELoss()
        self.model_clean = FFSimpleNet(input_dim=self.n_features,
                                       output_dim=1,
                                       activation='sigmoid')
        optimizer = torch.optim.SGD(self.model_clean.parameters(), lr=0.01)
        self.train_accs_clean, self.val_accs_clean, self.test_accs_clean, epoch, model = early_stopping(
            self.model_clean,
            self.train_dl,
            self.valid_dl,
            self.test_dl,
            criterion=criterion,
            optimizer=optimizer,
            device=device,
            verbose=False)

        dbs_rand, train_losses_rand, train_accs_rand, \
        test_accs_rand, subsets_rand = self.toy_run_recompute(
            self.model_clean, self.X_train_noisy, self.y_train, self.X_test_noisy, self.y_test, n_epochs,
            criterion=criterion, prop=prop, property_perc=property_perc,
            most=True, random=True, alternate=False)
        dbs_top, train_losses_top, train_accs_top, \
        test_accs_top, subsets_top = self.toy_run_recompute(
            self.model_clean, self.X_train_noisy, self.y_train, self.X_test_noisy, self.y_test, n_epochs,
            criterion=criterion, prop=prop, property_perc=property_perc,
            most=True, random=False, alternate=alternate)
        dbs_bottom, train_losses_bottom, train_accs_bottom, \
        test_accs_bottom, subsets_bottom = self.toy_run_recompute(
            self.model_clean, self.X_train_noisy, self.y_train, self.X_test_noisy, self.y_test, n_epochs,
            criterion=criterion, prop=prop, property_perc=property_perc,
            most=False, random=False, alternate=alternate)
        dbs_all, train_losses_all, train_accs_all, \
        test_accs_all, subsets_all = self.toy_run_recompute(
            self.model_clean,
            self.X_train_noisy, self.y_train, self.X_test_noisy, self.y_test, n_epochs,
            criterion=criterion, prop=prop, property_perc=1.0,
            most=False, random=True, alternate=False)

        dbs = dbs + [dbs_rand, dbs_top, dbs_bottom, dbs_all]
        train_accs = train_accs + [
            train_accs_rand, train_accs_top, train_accs_bottom, train_accs_all
        ]
        test_accs = test_accs + [
            test_accs_rand, test_accs_top, test_accs_bottom, test_accs_all
        ]
        labels = [
            'rand_exp', 'top_exp', 'bottom_exp', 'all_exp', 'rand_bce',
            'top_bce', 'bottom_bce', 'all_bce'
        ]
        colors = [
            'orange', 'green', 'red', 'blue', 'orange', 'green', 'red', 'blue'
        ]
        markers = ['--', '--', '--', '--', '.-', '.-', '.-', '.-']
        animation = animator.run(dbs, train_accs, test_accs, labels, colors,
                                 markers)

        print('done!')
        print('Saving animation...', end='')
        animation.save('animations/{}={}_{}={}.gif'.format(
            prop, property_perc, 'alternate', alternate),
                       dpi=100)
        print('done!')
Ejemplo n.º 37
0
class Entity(object):
    'Most every interactive thing in the game is an Entity.'

    # arbitrary, and meaningless for the most part.
    DIST = 48

    def __init__(self, ent, anim):
        'ent can be None if all of the entity manipulating methods (below) are overridden.'
        self.ent = ent
        self.stats = StatSet()
        self.stats.hp = 1

        self._animator = Animator()
        self._anim = anim
        self.direction = dir.DOWN  # as good as any
        self.interruptable = True  # if false, no state changes will occur
        self.invincible = False
        self.state = self.defaultState()

    #def __del__(self):
    #    print 'deleting ', self

    def destroy(self):
        for k in self.__dict__.keys():
            self.__dict__[k] = None

    def update(self):
        'Main update routine.  Override if you must, use the state mechanism if you can.'
        self.animate()
        try:
            return self._state()
        except StopIteration:
            self.state = self.defaultState()
            return self._state()

    def die(self, *args):
        system.engine.destroyEntity(self)

    # if recoil is nonzero, the enemy is blown backwards in a direction,
    # at some speed.  The default direction is backwards
    def hurt(self, amount, recoilSpeed=0, recoilDir=None):
        if self.invincible:
            return

        if recoilDir is None:
            recoilDir = dir.invert[self.direction]

        if self.stats.hp <= amount:
            self.stats.hp = 0
            self.die()
        else:
            self.stats.hp -= amount
            self.state = self.hurtState(recoilSpeed, recoilDir)

        #if damage display option on
        if system.engine.player.stats.damageind:
            x = self.ent.x + self.ent.hotwidth / 2 - gui.default_font.StringWidth(
                str(amount)) / 2
            y = self.ent.y
            system.engine.addThing(
                DamageCaption(str(amount), x, y, 40, 250, 0, 0))

    def _setState(self, newState):
        '''Tries to be psychic.  Generators are recognized, other crap is assumed
        to be a function that returns a generator.'''
        if self.interruptable or self._state is None:
            if isinstance(newState, GeneratorType):
                self._state = newState.next
            elif newState is None:
                self._state = None
            else:
                assert False, 'Entity.state property *must* be a generator!!! (got %s)' % ` newState `

    state = property(fset=_setState)

    def defaultState(self):
        while True:
            yield None

    def hurtState(self, recoilSpeed, recoilDir):
        class Restorer(object):
            def __init__(_self):
                _self.s = self.speed
                _self.i = self.invincible

            def __del__(_self):
                self.speed = _self.s
                self.invincible = _self.i

        rest = Restorer()

        dx, dy = dir.delta[recoilDir]
        self.speed = recoilSpeed
        self.move(recoilDir, 1000000)  # just go until I say stop
        self.anim = 'hurt'

        self.invincible = True
        t = 64
        while True:
            t -= 1
            if t <= 34: self.invincible = rest.i
            self.speed -= t / 8

            yield None

            if t <= 0 or self.speed <= 0: break

        self.direction = dir.invert[self.direction]
        self.ent.Stop()
        yield None

    def detectCollision(self, rect):
        '''
        Returns a list of entities that are within the rect.
        The rect's position is taken as being relative to the
        entity's position.  This is useful for attacks and such.
        '''
        '''
        entsat = []
        for i in range(ika.Map.layercount): #hack to be able to attack other enemies on other layers
            rect = (
                rect[0] + self.x,
                rect[1] + self.y,
                rect[2], rect[3],
                i)
            entsat += [system.engine.entFromEnt[e] for e in
            ika.EntitiesAt(*rect) if e in system.engine.entFromEnt]    
        
        return entsat   
        '''
        rect = (rect[0] + self.x, rect[1] + self.y, rect[2], rect[3],
                self.layer)

        return [
            system.engine.entFromEnt[e] for e in ika.EntitiesAt(*rect)
            if e in system.engine.entFromEnt
        ]

    def touches(self, ent):
        return self.ent.Touches(ent.ent)

    # Entity methods.  Most everything that involves an ika entity should be done here.
    def up(self):
        self.ent.MoveTo(self.ent.x, self.ent.y - self.DIST)
        self.direction = dir.UP

    def down(self):
        self.ent.MoveTo(self.ent.x, self.ent.y + self.DIST)
        self.direction = dir.DOWN

    def left(self):
        self.ent.MoveTo(self.ent.x - self.DIST, self.ent.y)
        self.direction = dir.LEFT

    def right(self):
        self.ent.MoveTo(self.ent.x + self.DIST, self.ent.y)
        self.direction = dir.RIGHT

    def upLeft(self):
        self.ent.MoveTo(self.ent.x - self.DIST, self.ent.y - self.DIST)
        self.direction = dir.UPLEFT

    def upRight(self):
        self.ent.MoveTo(self.ent.x + self.DIST, self.ent.y - self.DIST)
        self.direction = dir.UPRIGHT

    def downLeft(self):
        self.ent.MoveTo(self.ent.x - self.DIST, self.ent.y + self.DIST)
        self.direction = dir.DOWNLEFT

    def downRight(self):
        self.ent.MoveTo(self.ent.x + self.DIST, self.ent.y + self.DIST)
        self.direction = dir.DOWNRIGHT

    def move(self, d, dist=DIST):
        dx, dy = dir.delta[d]
        self.direction = d
        self.ent.MoveTo(int(self.ent.x + dist * dx),
                        int(self.ent.y + dist * dy))

    def getObs(self, d):  #hack hack hack
        dlist = [
            dir.delta[d], dir.delta[dir.rotateCounterCW45[d]],
            dir.delta[dir.rotateCW45[d]]
        ]
        for dd in dlist:
            dx, dy = dd
            cx = self.x + self.ent.hotwidth / 2
            cy = self.y + self.ent.hotheight / 2
            dist = (self.ent.hotwidth + self.ent.hotheight) / 2 + 8

            if (ika.Map.GetObs(int(cx + dist * dx), int(cx + dist * dy),
                               self.ent.layer)):
                return True
        return False

    def isMoving(self):
        return self.ent.IsMoving()

    def stop(self):
        self.ent.Stop()

    def getX(self):
        return self.ent.x

    def getY(self):
        return self.ent.y

    def setX(self, value):
        self.ent.x = value

    def setY(self, value):
        self.ent.y = value

    def getSpeed(self):
        return self.ent.speed

    def setSpeed(self, v):
        self.ent.speed = v

    def getLayer(self):
        return self.ent.layer

    def setLayer(self, v):
        self.ent.layer = v

    def animate(self):
        self._animator.update(1)
        self.ent.specframe = self._animator.curFrame

    def setAnim(self, value, loop=False):
        a, loop = self._anim[value]
        self._animator.setAnim(a[self.direction], loop)

    # properties.  Because they're high in fibre.
    x = property(getX, setX)
    y = property(getY, setY)
    moving = property(isMoving)
    speed = property(getSpeed, setSpeed)
    layer = property(getLayer, setLayer)
    anim = property(fset=setAnim)