diff --git a/actor.py b/actor.py index e809a85..72f51f9 100644 --- a/actor.py +++ b/actor.py @@ -1,43 +1,39 @@ ########################################### # Created on 1-9-2013. Miguel Angel Astor # ########################################### +import math + import pygame -from animation import Animation + +import math_utils ACTOR_STATES = { 'IDLE': 0, 'MOVING': 1 } -class BaseActor: - """ Represents any game object. This is the parent class for the actor - category of objects. It's behaviors are empty. """ - def __init__(self, name, visible, solid, position): - """ Initializes the actor object. """ - # Conditions and parameters. +class BaseActor(pygame.sprite.Sprite): + def __init__(self, id, image, name = "Default", animated = False, visible = True, solid = True): + super(Sprite, self).__init__() + + self.id = id self.name = name - self.alive = True # The Actor should be updated. - self.animated = False # The Actor has animations. - self.visible = visible # The Actor should be rendered. - self.solid = solid # The actor can collide with other actors - # All sprites for an actor are stored as a list of pygame sprites. - # The list starts empty. Sprites must be added with the add_sprite method. - self.sprites = [] - # Animations are stored as a key (Animation angle), - # value (Animation object) pairs. Animations are added with the - # add_animation method. - self.animations = {} - # Parameters for direction and movement. - self.position = list(position) - self.speed = [0, 0] # [X speed, Y speed]. - self.max_speed = [100, 100] # 100 pixels per second. - self.acceleration = [0, 0] # Ditto. - # Collision detection information. AABB and Bounding circle. - self.b_box = [0, 0] # [X length, Y length]. - self.radius = 0.0 - # Parameters for rendering. - self.angle = 0 - self.scale = 1.0 + self.animated = animated + self.visible = visible + self.solid = solid - def is_alive(self): - return self.alive + self.angle = 0.0 + self.position = [0, 0] + self.velocity = [0, 0] + self.acceleration = [0, 0] + self.max_velocity = [0, 0] + self.friction = 1.0 + + self.image = image + self.rect = self.image.get_rect() + + def get_id(self): + return self.id + + def get_name(self): + return self.name def is_animated(self): return self.animated @@ -48,19 +44,70 @@ class BaseActor: def is_solid(self): return self.solid - def destroy(self): - self.alive = False + def get_position(self): + return self.position - def set_visible(self, visible): - self.visible = visible + def set_position(self, new_pos): + self.position = list(new_pos) - def toggle_visible(self): - self.visible = not self.visible + def get_velocity(self): + return self.get_velocity - def set_solid(self, solid): - self.solid = solid + def set_velocity(self, new_vel): + self.velocity = list(new_vel) - def toggle_solid(self): - self.solid = not self.solid + def get_acceleration(self): + return self.acceleration - def add_sprite(self, filename) + def set_acceleration(self, new_accel): + self.acceleration = list(new_accel) + + def get_max_velocity(self): + return self.max_velocity + + def set_max_velocity(self, max_vel): + self.max_velocity = list(max_vel) + + def get_friction(self): + return self.get_friction + + def set_friction(self, new_friction): + self.friction = new_friction + +class BulletActor(BaseActor): + """ Actor class with fixed velocity bullet behavior. """ + def __init__(self, id, image, name = "Default", animated = False, visible = True, solid = True, frame_rate = 60): + super(BaseActor, self).__init__(id, image, name, animated, visible, solid) + self.then = 0 + self.now = 0 + self.frame_rate = frame_rate + self.moving = False + + def is_moving(self): + return self.moving + + def move(self): + self.moving = True + + def stop(self): + self.moving = False + + def update(self): + # Calculate the time elapsed between the previous call to update and this one. + self.now = pygame.time.get_ticks() + delta_t = self.now - self.then + if delta_t < 0: + delta_t = 0 # Compensatefor overflow of self.now + + if self.moving: + # Then we update it's velocity components compensating for time. + self.velocity[0] += (self.velocity[0] * delta_t) * (self.frame_rate / 1000) + self.velocity[1] += (self.velocity[1] * delta_t) * (self.frame_rate / 1000) + # Finally we take friction into account. + self.velocity[0] *= self.friction + self.velocity[1] *= self.friction + + # TODO: Update animation frame if any. + + self.then = self.now + diff --git a/animation.py b/animation.py index 351f26c..f3cc635 100644 --- a/animation.py +++ b/animation.py @@ -3,15 +3,15 @@ ########################################### class Animation: - """ This class represents an animated sprite. No sprite information is - stored in this class, only sprite indexes. """ - def __init__(self, name): + """ This class represents an animated sprite. """ + def __init__(self, name = "Default", num_frames = 1, frame_start_offset = 0): """ Initializes an empty animation. """ self.fps = 0 self.name = name self.looping = False + self.frame_start = frame_start_offset + self.num_frames = num_frames self.current_frame = 0 - self.frames = [] def __str__(self): """ Returns a string representation of this animation. """ @@ -19,30 +19,11 @@ class Animation: " :: Looping : " + str(self.looping) + " :: Current frame: " + str(self.current_frame) - def add_frame(self, frame): - """ Adds a frame to this animation. Frames should be added in order. """ - self.frames.append(frame) - - def get_next_frame(self): - """ Returns the current frame of the animation. Moves the current frame - count by one. """ - if(self.looping): - self.current_frame = (self.current_frame + 1) % len(self.frames) - elif (self.current_frame == len(self.frames) - 1): - pass - return self.frames[self.current_frame] - def get_current_frame(self): """ Returns the current frame of the animation. """ return self.current_frame - def set_current_frame(self, frame): - """ Changes the current frame of the animation. """ - # The frame is wrapped modulo the number of frames to ensure it is valid. - self.current_frame = frame % len(self.frames) - def get_looping(self): - """ Returns wether this animation should loop or not. """ return self.looping def set_looping(self, looping): @@ -53,3 +34,10 @@ class Animation: def set_frames_per_second(self, fps): self.fps = fps + + def generate_animation(self): + """ Generator function that returns the next frame of the animation. """ + while True: + for frame in range(self.frame_start, self.frame_start + self.num_frames): + self.current_frame = frame - self.frame_start + yield frame diff --git a/math_utils.py b/math_utils.py new file mode 100644 index 0000000..8ddfd2f --- /dev/null +++ b/math_utils.py @@ -0,0 +1,6 @@ +########################################### +# Created on 1-9-2013. Miguel Angel Astor # +########################################### + +def angle_to_vector(angle): + return [math.cos(angle), math.sin(angle)]