以上是我整体的代码图
bricks.py
__author__ = 'justinarmstrong'
import pygame as pg
from .. import setup
from .. import constants as c
from . import powerups
from . import coin
class Brick(pg.sprite.Sprite):
"""Bricks that can be destroyed"""
def __init__(self, x, y, contents=None, powerup_group=None, name='brick'):
"""Initialize the object"""
pg.sprite.Sprite.__init__(self)
self.sprite_sheet = setup.GFX['tile_set']
self.frames = []
self.frame_index = 0
self.setup_frames()
self.image = self.frames[self.frame_index]
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.mask = pg.mask.from_surface(self.image)
self.bumped_up = False
self.rest_height = y
self.state = c.RESTING
self.y_vel = 0
self.gravity = 1.2
self.name = name
self.contents = contents
self.setup_contents()
self.group = powerup_group
self.powerup_in_box = True
def get_image(self, x, y, width, height):
"""Extracts the image 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.BRICK_SIZE_MULTIPLIER),
int(rect.height*c.BRICK_SIZE_MULTIPLIER)))
return image
def setup_frames(self):
"""Set the frames to a list"""
self.frames.append(self.get_image(16, 0, 16, 16))
self.frames.append(self.get_image(432, 0, 16, 16))
def setup_contents(self):
"""Put 6 coins in contents if needed"""
if self.contents == '6coins':
self.coin_total = 6
else:
self.coin_total = 0
def update(self):
"""Updates the brick"""
self.handle_states()
def handle_states(self):
"""Determines brick behavior based on state"""
if self.state == c.RESTING:
self.resting()
elif self.state == c.BUMPED:
self.bumped()
elif self.state == c.OPENED:
self.opened()
def resting(self):
"""State when not moving"""
if self.contents == '6coins':
if self.coin_total == 0:
self.state == c.OPENED
def bumped(self):
"""Action during a BUMPED state"""
self.rect.y += self.y_vel
self.y_vel += self.gravity
if self.rect.y >= (self.rest_height + 5):
self.rect.y = self.rest_height
if self.contents == 'star':
self.state = c.OPENED
elif self.contents == '6coins':
if self.coin_total == 0:
self.state = c.OPENED
else:
self.state = c.RESTING
else:
self.state = c.RESTING
def start_bump(self, score_group):
"""Transitions brick into BUMPED state"""
self.y_vel = -6
if self.contents == '6coins':
setup.SFX['coin'].play()
if self.coin_total > 0:
self.group.add(coin.Coin(self.rect.centerx, self.rect.y, score_group))
self.coin_total -= 1
if self.coin_total == 0:
self.frame_index = 1
self.image = self.frames[self.frame_index]
elif self.contents == 'star':
setup.SFX['powerup_appears'].play()
self.frame_index = 1
self.image = self.frames[self.frame_index]
self.state = c.BUMPED
def opened(self):
"""Action during OPENED state"""
self.frame_index = 1
self.image = self.frames[self.frame_index]
if self.contents == 'star' and self.powerup_in_box:
self.group.add(powerups.Star(self.rect.centerx, self.rest_height))
self.powerup_in_box = False
class BrickPiece(pg.sprite.Sprite):
"""Pieces that appear when bricks are broken"""
def __init__(self, x, y, xvel, yvel):
super(BrickPiece, self).__init__()
self.sprite_sheet = setup.GFX['item_objects']
self.setup_frames()
self.frame_index = 0
self.image = self.frames[self.frame_index]
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.x_vel = xvel
self.y_vel = yvel
self.gravity = .8
def setup_frames(self):
"""create the frame list"""
self.frames = []
image = self.get_image(68, 20, 8, 8)
reversed_image = pg.transform.flip(image, True, False)
self.frames.append(image)
self.frames.append(reversed_image)
def get_image(self, x, y, width, height):
"""Extract image from 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.BRICK_SIZE_MULTIPLIER),
int(rect.height*c.BRICK_SIZE_MULTIPLIER)))
return image
def update(self):
"""Update brick piece"""
self.rect.x += self.x_vel
self.rect.y += self.y_vel
self.y_vel += self.gravity
self.check_if_off_screen()
def check_if_off_screen(self):
"""Remove from sprite groups if off screen"""
if self.rect.y > c.SCREEN_HEIGHT:
self.kill()
castle_flag.py
__author__ = 'justinarmstrong'
import pygame as pg
from .. import setup
from .. import constants as c
class Flag(pg.sprite.Sprite):
"""Flag on the castle"""
def __init__(self, x, y):
"""Initialize object"""
super(Flag, self).__init__()
self.sprite_sheet = setup.GFX['item_objects']
self.image = self.get_image(129, 2, 14, 14)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.state = 'rising'
self.y_vel = -2
self.target_height = y
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, *args):
"""Updates flag position"""
if self.state == 'rising':
self.rising()
elif self.state == 'resting':
self.resting()
def rising(self):
"""State when flag is rising to be on the castle"""
self.rect.y += self.y_vel
if self.rect.bottom <= self.target_height:
self.state = 'resting'
def resting(self):
"""State when the flag is stationary doing nothing"""
pass
checkpoint.py
__author__ = 'justinarmstrong'
import pygame as pg
from .. import constants as c
class Checkpoint(pg.sprite.Sprite):
"""Invisible sprite used to add enemies, special boxes
and trigger sliding down the flag pole"""
def __init__(self, x, name, y=0, width=10, height=600):
super(Checkpoint, self).__init__()
self.image = pg.Surface((width, height))
self.image.fill(c.BLACK)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.name = name
coin.py
__author__ = 'justinarmstrong'
import pygame as pg
from .. import setup
from .. import constants as c
from . import score
class Coin(pg.sprite.Sprite):
"""Coins found in boxes and bricks"""
def __init__(self, x, y, score_group):
pg.sprite.Sprite.__init__(self)
self.sprite_sheet = setup.GFX['item_objects']
self.frames = []
self.frame_index = 0
self.animation_timer = 0
self.state = c.SPIN
self.setup_frames()
self.image = self.frames[self.frame_index]
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.bottom = y - 5
self.gravity = 1
self.y_vel = -15
self.initial_height = self.rect.bottom - 5
self.score_group = score_group
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 setup_frames(self):
"""create the frame list"""
self.frames.append(self.get_image(52, 113, 8, 14))
self.frames.append(self.get_image(4, 113, 8, 14))
self.frames.append(self.get_image(20, 113, 8, 14))
self.frames.append(self.get_image(36, 113, 8, 14))
def update(self, game_info, viewport):
"""Update the coin's behavior"""
self.current_time = game_info[c.CURRENT_TIME]
self.viewport = viewport
if self.state == c.SPIN:
self.spinning()
def spinning(self):
"""Action when the coin is in the SPIN state"""
self.image = self.frames[self.frame_index]
self.rect.y += self.y_vel
self.y_vel += self.gravity
if (self.current_time - self.animation_timer) > 80:
if self.frame_index < 3:
self.frame_index += 1
else:
self.frame_index = 0
self.animation_timer = self.current_time
if self.rect.bottom > self.initial_height:
self.kill()
self.score_group.append(score.Score(self.rect.centerx - self.viewport.x,
self.rect.y,
200))
coin_box.py
__author__ = 'justinarmstrong'
import pygame as pg
from .. import setup
from .. import constants as c
from . import powerups
from . import coin
class Coin_box(pg.sprite.Sprite):
"""Coin box sprite"""
def __init__(self, x, y, contents='coin', group=None):
pg.sprite.Sprite.__init__(self)
self.sprite_sheet = setup.GFX['tile_set']
self.frames = []
self.setup_frames()
self.frame_index = 0
self.image = self.frames[self.frame_index]
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.mask = pg.mask.from_surface(self.image)
self.animation_timer = 0
self.first_half = True # First half of animation cycle
self.state = c.RESTING
self.rest_height = y
self.gravity = 1.2
self.y_vel = 0
self.contents = contents
self.group = group
def get_image(self, x, y, width, height):
"""Extract image from 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.BRICK_SIZE_MULTIPLIER),
int(rect.height*c.BRICK_SIZE_MULTIPLIER)))
return image
def setup_frames(self):
"""Create frame list"""
self.frames.append(
self.get_image(384, 0, 16, 16))
self.frames.append(
self.get_image(400, 0, 16, 16))
self.frames.append(
self.get_image(416, 0, 16, 16))
self.frames.append(
self.get_image(432, 0, 16, 16))
def update(self, game_info):
"""Update coin box behavior"""
self.current_time = game_info[c.CURRENT_TIME]
self.handle_states()
def handle_states(self):
"""Determine action based on RESTING, BUMPED or OPENED
state"""
if self.state == c.RESTING:
self.resting()
elif self.state == c.BUMPED:
self.bumped()
elif self.state == c.OPENED:
self.opened()
def resting(self):
"""Action when in the RESTING state"""
if self.first_half:
if self.frame_index == 0:
if (self.current_time - self.animation_timer) > 375:
self.frame_index += 1
self.animation_timer = self.current_time
elif self.frame_index < 2:
if (self.current_time - self.animation_timer) > 125:
self.frame_index += 1
self.animation_timer = self.current_time
elif self.frame_index == 2:
if (self.current_time - self.animation_timer) > 125:
self.frame_index -= 1
self.first_half = False
self.animation_timer = self.current_time
else:
if self.frame_index == 1:
if (self.current_time - self.animation_timer) > 125:
self.frame_index -= 1
self.first_half = True
self.animation_timer = self.current_time
self.image = self.frames[self.frame_index]
def bumped(self):
"""Action after Mario has bumped the box from below"""
self.rect.y += self.y_vel
self.y_vel += self.gravity
if self.rect.y > self.rest_height + 5:
self.rect.y = self.rest_height
self.state = c.OPENED
if self.contents == 'mushroom':
self.group.add(powerups.Mushroom(self.rect.centerx, self.rect.y))
elif self.contents == 'fireflower':
self.group.add(powerups.FireFlower(self.rect.centerx, self.rect.y))
elif self.contents == '1up_mushroom':
self.group.add(powerups.LifeMushroom(self.rect.centerx, self.rect.y))
self.frame_index = 3
self.image = self.frames[self.frame_index]
def start_bump(self, score_group):
"""Transitions box into BUMPED state"""
self.y_vel = -6
self.state = c.BUMPED
if self.contents == 'coin':
self.group.add(coin.Coin(self.rect.centerx,
self.rect.y,
score_group))
setup.SFX['coin'].play()
else:
setup.SFX['powerup_appears'].play()
def opened(self):
"""Placeholder for OPENED state"""
pass
collider.py
__author__ = 'justinarmstrong'
import pygame as pg
from .. import constants as c
class Collider(pg.sprite.Sprite):
"""Invisible sprites placed overtop background parts
that can be collided with (pipes, steps, ground, etc."""
def __init__(self, x, y, width, height, name='collider'):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((width, height)).convert()
#self.image.fill(c.RED)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.state = None
再附上一张效果图啦