diff --git a/pythonProject1/main.py b/pythonProject1/main.py index fc41857..8afba18 100644 --- a/pythonProject1/main.py +++ b/pythonProject1/main.py @@ -10,6 +10,7 @@ def main(): 'main_menu':main_menu.MainMenu(), 'load_screen':load_screen.LoadScreen(), 'level':level.Level(), + 'game_over':load_screen.GameOver() } game = tools.Game(state_dict,'main_menu') game.run() diff --git a/pythonProject1/source/__pycache__/tools.cpython-312.pyc b/pythonProject1/source/__pycache__/tools.cpython-312.pyc index 1a03e1b..227cd4b 100644 Binary files a/pythonProject1/source/__pycache__/tools.cpython-312.pyc and b/pythonProject1/source/__pycache__/tools.cpython-312.pyc differ diff --git a/pythonProject1/source/components/__pycache__/brick.cpython-312.pyc b/pythonProject1/source/components/__pycache__/brick.cpython-312.pyc new file mode 100644 index 0000000..4304f25 Binary files /dev/null and b/pythonProject1/source/components/__pycache__/brick.cpython-312.pyc differ diff --git a/pythonProject1/source/components/__pycache__/info.cpython-312.pyc b/pythonProject1/source/components/__pycache__/info.cpython-312.pyc index 3a3aa60..06657c4 100644 Binary files a/pythonProject1/source/components/__pycache__/info.cpython-312.pyc and b/pythonProject1/source/components/__pycache__/info.cpython-312.pyc differ diff --git a/pythonProject1/source/components/__pycache__/player.cpython-312.pyc b/pythonProject1/source/components/__pycache__/player.cpython-312.pyc index a7ea981..9488833 100644 Binary files a/pythonProject1/source/components/__pycache__/player.cpython-312.pyc and b/pythonProject1/source/components/__pycache__/player.cpython-312.pyc differ diff --git a/pythonProject1/source/components/brick.py b/pythonProject1/source/components/brick.py index e69de29..24dc415 100644 --- a/pythonProject1/source/components/brick.py +++ b/pythonProject1/source/components/brick.py @@ -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 # 设置坐标与图片 diff --git a/pythonProject1/source/components/info.py b/pythonProject1/source/components/info.py index 69e4899..80b5a24 100644 --- a/pythonProject1/source/components/info.py +++ b/pythonProject1/source/components/info.py @@ -6,8 +6,9 @@ from .. import setup, tools pygame.font.init() class Info: - def __init__(self,state): + def __init__(self,state,game_info): self.state = state + self.game_info = game_info self.create_state_labels() # 创造某个阶段特有文字 self.create_info_labels() # 通用信息 self.flash_coin = coin.FlashingCoin() @@ -22,9 +23,10 @@ class Info: elif self.state == 'load_screen': 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('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) - + elif self.state == 'game.over': + self.state_labels.append((self.create_label('GAME OVER'), (280, 300))) def create_info_labels(self): self.info_labels = [] diff --git a/pythonProject1/source/components/player.py b/pythonProject1/source/components/player.py index b637fe8..053dd37 100644 --- a/pythonProject1/source/components/player.py +++ b/pythonProject1/source/components/player.py @@ -52,6 +52,7 @@ class Player(pygame.sprite.Sprite): def setup_timer(self): self.walking_timer = 0 self.transition_timer = 0 + self.dead_timer = 0 def load_images(self): sheet = setup.GRAPHICS['mario_bros'] @@ -119,8 +120,8 @@ class Player(pygame.sprite.Sprite): self.jump(keys) elif self.state == 'fall': self.fall(keys) - elif self.state == 'basketball': - self.play_basketball(keys) + elif self.state == 'die': + self.die(keys) if self.face_right: 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) - def play_basketball(self,keys): - pass + def die(self,keys): + 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): # 求速度 if is_positive: diff --git a/pythonProject1/source/states/__pycache__/level.cpython-312.pyc b/pythonProject1/source/states/__pycache__/level.cpython-312.pyc index 9813913..049ef8e 100644 Binary files a/pythonProject1/source/states/__pycache__/level.cpython-312.pyc and b/pythonProject1/source/states/__pycache__/level.cpython-312.pyc differ diff --git a/pythonProject1/source/states/__pycache__/load_screen.cpython-312.pyc b/pythonProject1/source/states/__pycache__/load_screen.cpython-312.pyc index 6d32d44..7cca26d 100644 Binary files a/pythonProject1/source/states/__pycache__/load_screen.cpython-312.pyc and b/pythonProject1/source/states/__pycache__/load_screen.cpython-312.pyc differ diff --git a/pythonProject1/source/states/__pycache__/main_menu.cpython-312.pyc b/pythonProject1/source/states/__pycache__/main_menu.cpython-312.pyc index ab86612..0516e0e 100644 Binary files a/pythonProject1/source/states/__pycache__/main_menu.cpython-312.pyc and b/pythonProject1/source/states/__pycache__/main_menu.cpython-312.pyc differ diff --git a/pythonProject1/source/states/level.py b/pythonProject1/source/states/level.py index 0392de0..3ce37d8 100644 --- a/pythonProject1/source/states/level.py +++ b/pythonProject1/source/states/level.py @@ -2,20 +2,22 @@ from ..components import info import pygame from .. import tools, setup from .. import constants as C -from .. components import player,stuff +from .. components import player,stuff,brick import os import json class Level: - def __init__(self): + def start(self,game_info): + self.game_info = game_info self.finished = False - self.next = None - self.info = info.Info('level') + self.next = 'game_over' + self.info = info.Info('level',self.game_info) self.load_map_data() self.setup_background() self.setup_start_positions() self.setup_player() self.setup_ground_items() + self.setup_bricks() def load_map_data(self): 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)) + def setup_bricks(self): + self.brick_group = pygame.sprite.Group() + + if'brick' in self.map_data: + for brick_data in self.map_data['brick']: # 遍历得到x,y坐标以及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): + + self.current_time = pygame.time.get_ticks() 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) @@ -121,5 +150,19 @@ class Level: def draw(self, surface): self.game_ground.blit(self.background,self.game_window,self.game_window) 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) # 渲染 - self.info.draw(surface) \ No newline at end of file + 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' \ No newline at end of file diff --git a/pythonProject1/source/states/load_screen.py b/pythonProject1/source/states/load_screen.py index 2f7244b..bd2280f 100644 --- a/pythonProject1/source/states/load_screen.py +++ b/pythonProject1/source/states/load_screen.py @@ -2,11 +2,13 @@ from .. components import info import pygame class LoadScreen: - def __init__(self): + def start(self,game_info): + self.game_info = game_info self.finished = False self.next = 'level' + self.duration = 2000 # 持续时间 self.timer = 0 - self.info = info.Info('load_screen') + self.info = info.Info('load_screen',self.game_info) def update(self,surface,keys): self.draw(surface) @@ -18,4 +20,13 @@ class LoadScreen: def draw(self,surface): surface.fill((0,0,0)) - self.info.draw(surface) \ No newline at end of file + 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) \ No newline at end of file diff --git a/pythonProject1/source/states/main_menu.py b/pythonProject1/source/states/main_menu.py index bf5d9d3..42ee015 100644 --- a/pythonProject1/source/states/main_menu.py +++ b/pythonProject1/source/states/main_menu.py @@ -7,10 +7,24 @@ from ..components import info class MainMenu: 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_player() # 设置玩家 self.setup_cursor() # 设置光标 - self.info = info.Info('main_menu') + self.info = info.Info('main_menu',self.game_info) self.finished = False self.next = 'load_screen' @@ -42,6 +56,7 @@ class MainMenu: self.cursor.state = '2p' self.cursor.rect.y = 405 elif keys[pygame.K_RETURN]: + self.reset_game_info() # 按下回车重置 if self.cursor.state == '1p': self.finished = True elif self.cursor.state == '2p': @@ -57,4 +72,12 @@ class MainMenu: surface.blit(self.cursor.image,self.cursor.rect) self.info.update() - self.info.draw(surface) \ No newline at end of file + self.info.draw(surface) + + def reset_game_info(self): # 按下回车重置 + self.game_info.update({ + 'score':0, + 'coin':0, + 'lives':3, + 'player_state':'small' + }) \ No newline at end of file diff --git a/pythonProject1/source/tools.py b/pythonProject1/source/tools.py index 11eca67..173cac4 100644 --- a/pythonProject1/source/tools.py +++ b/pythonProject1/source/tools.py @@ -14,9 +14,11 @@ class Game: def update(self): if self.state.finished: + game_info = self.state.game_info next_state = self.state.next self.state.finished = False self.state = self.state_dict[next_state] + self.state.start(game_info) self.state.update(self.screen, self.keys) @@ -25,6 +27,7 @@ class Game: for event in pygame.event.get(): # 获取鼠标键盘事件 if event.type == pygame.QUIT: pygame.display.quit() # 退出游戏 + quit() elif event.type == pygame.KEYDOWN: # 按键按下 self.keys = pygame.key.get_pressed() # 按键状态 elif event.type == pygame.KEYUP: @@ -32,6 +35,7 @@ class Game: + self.update() pygame.display.update() # 更新屏幕