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.
SuperMario/pythonProject1/data/components/enemies.py

216 lines
5.2 KiB

9 months ago
import pygame as pg
from .. import setup
from .. import constants as c
class Enemy(pg.sprite.Sprite):
"""Base class for all enemies (Goombas, Koopas, etc.)"""
def __init__(self):
pg.sprite.Sprite.__init__(self)
def setup_enemy(self, x, y, direction, name, setup_frames):
"""Sets up various values for enemy"""
self.sprite_sheet = setup.GFX['smb_enemies_sheet']
self.frames = []
self.frame_index = 0
self.animate_timer = 0
self.death_timer = 0
self.gravity = 1.5
self.state = c.WALK
self.name = name
self.direction = direction
setup_frames()
self.image = self.frames[self.frame_index]
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.bottom = y
self.set_velocity()
def set_velocity(self):
"""Sets velocity vector based on direction"""
if self.direction == c.LEFT:
self.x_vel = -2
else:
self.x_vel = 2
self.y_vel = 0
def get_image(self, x, y, width, height):
"""Get the image frames from the sprite sheet"""
image = pg.Surface([width, height]).convert()
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 handle_state(self):
"""Enemy behavior based on state"""
if self.state == c.WALK:
self.walking()
elif self.state == c.FALL:
self.falling()
elif self.state == c.JUMPED_ON:
self.jumped_on()
elif self.state == c.SHELL_SLIDE:
self.shell_sliding()
elif self.state == c.DEATH_JUMP:
self.death_jumping()
def walking(self):
"""Default state of moving sideways"""
if (self.current_time - self.animate_timer) > 125:
if self.frame_index == 0:
self.frame_index += 1
elif self.frame_index == 1:
self.frame_index = 0
self.animate_timer = self.current_time
def falling(self):
"""For when it falls off a ledge"""
if self.y_vel < 10:
self.y_vel += self.gravity
def jumped_on(self):
"""Placeholder for when the enemy is stomped on"""
pass
def death_jumping(self):
"""Death animation"""
self.rect.y += self.y_vel
self.rect.x += self.x_vel
self.y_vel += self.gravity
if self.rect.y > 600:
self.kill()
def start_death_jump(self, direction):
"""Transitions enemy into a DEATH JUMP state"""
self.y_vel = -8
if direction == c.RIGHT:
self.x_vel = 2
else:
self.x_vel = -2
self.gravity = .5
self.frame_index = 3
self.image = self.frames[self.frame_index]
self.state = c.DEATH_JUMP
def animation(self):
"""Basic animation, switching between two frames"""
self.image = self.frames[self.frame_index]
def update(self, game_info, *args):
"""Updates enemy behavior"""
self.current_time = game_info[c.CURRENT_TIME]
self.handle_state()
self.animation()
class Goomba(Enemy):
def __init__(self, y=c.GROUND_HEIGHT, x=0, direction=c.LEFT, name='goomba'):
Enemy.__init__(self)
self.setup_enemy(x, y, direction, name, self.setup_frames)
def setup_frames(self):
"""Put the image frames in a list to be animated"""
self.frames.append(
self.get_image(0, 4, 16, 16))
self.frames.append(
self.get_image(30, 4, 16, 16))
self.frames.append(
self.get_image(61, 0, 16, 16))
self.frames.append(pg.transform.flip(self.frames[1], False, True))
def jumped_on(self):
"""When Mario squishes him"""
self.frame_index = 2
if (self.current_time - self.death_timer) > 500:
self.kill()
class Koopa(Enemy):
def __init__(self, y=c.GROUND_HEIGHT, x=0, direction=c.LEFT, name='koopa'):
Enemy.__init__(self)
self.setup_enemy(x, y, direction, name, self.setup_frames)
def setup_frames(self):
"""Sets frame list"""
self.frames.append(
self.get_image(150, 0, 16, 24))
self.frames.append(
self.get_image(180, 0, 16, 24))
self.frames.append(
self.get_image(360, 5, 16, 15))
self.frames.append(pg.transform.flip(self.frames[2], False, True))
def jumped_on(self):
"""When Mario jumps on the Koopa and puts him in his shell"""
self.x_vel = 0
self.frame_index = 2
shell_y = self.rect.bottom
shell_x = self.rect.x
self.rect = self.frames[self.frame_index].get_rect()
self.rect.x = shell_x
self.rect.bottom = shell_y
def shell_sliding(self):
"""When the koopa is sliding along the ground in his shell"""
if self.direction == c.RIGHT:
self.x_vel = 10
elif self.direction == c.LEFT:
self.x_vel = -10