You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1142 lines
42 KiB
1142 lines
42 KiB
|
|
import pygame as pg
|
|
from .. import setup, tools
|
|
from .. import constants as c
|
|
from . import powerups
|
|
|
|
|
|
class Mario(pg.sprite.Sprite):
|
|
def __init__(self):
|
|
pg.sprite.Sprite.__init__(self)
|
|
self.sprite_sheet = setup.GFX['mario_bros']
|
|
|
|
self.setup_timers()
|
|
self.setup_state_booleans()
|
|
self.setup_forces()
|
|
self.setup_counters()
|
|
self.load_images_from_sheet()
|
|
|
|
self.state = c.WALK
|
|
self.image = self.right_frames[self.frame_index]
|
|
self.rect = self.image.get_rect()
|
|
self.mask = pg.mask.from_surface(self.image)
|
|
|
|
self.key_timer = 0
|
|
|
|
|
|
def setup_timers(self):
|
|
"""Sets up timers for animations"""
|
|
self.walking_timer = 0
|
|
self.invincible_animation_timer = 0
|
|
self.invincible_start_timer = 0
|
|
self.fire_transition_timer = 0
|
|
self.death_timer = 0
|
|
self.transition_timer = 0
|
|
self.last_fireball_time = 0
|
|
self.hurt_invisible_timer = 0
|
|
self.hurt_invisible_timer2 = 0
|
|
self.flag_pole_timer = 0
|
|
|
|
|
|
def setup_state_booleans(self):
|
|
"""Sets up booleans that affect Mario's behavior"""
|
|
self.facing_right = True
|
|
self.allow_jump = True
|
|
self.dead = False
|
|
self.invincible = False
|
|
self.big = False
|
|
self.fire = False
|
|
self.allow_fireball = True
|
|
self.in_transition_state = False
|
|
self.hurt_invincible = False
|
|
self.in_castle = False
|
|
self.crouching = False
|
|
self.losing_invincibility = False
|
|
|
|
|
|
def setup_forces(self):
|
|
"""Sets up forces that affect Mario's velocity"""
|
|
self.x_vel = 0
|
|
self.y_vel = 0
|
|
self.max_x_vel = c.MAX_WALK_SPEED
|
|
self.max_y_vel = c.MAX_Y_VEL
|
|
self.x_accel = c.WALK_ACCEL
|
|
self.jump_vel = c.JUMP_VEL
|
|
self.gravity = c.GRAVITY
|
|
|
|
|
|
def setup_counters(self):
|
|
"""These keep track of various total for important values"""
|
|
self.frame_index = 0
|
|
self.invincible_index = 0
|
|
self.fire_transition_index = 0
|
|
self.fireball_count = 0
|
|
self.flag_pole_right = 0
|
|
|
|
|
|
def load_images_from_sheet(self):
|
|
"""Extracts Mario images from his sprite sheet and assigns
|
|
them to appropriate lists"""
|
|
self.right_frames = []
|
|
self.left_frames = []
|
|
|
|
self.right_small_normal_frames = []
|
|
self.left_small_normal_frames = []
|
|
self.right_small_green_frames = []
|
|
self.left_small_green_frames = []
|
|
self.right_small_red_frames = []
|
|
self.left_small_red_frames = []
|
|
self.right_small_black_frames = []
|
|
self.left_small_black_frames = []
|
|
|
|
self.right_big_normal_frames = []
|
|
self.left_big_normal_frames = []
|
|
self.right_big_green_frames = []
|
|
self.left_big_green_frames = []
|
|
self.right_big_red_frames = []
|
|
self.left_big_red_frames = []
|
|
self.right_big_black_frames = []
|
|
self.left_big_black_frames = []
|
|
|
|
self.right_fire_frames = []
|
|
self.left_fire_frames = []
|
|
|
|
|
|
#Images for normal small mario#
|
|
|
|
self.right_small_normal_frames.append(
|
|
self.get_image(178, 32, 12, 16)) # Right [0]
|
|
self.right_small_normal_frames.append(
|
|
self.get_image(80, 32, 15, 16)) # Right walking 1 [1]
|
|
self.right_small_normal_frames.append(
|
|
self.get_image(96, 32, 16, 16)) # Right walking 2 [2]
|
|
self.right_small_normal_frames.append(
|
|
self.get_image(112, 32, 16, 16)) # Right walking 3 [3]
|
|
self.right_small_normal_frames.append(
|
|
self.get_image(144, 32, 16, 16)) # Right jump [4]
|
|
self.right_small_normal_frames.append(
|
|
self.get_image(130, 32, 14, 16)) # Right skid [5]
|
|
self.right_small_normal_frames.append(
|
|
self.get_image(160, 32, 15, 16)) # Death frame [6]
|
|
self.right_small_normal_frames.append(
|
|
self.get_image(320, 8, 16, 24)) # Transition small to big [7]
|
|
self.right_small_normal_frames.append(
|
|
self.get_image(241, 33, 16, 16)) # Transition big to small [8]
|
|
self.right_small_normal_frames.append(
|
|
self.get_image(194, 32, 12, 16)) # Frame 1 of flag pole Slide [9]
|
|
self.right_small_normal_frames.append(
|
|
self.get_image(210, 33, 12, 16)) # Frame 2 of flag pole slide [10]
|
|
|
|
|
|
#Images for small green mario (for invincible animation)#
|
|
|
|
self.right_small_green_frames.append(
|
|
self.get_image(178, 224, 12, 16)) # Right standing [0]
|
|
self.right_small_green_frames.append(
|
|
self.get_image(80, 224, 15, 16)) # Right walking 1 [1]
|
|
self.right_small_green_frames.append(
|
|
self.get_image(96, 224, 16, 16)) # Right walking 2 [2]
|
|
self.right_small_green_frames.append(
|
|
self.get_image(112, 224, 15, 16)) # Right walking 3 [3]
|
|
self.right_small_green_frames.append(
|
|
self.get_image(144, 224, 16, 16)) # Right jump [4]
|
|
self.right_small_green_frames.append(
|
|
self.get_image(130, 224, 14, 16)) # Right skid [5]
|
|
|
|
#Images for red mario (for invincible animation)#
|
|
|
|
self.right_small_red_frames.append(
|
|
self.get_image(178, 272, 12, 16)) # Right standing [0]
|
|
self.right_small_red_frames.append(
|
|
self.get_image(80, 272, 15, 16)) # Right walking 1 [1]
|
|
self.right_small_red_frames.append(
|
|
self.get_image(96, 272, 16, 16)) # Right walking 2 [2]
|
|
self.right_small_red_frames.append(
|
|
self.get_image(112, 272, 15, 16)) # Right walking 3 [3]
|
|
self.right_small_red_frames.append(
|
|
self.get_image(144, 272, 16, 16)) # Right jump [4]
|
|
self.right_small_red_frames.append(
|
|
self.get_image(130, 272, 14, 16)) # Right skid [5]
|
|
|
|
#Images for black mario (for invincible animation)#
|
|
|
|
self.right_small_black_frames.append(
|
|
self.get_image(178, 176, 12, 16)) # Right standing [0]
|
|
self.right_small_black_frames.append(
|
|
self.get_image(80, 176, 15, 16)) # Right walking 1 [1]
|
|
self.right_small_black_frames.append(
|
|
self.get_image(96, 176, 16, 16)) # Right walking 2 [2]
|
|
self.right_small_black_frames.append(
|
|
self.get_image(112, 176, 15, 16)) # Right walking 3 [3]
|
|
self.right_small_black_frames.append(
|
|
self.get_image(144, 176, 16, 16)) # Right jump [4]
|
|
self.right_small_black_frames.append(
|
|
self.get_image(130, 176, 14, 16)) # Right skid [5]
|
|
|
|
|
|
#Images for normal big Mario
|
|
|
|
self.right_big_normal_frames.append(
|
|
self.get_image(176, 0, 16, 32)) # Right standing [0]
|
|
self.right_big_normal_frames.append(
|
|
self.get_image(81, 0, 16, 32)) # Right walking 1 [1]
|
|
self.right_big_normal_frames.append(
|
|
self.get_image(97, 0, 15, 32)) # Right walking 2 [2]
|
|
self.right_big_normal_frames.append(
|
|
self.get_image(113, 0, 15, 32)) # Right walking 3 [3]
|
|
self.right_big_normal_frames.append(
|
|
self.get_image(144, 0, 16, 32)) # Right jump [4]
|
|
self.right_big_normal_frames.append(
|
|
self.get_image(128, 0, 16, 32)) # Right skid [5]
|
|
self.right_big_normal_frames.append(
|
|
self.get_image(336, 0, 16, 32)) # Right throwing [6]
|
|
self.right_big_normal_frames.append(
|
|
self.get_image(160, 10, 16, 22)) # Right crouching [7]
|
|
self.right_big_normal_frames.append(
|
|
self.get_image(272, 2, 16, 29)) # Transition big to small [8]
|
|
self.right_big_normal_frames.append(
|
|
self.get_image(193, 2, 16, 30)) # Frame 1 of flag pole slide [9]
|
|
self.right_big_normal_frames.append(
|
|
self.get_image(209, 2, 16, 29)) # Frame 2 of flag pole slide [10]
|
|
|
|
#Images for green big Mario#
|
|
|
|
self.right_big_green_frames.append(
|
|
self.get_image(176, 192, 16, 32)) # Right standing [0]
|
|
self.right_big_green_frames.append(
|
|
self.get_image(81, 192, 16, 32)) # Right walking 1 [1]
|
|
self.right_big_green_frames.append(
|
|
self.get_image(97, 192, 15, 32)) # Right walking 2 [2]
|
|
self.right_big_green_frames.append(
|
|
self.get_image(113, 192, 15, 32)) # Right walking 3 [3]
|
|
self.right_big_green_frames.append(
|
|
self.get_image(144, 192, 16, 32)) # Right jump [4]
|
|
self.right_big_green_frames.append(
|
|
self.get_image(128, 192, 16, 32)) # Right skid [5]
|
|
self.right_big_green_frames.append(
|
|
self.get_image(336, 192, 16, 32)) # Right throwing [6]
|
|
self.right_big_green_frames.append(
|
|
self.get_image(160, 202, 16, 22)) # Right Crouching [7]
|
|
|
|
#Images for red big Mario#
|
|
|
|
self.right_big_red_frames.append(
|
|
self.get_image(176, 240, 16, 32)) # Right standing [0]
|
|
self.right_big_red_frames.append(
|
|
self.get_image(81, 240, 16, 32)) # Right walking 1 [1]
|
|
self.right_big_red_frames.append(
|
|
self.get_image(97, 240, 15, 32)) # Right walking 2 [2]
|
|
self.right_big_red_frames.append(
|
|
self.get_image(113, 240, 15, 32)) # Right walking 3 [3]
|
|
self.right_big_red_frames.append(
|
|
self.get_image(144, 240, 16, 32)) # Right jump [4]
|
|
self.right_big_red_frames.append(
|
|
self.get_image(128, 240, 16, 32)) # Right skid [5]
|
|
self.right_big_red_frames.append(
|
|
self.get_image(336, 240, 16, 32)) # Right throwing [6]
|
|
self.right_big_red_frames.append(
|
|
self.get_image(160, 250, 16, 22)) # Right crouching [7]
|
|
|
|
#Images for black big Mario#
|
|
|
|
self.right_big_black_frames.append(
|
|
self.get_image(176, 144, 16, 32)) # Right standing [0]
|
|
self.right_big_black_frames.append(
|
|
self.get_image(81, 144, 16, 32)) # Right walking 1 [1]
|
|
self.right_big_black_frames.append(
|
|
self.get_image(97, 144, 15, 32)) # Right walking 2 [2]
|
|
self.right_big_black_frames.append(
|
|
self.get_image(113, 144, 15, 32)) # Right walking 3 [3]
|
|
self.right_big_black_frames.append(
|
|
self.get_image(144, 144, 16, 32)) # Right jump [4]
|
|
self.right_big_black_frames.append(
|
|
self.get_image(128, 144, 16, 32)) # Right skid [5]
|
|
self.right_big_black_frames.append(
|
|
self.get_image(336, 144, 16, 32)) # Right throwing [6]
|
|
self.right_big_black_frames.append(
|
|
self.get_image(160, 154, 16, 22)) # Right Crouching [7]
|
|
|
|
|
|
#Images for Fire Mario#
|
|
|
|
self.right_fire_frames.append(
|
|
self.get_image(176, 48, 16, 32)) # Right standing [0]
|
|
self.right_fire_frames.append(
|
|
self.get_image(81, 48, 16, 32)) # Right walking 1 [1]
|
|
self.right_fire_frames.append(
|
|
self.get_image(97, 48, 15, 32)) # Right walking 2 [2]
|
|
self.right_fire_frames.append(
|
|
self.get_image(113, 48, 15, 32)) # Right walking 3 [3]
|
|
self.right_fire_frames.append(
|
|
self.get_image(144, 48, 16, 32)) # Right jump [4]
|
|
self.right_fire_frames.append(
|
|
self.get_image(128, 48, 16, 32)) # Right skid [5]
|
|
self.right_fire_frames.append(
|
|
self.get_image(336, 48, 16, 32)) # Right throwing [6]
|
|
self.right_fire_frames.append(
|
|
self.get_image(160, 58, 16, 22)) # Right crouching [7]
|
|
self.right_fire_frames.append(
|
|
self.get_image(0, 0, 0, 0)) # Place holder [8]
|
|
self.right_fire_frames.append(
|
|
self.get_image(193, 50, 16, 29)) # Frame 1 of flag pole slide [9]
|
|
self.right_fire_frames.append(
|
|
self.get_image(209, 50, 16, 29)) # Frame 2 of flag pole slide [10]
|
|
|
|
|
|
#The left image frames are numbered the same as the right
|
|
#frames but are simply reversed.
|
|
|
|
for frame in self.right_small_normal_frames:
|
|
new_image = pg.transform.flip(frame, True, False)
|
|
self.left_small_normal_frames.append(new_image)
|
|
|
|
for frame in self.right_small_green_frames:
|
|
new_image = pg.transform.flip(frame, True, False)
|
|
self.left_small_green_frames.append(new_image)
|
|
|
|
for frame in self.right_small_red_frames:
|
|
new_image = pg.transform.flip(frame, True, False)
|
|
self.left_small_red_frames.append(new_image)
|
|
|
|
for frame in self.right_small_black_frames:
|
|
new_image = pg.transform.flip(frame, True, False)
|
|
self.left_small_black_frames.append(new_image)
|
|
|
|
for frame in self.right_big_normal_frames:
|
|
new_image = pg.transform.flip(frame, True, False)
|
|
self.left_big_normal_frames.append(new_image)
|
|
|
|
for frame in self.right_big_green_frames:
|
|
new_image = pg.transform.flip(frame, True, False)
|
|
self.left_big_green_frames.append(new_image)
|
|
|
|
for frame in self.right_big_red_frames:
|
|
new_image = pg.transform.flip(frame, True, False)
|
|
self.left_big_red_frames.append(new_image)
|
|
|
|
for frame in self.right_big_black_frames:
|
|
new_image = pg.transform.flip(frame, True, False)
|
|
self.left_big_black_frames.append(new_image)
|
|
|
|
for frame in self.right_fire_frames:
|
|
new_image = pg.transform.flip(frame, True, False)
|
|
self.left_fire_frames.append(new_image)
|
|
|
|
|
|
self.normal_small_frames = [self.right_small_normal_frames,
|
|
self.left_small_normal_frames]
|
|
|
|
self.green_small_frames = [self.right_small_green_frames,
|
|
self.left_small_green_frames]
|
|
|
|
self.red_small_frames = [self.right_small_red_frames,
|
|
self.left_small_red_frames]
|
|
|
|
self.black_small_frames = [self.right_small_black_frames,
|
|
self.left_small_black_frames]
|
|
|
|
self.invincible_small_frames_list = [self.normal_small_frames,
|
|
self.green_small_frames,
|
|
self.red_small_frames,
|
|
self.black_small_frames]
|
|
|
|
self.normal_big_frames = [self.right_big_normal_frames,
|
|
self.left_big_normal_frames]
|
|
|
|
self.green_big_frames = [self.right_big_green_frames,
|
|
self.left_big_green_frames]
|
|
|
|
self.red_big_frames = [self.right_big_red_frames,
|
|
self.left_big_red_frames]
|
|
|
|
self.black_big_frames = [self.right_big_black_frames,
|
|
self.left_big_black_frames]
|
|
|
|
self.fire_frames = [self.right_fire_frames,
|
|
self.left_fire_frames]
|
|
|
|
self.invincible_big_frames_list = [self.normal_big_frames,
|
|
self.green_big_frames,
|
|
self.red_big_frames,
|
|
self.black_big_frames]
|
|
|
|
self.all_images = [self.right_big_normal_frames,
|
|
self.right_big_black_frames,
|
|
self.right_big_red_frames,
|
|
self.right_big_green_frames,
|
|
self.right_small_normal_frames,
|
|
self.right_small_green_frames,
|
|
self.right_small_red_frames,
|
|
self.right_small_black_frames,
|
|
self.left_big_normal_frames,
|
|
self.left_big_black_frames,
|
|
self.left_big_red_frames,
|
|
self.left_big_green_frames,
|
|
self.left_small_normal_frames,
|
|
self.left_small_red_frames,
|
|
self.left_small_green_frames,
|
|
self.left_small_black_frames]
|
|
|
|
|
|
self.right_frames = self.normal_small_frames[0]
|
|
self.left_frames = self.normal_small_frames[1]
|
|
|
|
|
|
def get_image(self, x, y, width, height):
|
|
"""Extracts image from sprite sheet"""
|
|
image = pg.Surface([width, height])
|
|
rect = image.get_rect()
|
|
|
|
image.blit(self.sprite_sheet, (0, 0), (x, y, width, height))
|
|
image.set_colorkey(c.BLACK)
|
|
image = pg.transform.scale(image,
|
|
(int(rect.width*c.SIZE_MULTIPLIER),
|
|
int(rect.height*c.SIZE_MULTIPLIER)))
|
|
return image
|
|
|
|
|
|
def update(self, keys, game_info, fire_group):
|
|
"""Updates Mario's states and animations once per frame"""
|
|
self.current_time = game_info[c.CURRENT_TIME]
|
|
self.handle_state(keys, fire_group)
|
|
self.check_for_special_state()
|
|
self.animation()
|
|
|
|
|
|
def handle_state(self, keys, fire_group):
|
|
"""Determines Mario's behavior based on his state"""
|
|
if self.state == c.STAND:
|
|
self.standing(keys, fire_group)
|
|
elif self.state == c.WALK:
|
|
self.walking(keys, fire_group)
|
|
elif self.state == c.JUMP:
|
|
self.jumping(keys, fire_group)
|
|
elif self.state == c.FALL:
|
|
self.falling(keys, fire_group)
|
|
elif self.state == c.DEATH_JUMP:
|
|
self.jumping_to_death()
|
|
elif self.state == c.SMALL_TO_BIG:
|
|
self.changing_to_big()
|
|
elif self.state == c.BIG_TO_FIRE:
|
|
self.changing_to_fire()
|
|
elif self.state == c.BIG_TO_SMALL:
|
|
self.changing_to_small()
|
|
elif self.state == c.FLAGPOLE:
|
|
self.flag_pole_sliding()
|
|
elif self.state == c.BOTTOM_OF_POLE:
|
|
self.sitting_at_bottom_of_pole()
|
|
elif self.state == c.WALKING_TO_CASTLE:
|
|
self.walking_to_castle()
|
|
elif self.state == c.END_OF_LEVEL_FALL:
|
|
self.falling_at_end_of_level()
|
|
|
|
|
|
def standing(self, keys, fire_group):
|
|
"""This function is called if Mario is standing still"""
|
|
self.check_to_allow_jump(keys)
|
|
self.check_to_allow_fireball(keys)
|
|
|
|
self.frame_index = 0
|
|
self.x_vel = 0
|
|
self.y_vel = 0
|
|
|
|
if keys[tools.keybinding['action']]:
|
|
if self.fire and self.allow_fireball:
|
|
self.shoot_fireball(fire_group)
|
|
|
|
if keys[tools.keybinding['down']]:
|
|
self.crouching = True
|
|
|
|
if keys[tools.keybinding['left']]:
|
|
self.facing_right = False
|
|
self.get_out_of_crouch()
|
|
self.state = c.WALK
|
|
elif keys[tools.keybinding['right']]:
|
|
self.facing_right = True
|
|
self.get_out_of_crouch()
|
|
self.state = c.WALK
|
|
elif keys[tools.keybinding['jump']]:
|
|
if self.allow_jump:
|
|
if self.big:
|
|
setup.SFX['big_jump'].play()
|
|
else:
|
|
setup.SFX['small_jump'].play()
|
|
self.state = c.JUMP
|
|
self.y_vel = c.JUMP_VEL
|
|
else:
|
|
self.state = c.STAND
|
|
|
|
if not keys[tools.keybinding['down']]:
|
|
self.get_out_of_crouch()
|
|
|
|
|
|
def get_out_of_crouch(self):
|
|
"""Get out of crouch"""
|
|
bottom = self.rect.bottom
|
|
left = self.rect.x
|
|
if self.facing_right:
|
|
self.image = self.right_frames[0]
|
|
else:
|
|
self.image = self.left_frames[0]
|
|
self.rect = self.image.get_rect()
|
|
self.rect.bottom = bottom
|
|
self.rect.x = left
|
|
self.crouching = False
|
|
|
|
|
|
def check_to_allow_jump(self, keys):
|
|
"""Check to allow Mario to jump"""
|
|
if not keys[tools.keybinding['jump']]:
|
|
self.allow_jump = True
|
|
|
|
|
|
def check_to_allow_fireball(self, keys):
|
|
"""Check to allow the shooting of a fireball"""
|
|
if not keys[tools.keybinding['action']]:
|
|
self.allow_fireball = True
|
|
|
|
|
|
def shoot_fireball(self, powerup_group):
|
|
"""Shoots fireball, allowing no more than two to exist at once"""
|
|
setup.SFX['fireball'].play()
|
|
self.fireball_count = self.count_number_of_fireballs(powerup_group)
|
|
|
|
if (self.current_time - self.last_fireball_time) > 200:
|
|
if self.fireball_count < 2:
|
|
self.allow_fireball = False
|
|
powerup_group.add(
|
|
powerups.FireBall(self.rect.right, self.rect.y, self.facing_right))
|
|
self.last_fireball_time = self.current_time
|
|
|
|
self.frame_index = 6
|
|
if self.facing_right:
|
|
self.image = self.right_frames[self.frame_index]
|
|
else:
|
|
self.image = self.left_frames[self.frame_index]
|
|
|
|
|
|
def count_number_of_fireballs(self, powerup_group):
|
|
"""Count number of fireballs that exist in the level"""
|
|
fireball_list = []
|
|
|
|
for powerup in powerup_group:
|
|
if powerup.name == c.FIREBALL:
|
|
fireball_list.append(powerup)
|
|
|
|
return len(fireball_list)
|
|
|
|
|
|
def walking(self, keys, fire_group):
|
|
"""This function is called when Mario is in a walking state
|
|
It changes the frame, checks for holding down the run button,
|
|
checks for a jump, then adjusts the state if necessary"""
|
|
|
|
self.check_to_allow_jump(keys)
|
|
self.check_to_allow_fireball(keys)
|
|
|
|
if self.frame_index == 0:
|
|
self.frame_index += 1
|
|
self.walking_timer = self.current_time
|
|
else:
|
|
if (self.current_time - self.walking_timer >
|
|
self.calculate_animation_speed()):
|
|
if self.frame_index < 3:
|
|
self.frame_index += 1
|
|
else:
|
|
self.frame_index = 1
|
|
|
|
self.walking_timer = self.current_time
|
|
|
|
if keys[tools.keybinding['action']]:
|
|
self.max_x_vel = c.MAX_RUN_SPEED
|
|
self.x_accel = c.RUN_ACCEL
|
|
if self.fire and self.allow_fireball:
|
|
self.shoot_fireball(fire_group)
|
|
else:
|
|
self.max_x_vel = c.MAX_WALK_SPEED
|
|
self.x_accel = c.WALK_ACCEL
|
|
|
|
if keys[tools.keybinding['jump']]:
|
|
if self.allow_jump:
|
|
if self.big:
|
|
setup.SFX['big_jump'].play()
|
|
else:
|
|
setup.SFX['small_jump'].play()
|
|
self.state = c.JUMP
|
|
if self.x_vel > 4.5 or self.x_vel < -4.5:
|
|
self.y_vel = c.JUMP_VEL - .5
|
|
else:
|
|
self.y_vel = c.JUMP_VEL
|
|
|
|
|
|
if keys[tools.keybinding['left']]:
|
|
self.get_out_of_crouch()
|
|
self.facing_right = False
|
|
if self.x_vel > 0:
|
|
self.frame_index = 5
|
|
self.x_accel = c.SMALL_TURNAROUND
|
|
else:
|
|
self.x_accel = c.WALK_ACCEL
|
|
|
|
if self.x_vel > (self.max_x_vel * -1):
|
|
self.x_vel -= self.x_accel
|
|
if self.x_vel > -0.5:
|
|
self.x_vel = -0.5
|
|
elif self.x_vel < (self.max_x_vel * -1):
|
|
self.x_vel += self.x_accel
|
|
|
|
elif keys[tools.keybinding['right']]:
|
|
self.get_out_of_crouch()
|
|
self.facing_right = True
|
|
if self.x_vel < 0:
|
|
self.frame_index = 5
|
|
self.x_accel = c.SMALL_TURNAROUND
|
|
else:
|
|
self.x_accel = c.WALK_ACCEL
|
|
|
|
if self.x_vel < self.max_x_vel:
|
|
self.x_vel += self.x_accel
|
|
if self.x_vel < 0.5:
|
|
self.x_vel = 0.5
|
|
elif self.x_vel > self.max_x_vel:
|
|
self.x_vel -= self.x_accel
|
|
|
|
else:
|
|
if self.facing_right:
|
|
if self.x_vel > 0:
|
|
self.x_vel -= self.x_accel
|
|
else:
|
|
self.x_vel = 0
|
|
self.state = c.STAND
|
|
else:
|
|
if self.x_vel < 0:
|
|
self.x_vel += self.x_accel
|
|
else:
|
|
self.x_vel = 0
|
|
self.state = c.STAND
|
|
|
|
|
|
def calculate_animation_speed(self):
|
|
"""Used to make walking animation speed be in relation to
|
|
Mario's x-vel"""
|
|
if self.x_vel == 0:
|
|
animation_speed = 130
|
|
elif self.x_vel > 0:
|
|
animation_speed = 130 - (self.x_vel * (13))
|
|
else:
|
|
animation_speed = 130 - (self.x_vel * (13) * -1)
|
|
|
|
return animation_speed
|
|
|
|
|
|
def jumping(self, keys, fire_group):
|
|
"""Called when Mario is in a JUMP state."""
|
|
self.allow_jump = False
|
|
self.frame_index = 4
|
|
self.gravity = c.JUMP_GRAVITY
|
|
self.y_vel += self.gravity
|
|
self.check_to_allow_fireball(keys)
|
|
|
|
if self.y_vel >= 0 and self.y_vel < self.max_y_vel:
|
|
self.gravity = c.GRAVITY
|
|
self.state = c.FALL
|
|
|
|
if keys[tools.keybinding['left']]:
|
|
if self.x_vel > (self.max_x_vel * - 1):
|
|
self.x_vel -= self.x_accel
|
|
|
|
elif keys[tools.keybinding['right']]:
|
|
if self.x_vel < self.max_x_vel:
|
|
self.x_vel += self.x_accel
|
|
|
|
if not keys[tools.keybinding['jump']]:
|
|
self.gravity = c.GRAVITY
|
|
self.state = c.FALL
|
|
|
|
if keys[tools.keybinding['action']]:
|
|
if self.fire and self.allow_fireball:
|
|
self.shoot_fireball(fire_group)
|
|
|
|
|
|
def falling(self, keys, fire_group):
|
|
"""Called when Mario is in a FALL state"""
|
|
self.check_to_allow_fireball(keys)
|
|
if self.y_vel < c.MAX_Y_VEL:
|
|
self.y_vel += self.gravity
|
|
|
|
if keys[tools.keybinding['left']]:
|
|
if self.x_vel > (self.max_x_vel * - 1):
|
|
self.x_vel -= self.x_accel
|
|
|
|
elif keys[tools.keybinding['right']]:
|
|
if self.x_vel < self.max_x_vel:
|
|
self.x_vel += self.x_accel
|
|
|
|
if keys[tools.keybinding['action']]:
|
|
if self.fire and self.allow_fireball:
|
|
self.shoot_fireball(fire_group)
|
|
|
|
|
|
def jumping_to_death(self):
|
|
"""Called when Mario is in a DEATH_JUMP state"""
|
|
if self.death_timer == 0:
|
|
self.death_timer = self.current_time
|
|
elif (self.current_time - self.death_timer) > 500:
|
|
self.rect.y += self.y_vel
|
|
self.y_vel += self.gravity
|
|
|
|
|
|
def start_death_jump(self, game_info):
|
|
"""Used to put Mario in a DEATH_JUMP state"""
|
|
self.dead = True
|
|
game_info[c.MARIO_DEAD] = True
|
|
self.y_vel = -11
|
|
self.gravity = .5
|
|
self.frame_index = 6
|
|
self.image = self.right_frames[self.frame_index]
|
|
self.state = c.DEATH_JUMP
|
|
self.in_transition_state = True
|
|
|
|
|
|
def changing_to_big(self):
|
|
"""Changes Mario's image attribute based on time while
|
|
transitioning to big"""
|
|
self.in_transition_state = True
|
|
|
|
if self.transition_timer == 0:
|
|
self.transition_timer = self.current_time
|
|
elif self.timer_between_these_two_times(135, 200):
|
|
self.set_mario_to_middle_image()
|
|
elif self.timer_between_these_two_times(200, 365):
|
|
self.set_mario_to_small_image()
|
|
elif self.timer_between_these_two_times(365, 430):
|
|
self.set_mario_to_middle_image()
|
|
elif self.timer_between_these_two_times(430, 495):
|
|
self.set_mario_to_small_image()
|
|
elif self.timer_between_these_two_times(495, 560):
|
|
self.set_mario_to_middle_image()
|
|
elif self.timer_between_these_two_times(560, 625):
|
|
self.set_mario_to_big_image()
|
|
elif self.timer_between_these_two_times(625, 690):
|
|
self.set_mario_to_small_image()
|
|
elif self.timer_between_these_two_times(690, 755):
|
|
self.set_mario_to_middle_image()
|
|
elif self.timer_between_these_two_times(755, 820):
|
|
self.set_mario_to_big_image()
|
|
elif self.timer_between_these_two_times(820, 885):
|
|
self.set_mario_to_small_image()
|
|
elif self.timer_between_these_two_times(885, 950):
|
|
self.set_mario_to_big_image()
|
|
self.state = c.WALK
|
|
self.in_transition_state = False
|
|
self.transition_timer = 0
|
|
self.become_big()
|
|
|
|
|
|
def timer_between_these_two_times(self,start_time, end_time):
|
|
"""Checks if the timer is at the right time for the action. Reduces
|
|
the ugly code."""
|
|
if (self.current_time - self.transition_timer) >= start_time\
|
|
and (self.current_time - self.transition_timer) < end_time:
|
|
return True
|
|
|
|
|
|
def set_mario_to_middle_image(self):
|
|
"""During a change from small to big, sets mario's image to the
|
|
transition/middle size"""
|
|
if self.facing_right:
|
|
self.image = self.normal_small_frames[0][7]
|
|
else:
|
|
self.image = self.normal_small_frames[1][7]
|
|
bottom = self.rect.bottom
|
|
centerx = self.rect.centerx
|
|
self.rect = self.image.get_rect()
|
|
self.rect.bottom = bottom
|
|
self.rect.centerx = centerx
|
|
|
|
|
|
def set_mario_to_small_image(self):
|
|
"""During a change from small to big, sets mario's image to small"""
|
|
if self.facing_right:
|
|
self.image = self.normal_small_frames[0][0]
|
|
else:
|
|
self.image = self.normal_small_frames[1][0]
|
|
bottom = self.rect.bottom
|
|
centerx = self.rect.centerx
|
|
self.rect = self.image.get_rect()
|
|
self.rect.bottom = bottom
|
|
self.rect.centerx = centerx
|
|
|
|
|
|
def set_mario_to_big_image(self):
|
|
"""During a change from small to big, sets mario's image to big"""
|
|
if self.facing_right:
|
|
self.image = self.normal_big_frames[0][0]
|
|
else:
|
|
self.image = self.normal_big_frames[1][0]
|
|
bottom = self.rect.bottom
|
|
centerx = self.rect.centerx
|
|
self.rect = self.image.get_rect()
|
|
self.rect.bottom = bottom
|
|
self.rect.centerx = centerx
|
|
|
|
|
|
def become_big(self):
|
|
self.big = True
|
|
self.right_frames = self.right_big_normal_frames
|
|
self.left_frames = self.left_big_normal_frames
|
|
bottom = self.rect.bottom
|
|
left = self.rect.x
|
|
image = self.right_frames[0]
|
|
self.rect = image.get_rect()
|
|
self.rect.bottom = bottom
|
|
self.rect.x = left
|
|
|
|
|
|
def changing_to_fire(self):
|
|
"""Called when Mario is in a BIG_TO_FIRE state (i.e. when
|
|
he obtains a fire flower"""
|
|
self.in_transition_state = True
|
|
|
|
if self.facing_right:
|
|
frames = [self.right_fire_frames[3],
|
|
self.right_big_green_frames[3],
|
|
self.right_big_red_frames[3],
|
|
self.right_big_black_frames[3]]
|
|
else:
|
|
frames = [self.left_fire_frames[3],
|
|
self.left_big_green_frames[3],
|
|
self.left_big_red_frames[3],
|
|
self.left_big_black_frames[3]]
|
|
|
|
if self.fire_transition_timer == 0:
|
|
self.fire_transition_timer = self.current_time
|
|
elif (self.current_time - self.fire_transition_timer) > 65 and (self.current_time - self.fire_transition_timer) < 130:
|
|
self.image = frames[0]
|
|
elif (self.current_time - self.fire_transition_timer) < 195:
|
|
self.image = frames[1]
|
|
elif (self.current_time - self.fire_transition_timer) < 260:
|
|
self.image = frames[2]
|
|
elif (self.current_time - self.fire_transition_timer) < 325:
|
|
self.image = frames[3]
|
|
elif (self.current_time - self.fire_transition_timer) < 390:
|
|
self.image = frames[0]
|
|
elif (self.current_time - self.fire_transition_timer) < 455:
|
|
self.image = frames[1]
|
|
elif (self.current_time - self.fire_transition_timer) < 520:
|
|
self.image = frames[2]
|
|
elif (self.current_time - self.fire_transition_timer) < 585:
|
|
self.image = frames[3]
|
|
elif (self.current_time - self.fire_transition_timer) < 650:
|
|
self.image = frames[0]
|
|
elif (self.current_time - self.fire_transition_timer) < 715:
|
|
self.image = frames[1]
|
|
elif (self.current_time - self.fire_transition_timer) < 780:
|
|
self.image = frames[2]
|
|
elif (self.current_time - self.fire_transition_timer) < 845:
|
|
self.image = frames[3]
|
|
elif (self.current_time - self.fire_transition_timer) < 910:
|
|
self.image = frames[0]
|
|
elif (self.current_time - self.fire_transition_timer) < 975:
|
|
self.image = frames[1]
|
|
elif (self.current_time - self.fire_transition_timer) < 1040:
|
|
self.image = frames[2]
|
|
self.fire = True
|
|
self.in_transition_state = False
|
|
self.state = c.WALK
|
|
self.transition_timer = 0
|
|
|
|
|
|
def changing_to_small(self):
|
|
"""Mario's state and animation when he shrinks from big to small
|
|
after colliding with an enemy"""
|
|
self.in_transition_state = True
|
|
self.hurt_invincible = True
|
|
self.state = c.BIG_TO_SMALL
|
|
|
|
if self.facing_right:
|
|
frames = [self.right_big_normal_frames[4],
|
|
self.right_big_normal_frames[8],
|
|
self.right_small_normal_frames[8]
|
|
]
|
|
else:
|
|
frames = [self.left_big_normal_frames[4],
|
|
self.left_big_normal_frames[8],
|
|
self.left_small_normal_frames[8]
|
|
]
|
|
|
|
if self.transition_timer == 0:
|
|
self.transition_timer = self.current_time
|
|
elif (self.current_time - self.transition_timer) < 265:
|
|
self.image = frames[0]
|
|
self.hurt_invincible_check()
|
|
self.adjust_rect()
|
|
elif (self.current_time - self.transition_timer) < 330:
|
|
self.image = frames[1]
|
|
self.hurt_invincible_check()
|
|
self.adjust_rect()
|
|
elif (self.current_time - self.transition_timer) < 395:
|
|
self.image = frames[2]
|
|
self.hurt_invincible_check()
|
|
self.adjust_rect()
|
|
elif (self.current_time - self.transition_timer) < 460:
|
|
self.image = frames[1]
|
|
self.hurt_invincible_check()
|
|
self.adjust_rect()
|
|
elif (self.current_time - self.transition_timer) < 525:
|
|
self.image = frames[2]
|
|
self.hurt_invincible_check()
|
|
self.adjust_rect()
|
|
elif (self.current_time - self.transition_timer) < 590:
|
|
self.image = frames[1]
|
|
self.hurt_invincible_check()
|
|
self.adjust_rect()
|
|
elif (self.current_time - self.transition_timer) < 655:
|
|
self.image = frames[2]
|
|
self.hurt_invincible_check()
|
|
self.adjust_rect()
|
|
elif (self.current_time - self.transition_timer) < 720:
|
|
self.image = frames[1]
|
|
self.hurt_invincible_check()
|
|
self.adjust_rect()
|
|
elif (self.current_time - self.transition_timer) < 785:
|
|
self.image = frames[2]
|
|
self.hurt_invincible_check()
|
|
self.adjust_rect()
|
|
elif (self.current_time - self.transition_timer) < 850:
|
|
self.image = frames[1]
|
|
self.hurt_invincible_check()
|
|
self.adjust_rect()
|
|
elif (self.current_time - self.transition_timer) < 915:
|
|
self.image = frames[2]
|
|
self.adjust_rect()
|
|
self.in_transition_state = False
|
|
self.state = c.WALK
|
|
self.big = False
|
|
self.transition_timer = 0
|
|
self.hurt_invisible_timer = 0
|
|
self.become_small()
|
|
|
|
|
|
def adjust_rect(self):
|
|
"""Makes sure new Rect has the same bottom and left
|
|
location as previous Rect"""
|
|
x = self.rect.x
|
|
bottom = self.rect.bottom
|
|
self.rect = self.image.get_rect()
|
|
self.rect.x = x
|
|
self.rect.bottom = bottom
|
|
|
|
|
|
def become_small(self):
|
|
self.big = False
|
|
self.right_frames = self.right_small_normal_frames
|
|
self.left_frames = self.left_small_normal_frames
|
|
bottom = self.rect.bottom
|
|
left = self.rect.x
|
|
image = self.right_frames[0]
|
|
self.rect = image.get_rect()
|
|
self.rect.bottom = bottom
|
|
self.rect.x = left
|
|
|
|
|
|
def flag_pole_sliding(self):
|
|
"""State where Mario is sliding down the flag pole"""
|
|
self.state = c.FLAGPOLE
|
|
self.in_transition_state = True
|
|
self.x_vel = 0
|
|
self.y_vel = 0
|
|
|
|
if self.flag_pole_timer == 0:
|
|
self.flag_pole_timer = self.current_time
|
|
elif self.rect.bottom < 493:
|
|
if (self.current_time - self.flag_pole_timer) < 65:
|
|
self.image = self.right_frames[9]
|
|
elif (self.current_time - self.flag_pole_timer) < 130:
|
|
self.image = self.right_frames[10]
|
|
elif (self.current_time - self.flag_pole_timer) >= 130:
|
|
self.flag_pole_timer = self.current_time
|
|
|
|
self.rect.right = self.flag_pole_right
|
|
self.y_vel = 5
|
|
self.rect.y += self.y_vel
|
|
|
|
if self.rect.bottom >= 488:
|
|
self.flag_pole_timer = self.current_time
|
|
|
|
elif self.rect.bottom >= 493:
|
|
self.image = self.right_frames[10]
|
|
|
|
|
|
def sitting_at_bottom_of_pole(self):
|
|
"""State when mario is at the bottom of the flag pole"""
|
|
if self.flag_pole_timer == 0:
|
|
self.flag_pole_timer = self.current_time
|
|
self.image = self.left_frames[10]
|
|
elif (self.current_time - self.flag_pole_timer) < 210:
|
|
self.image = self.left_frames[10]
|
|
else:
|
|
self.in_transition_state = False
|
|
if self.rect.bottom < 485:
|
|
self.state = c.END_OF_LEVEL_FALL
|
|
else:
|
|
self.state = c.WALKING_TO_CASTLE
|
|
|
|
|
|
def set_state_to_bottom_of_pole(self):
|
|
"""Sets Mario to the BOTTOM_OF_POLE state"""
|
|
self.image = self.left_frames[9]
|
|
right = self.rect.right
|
|
#self.rect.bottom = 493
|
|
self.rect.x = right
|
|
if self.big:
|
|
self.rect.x -= 10
|
|
self.flag_pole_timer = 0
|
|
self.state = c.BOTTOM_OF_POLE
|
|
|
|
|
|
def walking_to_castle(self):
|
|
"""State when Mario walks to the castle to end the level"""
|
|
self.max_x_vel = 5
|
|
self.x_accel = c.WALK_ACCEL
|
|
|
|
if self.x_vel < self.max_x_vel:
|
|
self.x_vel += self.x_accel
|
|
|
|
if (self.walking_timer == 0 or (self.current_time - self.walking_timer) > 200):
|
|
self.walking_timer = self.current_time
|
|
|
|
elif (self.current_time - self.walking_timer) > \
|
|
self.calculate_animation_speed():
|
|
if self.frame_index < 3:
|
|
self.frame_index += 1
|
|
else:
|
|
self.frame_index = 1
|
|
self.walking_timer = self.current_time
|
|
|
|
|
|
def falling_at_end_of_level(self, *args):
|
|
"""State when Mario is falling from the flag pole base"""
|
|
self.y_vel += c.GRAVITY
|
|
|
|
|
|
|
|
def check_for_special_state(self):
|
|
"""Determines if Mario is invincible, Fire Mario or recently hurt"""
|
|
self.check_if_invincible()
|
|
self.check_if_fire()
|
|
self.check_if_hurt_invincible()
|
|
self.check_if_crouching()
|
|
|
|
|
|
def check_if_invincible(self):
|
|
if self.invincible:
|
|
if ((self.current_time - self.invincible_start_timer) < 10000):
|
|
self.losing_invincibility = False
|
|
self.change_frame_list(30)
|
|
elif ((self.current_time - self.invincible_start_timer) < 12000):
|
|
self.losing_invincibility = True
|
|
self.change_frame_list(100)
|
|
else:
|
|
self.losing_invincibility = False
|
|
self.invincible = False
|
|
else:
|
|
if self.big:
|
|
self.right_frames = self.right_big_normal_frames
|
|
self.left_frames = self.left_big_normal_frames
|
|
else:
|
|
self.right_frames = self.invincible_small_frames_list[0][0]
|
|
self.left_frames = self.invincible_small_frames_list[0][1]
|
|
|
|
|
|
def change_frame_list(self, frame_switch_speed):
|
|
if (self.current_time - self.invincible_animation_timer) > frame_switch_speed:
|
|
if self.invincible_index < (len(self.invincible_small_frames_list) - 1):
|
|
self.invincible_index += 1
|
|
else:
|
|
self.invincible_index = 0
|
|
|
|
if self.big:
|
|
frames = self.invincible_big_frames_list[self.invincible_index]
|
|
else:
|
|
frames = self.invincible_small_frames_list[self.invincible_index]
|
|
|
|
self.right_frames = frames[0]
|
|
self.left_frames = frames[1]
|
|
|
|
self.invincible_animation_timer = self.current_time
|
|
|
|
|
|
def check_if_fire(self):
|
|
if self.fire and self.invincible == False:
|
|
self.right_frames = self.fire_frames[0]
|
|
self.left_frames = self.fire_frames[1]
|
|
|
|
|
|
def check_if_hurt_invincible(self):
|
|
"""Check if Mario is still temporarily invincible after getting hurt"""
|
|
if self.hurt_invincible and self.state != c.BIG_TO_SMALL:
|
|
if self.hurt_invisible_timer2 == 0:
|
|
self.hurt_invisible_timer2 = self.current_time
|
|
elif (self.current_time - self.hurt_invisible_timer2) < 2000:
|
|
self.hurt_invincible_check()
|
|
else:
|
|
self.hurt_invincible = False
|
|
self.hurt_invisible_timer = 0
|
|
self.hurt_invisible_timer2 = 0
|
|
for frames in self.all_images:
|
|
for image in frames:
|
|
image.set_alpha(255)
|
|
|
|
|
|
def hurt_invincible_check(self):
|
|
"""Makes Mario invincible on a fixed interval"""
|
|
if self.hurt_invisible_timer == 0:
|
|
self.hurt_invisible_timer = self.current_time
|
|
elif (self.current_time - self.hurt_invisible_timer) < 35:
|
|
self.image.set_alpha(0)
|
|
elif (self.current_time - self.hurt_invisible_timer) < 70:
|
|
self.image.set_alpha(255)
|
|
self.hurt_invisible_timer = self.current_time
|
|
|
|
|
|
def check_if_crouching(self):
|
|
"""Checks if mario is crouching"""
|
|
if self.crouching and self.big:
|
|
bottom = self.rect.bottom
|
|
left = self.rect.x
|
|
if self.facing_right:
|
|
self.image = self.right_frames[7]
|
|
else:
|
|
self.image = self.left_frames[7]
|
|
self.rect = self.image.get_rect()
|
|
self.rect.bottom = bottom
|
|
self.rect.x = left
|
|
|
|
|
|
def animation(self):
|
|
"""Adjusts Mario's image for animation"""
|
|
if self.state == c.DEATH_JUMP \
|
|
or self.state == c.SMALL_TO_BIG \
|
|
or self.state == c.BIG_TO_FIRE \
|
|
or self.state == c.BIG_TO_SMALL \
|
|
or self.state == c.FLAGPOLE \
|
|
or self.state == c.BOTTOM_OF_POLE \
|
|
or self.crouching:
|
|
pass
|
|
elif self.facing_right:
|
|
self.image = self.right_frames[self.frame_index]
|
|
else:
|
|
self.image = self.left_frames[self.frame_index]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|