first commit

main
夏铭 6 months ago
parent f95ca8856c
commit 438e0652fc

@ -10,6 +10,7 @@ def main():
'main_menu':main_menu.MainMenu(), 'main_menu':main_menu.MainMenu(),
'load_screen':load_screen.LoadScreen(), 'load_screen':load_screen.LoadScreen(),
'level':level.Level(), 'level':level.Level(),
'game_over':load_screen.GameOver()
} }
game = tools.Game(state_dict,'main_menu') game = tools.Game(state_dict,'main_menu')
game.run() game.run()

@ -0,0 +1,27 @@
import pygame
from .. import tools,setup
from .. import constants as C
class Brick(pygame.sprite.Sprite):
def __init__(self, x, y,brick_type,color=1):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.type = brick_type
bright_rect_frames = [(16,0,16,16),(48,0,16,16)]
dark_rect_frames = [(16,32,16,16),(48,32,16,16)] # 抠图
if not color:
self.frame_rects = bright_rect_frames
else:
self.frame_rects = dark_rect_frames
self.frames = []
for frame_rect in self.frame_rects:
self.frames.append(tools.get_image(setup.GRAPHICS['tile_set'],*frame_rect,(0,0,0),C.BG_MULTI)) # 遍历加载图片
self.frame_index = 0
self.image = self.frames[self.frame_index]
self.rect = self.image.get_rect()
self.rect.x = self.x
self.rect.y = self.y # 设置坐标与图片

@ -6,8 +6,9 @@ from .. import setup, tools
pygame.font.init() pygame.font.init()
class Info: class Info:
def __init__(self,state): def __init__(self,state,game_info):
self.state = state self.state = state
self.game_info = game_info
self.create_state_labels() # 创造某个阶段特有文字 self.create_state_labels() # 创造某个阶段特有文字
self.create_info_labels() # 通用信息 self.create_info_labels() # 通用信息
self.flash_coin = coin.FlashingCoin() self.flash_coin = coin.FlashingCoin()
@ -22,9 +23,10 @@ class Info:
elif self.state == 'load_screen': elif self.state == 'load_screen':
self.state_labels.append((self.create_label('WORLD'), (280, 200))) self.state_labels.append((self.create_label('WORLD'), (280, 200)))
self.state_labels.append((self.create_label('1 - 1'), (430, 200))) self.state_labels.append((self.create_label('1 - 1'), (430, 200)))
self.state_labels.append((self.create_label('X 3'), (380, 280))) self.state_labels.append((self.create_label('X {}'.format(self.game_info['lives'])), (380, 280)))
self.player_image = tools.get_image(setup.GRAPHICS['mario_bros'],178,32,12,16,(0,0,0), C.BG_MULTI) self.player_image = tools.get_image(setup.GRAPHICS['mario_bros'],178,32,12,16,(0,0,0), C.BG_MULTI)
elif self.state == 'game.over':
self.state_labels.append((self.create_label('GAME OVER'), (280, 300)))
def create_info_labels(self): def create_info_labels(self):
self.info_labels = [] self.info_labels = []

@ -52,6 +52,7 @@ class Player(pygame.sprite.Sprite):
def setup_timer(self): def setup_timer(self):
self.walking_timer = 0 self.walking_timer = 0
self.transition_timer = 0 self.transition_timer = 0
self.dead_timer = 0
def load_images(self): def load_images(self):
sheet = setup.GRAPHICS['mario_bros'] sheet = setup.GRAPHICS['mario_bros']
@ -119,8 +120,8 @@ class Player(pygame.sprite.Sprite):
self.jump(keys) self.jump(keys)
elif self.state == 'fall': elif self.state == 'fall':
self.fall(keys) self.fall(keys)
elif self.state == 'basketball': elif self.state == 'die':
self.play_basketball(keys) self.die(keys)
if self.face_right: if self.face_right:
self.image = self.right_frames[self.frame_index] self.image = self.right_frames[self.frame_index]
@ -220,8 +221,19 @@ class Player(pygame.sprite.Sprite):
self.x_vel = self.calc_vel(self.x_vel, self.x_accel, self.max_x_vel, False) self.x_vel = self.calc_vel(self.x_vel, self.x_accel, self.max_x_vel, False)
def play_basketball(self,keys): def die(self,keys):
pass self.rect.y += self.y_vel
self.y_vel += self.anti_gravity
def go_die(self):
self.dead = True
self.y_vel = self.jump_vel
self.frame_index = 6
self.state = 'die'
self.death_timer = self.current_time
def calc_vel(self,vel,accel,max_vel,is_positive=True): # 求速度 def calc_vel(self,vel,accel,max_vel,is_positive=True): # 求速度
if is_positive: if is_positive:

@ -2,20 +2,22 @@ from ..components import info
import pygame import pygame
from .. import tools, setup from .. import tools, setup
from .. import constants as C from .. import constants as C
from .. components import player,stuff from .. components import player,stuff,brick
import os import os
import json import json
class Level: class Level:
def __init__(self): def start(self,game_info):
self.game_info = game_info
self.finished = False self.finished = False
self.next = None self.next = 'game_over'
self.info = info.Info('level') self.info = info.Info('level',self.game_info)
self.load_map_data() self.load_map_data()
self.setup_background() self.setup_background()
self.setup_start_positions() self.setup_start_positions()
self.setup_player() self.setup_player()
self.setup_ground_items() self.setup_ground_items()
self.setup_bricks()
def load_map_data(self): def load_map_data(self):
file_name = 'level_1.json' file_name = 'level_1.json'
@ -54,10 +56,37 @@ class Level:
self.ground_items_group.add(stuff.Item(item['x'],item['y'],item['width'],item['height'],name)) self.ground_items_group.add(stuff.Item(item['x'],item['y'],item['width'],item['height'],name))
def setup_bricks(self):
self.brick_group = pygame.sprite.Group()
if'brick' in self.map_data:
for brick_data in self.map_data['brick']: # 遍历得到xy坐标以及type
x,y = brick_data['x'],brick_data['y']
brick_type = brick_data['type']
if 'brick_num' in brick_data:
#TODO Batch bricks
pass
else:
self.brick_group.add(brick.Brick(x,y,brick_type))
def update(self, surface, keys): def update(self, surface, keys):
self.current_time = pygame.time.get_ticks()
self.player.update(keys) self.player.update(keys)
self.update_player_position()
self.update_game_window() if self.player.dead:
if self.current_time - self.player.death_timer > 3000:
self.finished = True
self.update_game_info()
else:
self.update_player_position()
self.check_if_go_die()
self.update_game_window()
self.info.update()
self.brick_group.update()
self.draw(surface) self.draw(surface)
@ -121,5 +150,19 @@ class Level:
def draw(self, surface): def draw(self, surface):
self.game_ground.blit(self.background,self.game_window,self.game_window) self.game_ground.blit(self.background,self.game_window,self.game_window)
self.game_ground.blit(self.player.image,self.player.rect) # 将背景与人物化境 self.game_ground.blit(self.player.image,self.player.rect) # 将背景与人物化境
self.brick_group.draw(self.game_ground)
surface.blit(self.game_ground,(0,0), self.game_window) # 渲染 surface.blit(self.game_ground,(0,0), self.game_window) # 渲染
self.info.draw(surface) self.info.draw(surface)
def check_if_go_die(self):
if self.player.rect.y > C.SCREEN_H:
self.player.go_die() # 判断是否掉落屏幕外
def update_game_info(self):
if self.player.dead:
self.game_info['lives'] -= 1
if self.game_info['lives'] == 0:
self.next = 'game_over'
else:
self.next = 'load_screen'

@ -2,11 +2,13 @@ from .. components import info
import pygame import pygame
class LoadScreen: class LoadScreen:
def __init__(self): def start(self,game_info):
self.game_info = game_info
self.finished = False self.finished = False
self.next = 'level' self.next = 'level'
self.duration = 2000 # 持续时间
self.timer = 0 self.timer = 0
self.info = info.Info('load_screen') self.info = info.Info('load_screen',self.game_info)
def update(self,surface,keys): def update(self,surface,keys):
self.draw(surface) self.draw(surface)
@ -19,3 +21,12 @@ class LoadScreen:
def draw(self,surface): def draw(self,surface):
surface.fill((0,0,0)) surface.fill((0,0,0))
self.info.draw(surface) self.info.draw(surface)
class GameOver(LoadScreen):
def start(self,game_info):
self.game_info = game_info
self.finished = False
self.next = 'main_menu'
self.duration = 4000
self.timer = 0
self.info = info.Info('game.over',self.game_info)

@ -7,10 +7,24 @@ from ..components import info
class MainMenu: class MainMenu:
def __init__(self): def __init__(self):
game_info = {
'score':0,
'coin':0,
'lives':3,
'player_state':'small'
}
self.start(game_info)
def start(self,game_info): # 使其可以重复调用实现重置效果
self.game_info = game_info
self.setup_background() # 设置底图 self.setup_background() # 设置底图
self.setup_player() # 设置玩家 self.setup_player() # 设置玩家
self.setup_cursor() # 设置光标 self.setup_cursor() # 设置光标
self.info = info.Info('main_menu') self.info = info.Info('main_menu',self.game_info)
self.finished = False self.finished = False
self.next = 'load_screen' self.next = 'load_screen'
@ -42,6 +56,7 @@ class MainMenu:
self.cursor.state = '2p' self.cursor.state = '2p'
self.cursor.rect.y = 405 self.cursor.rect.y = 405
elif keys[pygame.K_RETURN]: elif keys[pygame.K_RETURN]:
self.reset_game_info() # 按下回车重置
if self.cursor.state == '1p': if self.cursor.state == '1p':
self.finished = True self.finished = True
elif self.cursor.state == '2p': elif self.cursor.state == '2p':
@ -58,3 +73,11 @@ class MainMenu:
self.info.update() self.info.update()
self.info.draw(surface) self.info.draw(surface)
def reset_game_info(self): # 按下回车重置
self.game_info.update({
'score':0,
'coin':0,
'lives':3,
'player_state':'small'
})

@ -14,9 +14,11 @@ class Game:
def update(self): def update(self):
if self.state.finished: if self.state.finished:
game_info = self.state.game_info
next_state = self.state.next next_state = self.state.next
self.state.finished = False self.state.finished = False
self.state = self.state_dict[next_state] self.state = self.state_dict[next_state]
self.state.start(game_info)
self.state.update(self.screen, self.keys) self.state.update(self.screen, self.keys)
@ -25,6 +27,7 @@ class Game:
for event in pygame.event.get(): # 获取鼠标键盘事件 for event in pygame.event.get(): # 获取鼠标键盘事件
if event.type == pygame.QUIT: if event.type == pygame.QUIT:
pygame.display.quit() # 退出游戏 pygame.display.quit() # 退出游戏
quit()
elif event.type == pygame.KEYDOWN: # 按键按下 elif event.type == pygame.KEYDOWN: # 按键按下
self.keys = pygame.key.get_pressed() # 按键状态 self.keys = pygame.key.get_pressed() # 按键状态
elif event.type == pygame.KEYUP: elif event.type == pygame.KEYUP:
@ -32,6 +35,7 @@ class Game:
self.update() self.update()
pygame.display.update() # 更新屏幕 pygame.display.update() # 更新屏幕

Loading…
Cancel
Save