Ejemplo n.º 1
0
class SimpleVehicle2d(BasePointMass2d):
    """Point mass with steering behaviour."""

    def __init__(self, position, radius, velocity, spritedata=None):
        BasePointMass2d.__init__(self, position, radius, velocity, spritedata)
        # Steering behavior class for this object.
        self.steering = SteeringBehavior(self)

    def move(self, delta_t=1.0):
        """Compute steering force and update rectilinear motion."""
        force = self.steering.compute_force()
        BasePointMass2d.move(self, delta_t, force)
Ejemplo n.º 2
0
    def __init__(self,
                 img_surf,
                 img_rect,
                 position,
                 radius,
                 velocity):
        # Must call pygame's Sprite.__init__ first!
        pygame.sprite.Sprite.__init__(self)

        # Pygame image information for blitting
        self.orig = img_surf
        self.image = img_surf
        self.rect = img_rect

        # Basic object physics
        # Note: We can't use self.pos = position here because of Point2d's
        # __init__ method (and lack of __copy__), ditto for self.vel.
        self.pos = Point2d(position[0], position[1])  # Center of object
        self.radius = radius                          # Bounding radius
        self.vel = Point2d(velocity[0], velocity[1])  # Current Velocity

        # Normalized front vector in world coordinates.
        # This stays aligned with the object's velocity.
        try:
            self.front = velocity.unit()
        except ZeroDivisionError:
            # If velocity is <0,0>, set facing to screen upwards
            self.front = Point2d(0,-1)
        self.left = Point2d(-self.front[1], self.front[0])
        self._rotate_for_blit()

        # Movement constraints (defaults from steering_constants.py)
        ## TODO: Put these in the function argument, perhaps as **kwargs
        self.mass = POINTMASS2D_MASS
        self.maxspeed = POINTMASS2D_MAXSPEED
        self.maxforce = POINTMASS2D_MAXFORCE

        # Steering behavior class for this object.
        self.steering = SteeringBehavior(self)
Ejemplo n.º 3
0
class PointMass2d(pygame.sprite.Sprite):
    """A pygame.Sprite with rectilnear motion and steering behaviour.

    Parameters
    ----------
    img_surf: pygame.Surface
        Contains the image of the sprite; used for blitting.
    img_rect: pygame.rect
        Pygame rectangle with sprite information; used for blitting.
    position: Point2d
        Center of mass, in screen coordinates.
    radius: float
        Bounding radius of the object.
    velocity: Point2d
        Velocity vector, in screen coordinates. Facing will match this.

    Notes
    -----
    This class uses Pygame's sprite group update() method to automatically
    compute steering and rectilinear motion along with each render update.
    While this works for simple use, it is causing integaration issues with
    other update (i.e., FSM and messaging). The new BasePointMass2d class
    above decouples the pygame sprite update, and may be more appropriate.
    As a result, it is not unlikely that this class will be deprecated.

    It is recommended to use the load_image() function above to initialize
    the image surface and rectangle, then pass the values to this function.
    One reason for separating these functions is to allow multiple sprites
    to use the same image file.
    """

    def __init__(self,
                 img_surf,
                 img_rect,
                 position,
                 radius,
                 velocity):
        # Must call pygame's Sprite.__init__ first!
        pygame.sprite.Sprite.__init__(self)

        # Pygame image information for blitting
        self.orig = img_surf
        self.image = img_surf
        self.rect = img_rect

        # Basic object physics
        # Note: We can't use self.pos = position here because of Point2d's
        # __init__ method (and lack of __copy__), ditto for self.vel.
        self.pos = Point2d(position[0], position[1])  # Center of object
        self.radius = radius                          # Bounding radius
        self.vel = Point2d(velocity[0], velocity[1])  # Current Velocity

        # Normalized front vector in world coordinates.
        # This stays aligned with the object's velocity.
        try:
            self.front = velocity.unit()
        except ZeroDivisionError:
            # If velocity is <0,0>, set facing to screen upwards
            self.front = Point2d(0,-1)
        self.left = Point2d(-self.front[1], self.front[0])
        self._rotate_for_blit()

        # Movement constraints (defaults from steering_constants.py)
        ## TODO: Put these in the function argument, perhaps as **kwargs
        self.mass = POINTMASS2D_MASS
        self.maxspeed = POINTMASS2D_MAXSPEED
        self.maxforce = POINTMASS2D_MAXFORCE

        # Steering behavior class for this object.
        self.steering = SteeringBehavior(self)

    def move(self, delta_t=1.0, force_vector=None):
        """Update the position of this object, using its current velocity.

        Parameters
        ----------
        delta_t: float
            Time increment since last move.
        """
        self.pos = self.pos + self.vel.scale(delta_t)
        self.rect.center = self.pos[0], self.pos[1]

        if force_vector:
            # Don't exceed our maximum force; compute acceleration/velocity
            force_vector.truncate(self.maxforce)
            accel = force_vector.scale(delta_t/self.mass)
            self.vel = self.vel + accel

        # Don't exceed our maximum speed
        self.vel.truncate(self.maxspeed)

        # If velocity is very small, skip alignment to avoid jittering.
        if self.vel.sqnorm() > SPEED_EPSILON:
            self.front = self.vel.unit()
            self.left = Point2d(-self.front[1], self.front[0])

    def _rotate_for_blit(self):
        """Used to rotate the object's image prior to blitting.

        Note
        ----
        This function does not update any physics, it only rotates the image,
        based on the object's current front vector.
        """
        theta = self.front.angle()*SCREEN_DEG
        center = self.rect.center
        self.image = pygame.transform.rotate(self.orig, theta)
        self.rect = self.image.get_rect()
        self.rect.center = center

    def update(self, delta_t=1.0):
        """Update the object's position and autonomous steering force.

        Parameters
        ----------
        dt: float
            Time increment since last update. Default = 1.0.

        Note
        ----
        This function is intended to be called by a pygame.Group.update()
        method each cycle. This passes the same arguments to each sprite, so
        instance-specific behaviour must be computed within this function.
        """

        # Autonomous steering behaviour computed here
        force = self.steering.compute_force()

        # Movement and image rotation:
        self.move(delta_t, force)
        self._rotate_for_blit()

        # Used to draw force vectors for pygame demos
        self.force = force
Ejemplo n.º 4
0
 def __init__(self, position, radius, velocity, spritedata=None):
     BasePointMass2d.__init__(self, position, radius, velocity, spritedata)
     # Steering behavior class for this object.
     self.steering = SteeringBehavior(self)