def __init__(self, kwargs): Character.__init__(self, kwargs) self._populate_images() # TODO: Move animation cycling to PSprite? self._walk_ctr = 0 # Walk cycle counter self._fpi = kwargs["fpi"] self._prev_image_series = "none" # Name of previous animation # Signal that this Player has died self.dead = False # Number of frames to display dead animation self._dead_ctr = 60 # Platform the player is standing on self._floor = None # Player control characteristics self._max_vx = kwargs["horizontal_speed"] self._ix = kwargs["horizontal_inertia"] # _mx: current momentum in x-direction self._mx = 0.0 self._j_multi = kwargs["multi_jumps"] # _jumps: current number of consecutive jumps without landing self._jumps = 0 # Is SPACE pressed? Don't jump again w/out SPACE being released # Defaults to True to prevent jump on spawn self._k_space = True # Vertical velocity at jump time _j_t is given by # v = _j_a * (_j_t + _j_o) + _j_b # _j_t keeps track of how far into a jump the sprite is # _j_t == None means that a jump is not in progress # _j_o is an offset that ensures that _j_t == 0 is the apogee (useful # for determining speed when falling of floors) self._j_a = kwargs["vertical_acceleration"] self._j_b = kwargs["jump_velocity"] self._j_t = None self._j_o = -self._j_b / self._j_a # Vertical point direction ((-1, 0, 1) == (down, forward, up)) self._point_v = 0 # Horizontal point direction ((-1, 1) == (left, right)) self._point_h = 1 # Make sure control characteristics make sense if self._max_vx <= 0.0: raise ValueError("horizontal_speed must be > 0.0") if self._ix <= 0.0: raise ValueError("horizontal_inertia must be > 0.0") if self._j_multi <= 0: raise ValueError("multi_jumps must be > 0") if self._j_a <= 0.0: raise ValueError("vertical_acceleration must be > 0.0") if self._j_b >= 0.0: raise ValueError("jump_velocity must be < 0.0") # Set targets targets = kwargs["targets"] if targets is None: targets = pygame.sprite.RenderPlain() # Set up default Projectile container self.fired_projectiles = kwargs["fired_projectiles"] b_kwargs = { "owner": self, "floors": kwargs["floors"], "l_walls": kwargs["l_walls"], "r_walls": kwargs["r_walls"], "ceilings": kwargs["ceilings"], "projectile_class": kwargs["projectile_class"], "fired_projectiles": self.fired_projectiles, "max_in_flight": kwargs["max_in_flight"], "max_shots": -1, "targets": targets, "centerx": 0, "centery": 0, "decoration_list": kwargs["decoration_list"] } self._box = ProjectileBox(b_kwargs) # Stack of Boxes self._box_stack = [] # Invincibility counter after being hit self._invincible_counter = 0 # Decorations # Invincibility r = math.ceil(max(self.rect.width, self.rect.height) * 0.75) self._dec_invinc_surf = \ pygame.Surface((r*2, r*2), flags=SRCALPHA).convert_alpha() self._dec_invinc_rect = self._dec_invinc_surf.get_rect() pygame.draw.circle(self._dec_invinc_surf, (0, 80, 0), (r, r), r - 1, 1) # Got hit self._hit_counter = 0 self._dec_hit_surf = \ pygame.Surface((r*2, r*2), flags=SRCALPHA).convert_alpha() self._dec_hit_rect = self._dec_invinc_surf.get_rect() pygame.draw.circle(self._dec_hit_surf, (255, 0, 0), (r, r), r - 1, 0)
def __init__(self, kwargs): Character.__init__(self, kwargs) self._populate_images() self.points = kwargs["points"] # Location and default movement characteristics # True x- and y-coordinates are calculated and stored in floats to # allow for sub-pixel motion, but collision detection, drawing, etc. # are done on integers self._xf = float(self.rect.centerx) self._yf = float(self.rect.centery) # Useful for Baddies that just float and bounce around self._speed = 1.0 self._dir = 0.0 # Animation-related variables # TODO: Move animation cycling to PSprite? self._walk_ctr = 0 self._fpi = kwargs["fpi"] self._prev_image_series = "none" # Whether to draw hit decoration self._hit_counter = 0 # Number of frames to display dead animation self._dead_ctr = 30 # Set targets targets = kwargs["targets"] if targets is None: targets = pygame.sprite.RenderPlain() # Set up Projectiles # Use fired_projectiles from owner so Projectiles can outlive the # Baddie b_kwargs = { "owner": self, "floors": kwargs["floors"], "l_walls": kwargs["l_walls"], "r_walls": kwargs["r_walls"], "ceilings": kwargs["ceilings"], "projectile_class": kwargs["projectile_class"], "fired_projectiles": kwargs["fired_projectiles"], "max_in_flight": kwargs["max_in_flight"], "max_shots": -1, "targets": kwargs["targets"], "centerx": 0, "centery": 0, "decoration_list": kwargs["decoration_list"] } self._box = ProjectileBox(b_kwargs) # Decorations # Invincibility r = math.ceil(max(self.rect.width, self.rect.height) * 0.75) self._dec_invinc_surf = \ pygame.Surface((r*2, r*2), flags=SRCALPHA).convert_alpha() self._dec_invinc_rect = self._dec_invinc_surf.get_rect() pygame.draw.circle(self._dec_invinc_surf, (255, 0, 0), (r, r), r - 1, 0)