pygame--超级马里奥(万字详细版)

news2024/11/26 0:32:49

3c1598e96a264e0989519bdac21e9b14.gif

超级马里奥点我下载https://github.com/marblexu/PythonSuperMario

 1.游戏介绍

小时候的经典游戏,代码参考了github上的项目Mario-Level-1,使用pygame来实现,从中学习到了横版过关游戏实现中的一些处理方法。原项目实现了超级玛丽的第一个小关。

在原项目的基础上,游戏使用json文件来保存每一个关卡的数据,将数据和代码解耦合,目前已开发4个小关,后续关卡的扩展也很方便,只需要添加json文件和地图图片,支持新的怪物就行。游戏还支持进入水管,到新的子地图。

这篇文章是要介绍下游戏中的几个界面显示和界面之前如何转换,所以特意写了一个demo程序,完整的游戏代码在下面的github链接中下载。

2.状态介绍

游戏中的状态机一般都是有限状态机,简写为FSM(Finite State Machine),简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。
状态机的每一个状态至少需要有下面三个操作:

Startup:当从其他状态进入这个状态时,需要进行的初始化操作

Update :在这个状态运行时进行的更新操作
Cleanup:当从这个状态退出时,需要进行的清除操作
状态需要的变量:

next: 表示这个状态退出后要转到的下一个状态
persist:在状态间转换时需要传递的数据
done:表示这个状态是否结束,状态机会根据这个值来决定转换状态

c645dbda38c24f43884393c40623c8b8.png

 

状态机代码实现

因为这篇文章的目的是游戏界面的状态机实现,所以专门写了一个state_demo.py文件,让大家可以更加方便的看代码。

游戏启动代码

开始是 pygame的初始化,设置屏幕大小为c.SCREEN_SIZE(800, 600)。所有的常量都保存在单独的constants.py中。

import os
import pygame as pg
import constants as c

pg.init()
pg.event.set_allowed([pg.KEYDOWN, pg.KEYUP, pg.QUIT])
pg.display.set_caption(c.ORIGINAL_CAPTION)
SCREEN = pg.display.set_mode(c.SCREEN_SIZE)
SCREEN_RECT = SCREEN.get_rect()

 oad_all_gfx函数查找指定目录下所有符合后缀名的图片,使用pg.image.load函数加载,保存在graphics set中。
GFX 保存在resources/graphics目录找到的所有图片,后面获取各种图形时会用到。

def load_all_gfx(directory, colorkey=(255,0,255), accept=('.png', '.jpg', '.bmp', '.gif')):
    graphics = {}
    for pic in os.listdir(directory):
        name, ext = os.path.splitext(pic)
        if ext.lower() in accept:
            img = pg.image.load(os.path.join(directory, pic))
            if img.get_alpha():
                img = img.convert_alpha()
            else:
                img = img.convert()
                img.set_colorkey(colorkey)
            graphics[name] = img
    return graphics

GFX = load_all_gfx(os.path.join("resources","graphics"))

 下面是demo的入口函数,先创建了一个保存所有状态的state_dict set,调用setup_states函数设置起始状态是 MAIN_MENU。

if __name__=='__main__':
    game = Control()
    state_dict = {c.MAIN_MENU: Menu(),
                  c.LOAD_SCREEN: LoadScreen(),
                  c.LEVEL: Level(),
                  c.GAME_OVER: GameOver(),
                  c.TIME_OUT: TimeOut()}
    game.setup_states(state_dict, c.MAIN_MENU)
    game.main()

 

状态类

先定义一个State 基类, 按照上面说的状态需要的三个操作分别定义函数(startup, update, cleanup)。在 init 函数中定义了上面说的三个变量(next,persist,done),还有start_time 和 current_time 用于记录时间。

class State():
   def __init__(self):
       self.start_time = 0.0
       self.current_time = 0.0
       self.done = False
       self.next = None
       self.persist = {}
   
   @abstractmethod
   def startup(self, current_time, persist):
       '''abstract method'''

   def cleanup(self):
       self.done = False
       return self.persist
   
   @abstractmethod
   def update(sefl, surface, keys, current_time):
       '''abstract method'''

info类

下面介绍Info类,界面的显示大部分都是由它来完成,init函数中create_info_labels函数创建通用的信息,create_state_labels函数对于不同的状态,会初始化不同的信息。

class Info():
   def __init__(self, game_info, state):
       self.coin_total = game_info[c.COIN_TOTAL]
       self.total_lives = game_info[c.LIVES]
       self.state = state
       self.game_info = game_info
       
       self.create_font_image_dict()
       self.create_info_labels()
       self.create_state_labels()
       self.flashing_coin = FlashCoin(280, 53)

 

Control类

Control 是状态机类,main函数是游戏的主循环,setup_states函数设置游戏启动时运行的状态

class Control():
   def __init__(self):
       self.screen = pg.display.get_surface()
       self.done = False
       self.clock = pg.time.Clock()
       self.fps = 60
       self.current_time = 0.0
       self.keys = pg.key.get_pressed()
       self.state_dict = {}
       self.state_name = None
       self.state = None
   
   def setup_states(self, state_dict, start_state):
       self.state_dict = state_dict
       self.state_name = start_state
       self.state = self.state_dict[self.state_name]
   
   def main(self):
       while not self.done:
           self.event_loop()
           self.update()
           pg.display.update()
           self.clock.tick(self.fps)

3.完整源码

constants.py

我设置的游戏时间是300秒,也可以改。

SCREEN_HEIGHT = 600
SCREEN_WIDTH = 800
SCREEN_SIZE = (SCREEN_WIDTH,SCREEN_HEIGHT)

ORIGINAL_CAPTION = "Super Mario Bros"

GAME_TIME_OUT = 5

## COLORS ##
#                R    G    B
BLACK        = (  0,   0,   0)

SIZE_MULTIPLIER = 2.5
BRICK_SIZE_MULTIPLIER = 2.69
BACKGROUND_MULTIPLER = 2.679
GROUND_HEIGHT = SCREEN_HEIGHT - 62

#STATES FOR ENTIRE GAME
MAIN_MENU = 'main menu'
LOAD_SCREEN = 'load screen'
TIME_OUT = 'time out'
GAME_OVER = 'game over'
LEVEL = 'level'

#MAIN MENU CURSOR STATES
PLAYER1 = '1 PLAYER GAME'
PLAYER2 = '2 PLAYER GAME'

#GAME INFO DICTIONARY KEYS
COIN_TOTAL = 'coin total'
SCORE = 'score'
TOP_SCORE = 'top score'
LIVES = 'lives'
CURRENT_TIME = 'current time'
LEVEL_NUM = 'level num'
PLAYER_NAME = 'player name'
PLAYER_MARIO = 'mario'
PLAYER_LUIGI = 'luigi'

ITEM_SHEET = 'item_objects'

 state_demo.py

import os
import pygame as pg
from abc import ABC, abstractmethod
import constants as c


class State():
  def __init__(self):
      self.start_time = 0.0
      self.current_time = 0.0
      self.done = False
      self.next = None
      self.persist = {}
  
  @abstractmethod
  def startup(self, current_time, persist):
      '''abstract method'''

  def cleanup(self):
      self.done = False
      return self.persist
  
  @abstractmethod
  def update(sefl, surface, keys, current_time):
      '''abstract method'''

class Menu(State):
  def __init__(self):
      State.__init__(self)
      persist = {c.COIN_TOTAL: 0,
                 c.SCORE: 0,
                 c.LIVES: 3,
                 c.TOP_SCORE: 0,
                 c.CURRENT_TIME: 0.0,
                 c.LEVEL_NUM: 1,
                 c.PLAYER_NAME: c.PLAYER_MARIO}
      self.startup(0.0, persist)
  
  def startup(self, current_time, persist):
      self.next = c.LOAD_SCREEN
      self.persist = persist
      self.game_info = persist
      self.overhead_info = Info(self.game_info, c.MAIN_MENU)

      self.setup_background()
      self.setup_player()
      self.setup_cursor()
      
  def setup_background(self):
      self.background = GFX['level_1']
      self.background_rect = self.background.get_rect()
      self.background = pg.transform.scale(self.background,
                                  (int(self.background_rect.width*c.BACKGROUND_MULTIPLER),
                                  int(self.background_rect.height*c.BACKGROUND_MULTIPLER)))

      self.viewport = SCREEN.get_rect(bottom=SCREEN_RECT.bottom)
      self.image_dict = {}
      image = get_image(GFX['title_screen'], 1, 60, 176, 88,
                          (255, 0, 220), c.SIZE_MULTIPLIER)
      rect = image.get_rect()
      rect.x, rect.y = (170, 100)
      self.image_dict['GAME_NAME_BOX'] = (image, rect)

  def setup_player(self):
      self.player_list = []
      player_rect_info = [(178, 32, 12, 16), (178, 128, 12, 16)]
      for rect in player_rect_info:
          image = get_image(GFX['mario_bros'],
                              *rect, c.BLACK, 2.9)
          rect = image.get_rect()
          rect.x, rect.bottom = 110, c.GROUND_HEIGHT
          self.player_list.append((image, rect))
      self.player_index = 0

  def setup_cursor(self):
      self.cursor = pg.sprite.Sprite()
      self.cursor.image = get_image(GFX[c.ITEM_SHEET], 24, 160, 8, 8, c.BLACK, 3)
      rect = self.cursor.image.get_rect()
      rect.x, rect.y = (220, 358)
      self.cursor.rect = rect
      self.cursor.state = c.PLAYER1

  def update(self, surface, keys, current_time):
      self.current_time = current_time
      self.game_info[c.CURRENT_TIME] = self.current_time
      self.player_image = self.player_list[self.player_index][0]
      self.player_rect = self.player_list[self.player_index][1]
      self.update_cursor(keys)
      self.overhead_info.update(self.game_info)

      surface.blit(self.background, self.viewport, self.viewport)
      surface.blit(self.image_dict['GAME_NAME_BOX'][0],
                   self.image_dict['GAME_NAME_BOX'][1])
      surface.blit(self.player_image, self.player_rect)
      surface.blit(self.cursor.image, self.cursor.rect)
      self.overhead_info.draw(surface)

  def update_cursor(self, keys):
      if self.cursor.state == c.PLAYER1:
          self.cursor.rect.y = 358
          if keys[pg.K_DOWN]:
              self.cursor.state = c.PLAYER2
              self.player_index = 1
              self.game_info[c.PLAYER_NAME] = c.PLAYER_LUIGI
      elif self.cursor.state == c.PLAYER2:
          self.cursor.rect.y = 403
          if keys[pg.K_UP]:
              self.cursor.state = c.PLAYER1
              self.player_index = 0
              self.game_info[c.PLAYER_NAME] = c.PLAYER_MARIO
      if keys[pg.K_RETURN]:
          self.done = True

class LoadScreen(State):
  def __init__(self):
      State.__init__(self)
      self.time_list = [2400, 2600, 2635]
      
  def startup(self, current_time, persist):
      self.start_time = current_time
      self.persist = persist
      self.game_info = self.persist
      self.next = self.set_next_state()
      
      info_state = self.set_info_state()
      self.overhead_info = Info(self.game_info, info_state)
  
  def set_next_state(self):
      return c.LEVEL
  
  def set_info_state(self):
      return c.LOAD_SCREEN

  def update(self, surface, keys, current_time):
      if (current_time - self.start_time) < self.time_list[0]:
          surface.fill(c.BLACK)
          self.overhead_info.update(self.game_info)
          self.overhead_info.draw(surface)
      elif (current_time - self.start_time) < self.time_list[1]:
          surface.fill(c.BLACK)
      elif (current_time - self.start_time) < self.time_list[2]:
          surface.fill((106, 150, 252))
      else:
          self.done = True
          
class GameOver(LoadScreen):
  def __init__(self):
      LoadScreen.__init__(self)
      self.time_list = [3000, 3200, 3235]

  def set_next_state(self):
      return c.MAIN_MENU
  
  def set_info_state(self):
      return c.GAME_OVER

class TimeOut(LoadScreen):
  def __init__(self):
      LoadScreen.__init__(self)
      self.time_list = [2400, 2600, 2635]

  def set_next_state(self):
      if self.persist[c.LIVES] == 0:
          return c.GAME_OVER
      else:
          return c.LOAD_SCREEN

  def set_info_state(self):
      return c.TIME_OUT

class Level(State):
  def __init__(self):
      State.__init__(self)

  def startup(self, current_time, persist):
      self.game_info = persist
      self.persist = self.game_info
      self.player = None
      self.overhead_info = Info(self.game_info, c.LEVEL)
      self.setup_background()

  def setup_background(self):
      self.background = GFX['level_1']
      self.bg_rect = self.background.get_rect()
      self.background = pg.transform.scale(self.background, 
                                  (int(self.bg_rect.width*c.BACKGROUND_MULTIPLER),
                                  int(self.bg_rect.height*c.BACKGROUND_MULTIPLER)))
      self.bg_rect = self.background.get_rect()

      self.level = pg.Surface((self.bg_rect.w, self.bg_rect.h)).convert()
      self.viewport = SCREEN.get_rect(bottom=self.bg_rect.bottom)

  def update(self, surface, keys, current_time):
      self.game_info[c.CURRENT_TIME] = self.current_time = current_time
      self.overhead_info.update(self.game_info, self.player)
      if self.overhead_info.time <= 0:
          self.update_game_info()
          self.done = True
      self.draw(surface)
  
  def update_game_info(self):
      self.persist[c.LIVES] -= 1

      if self.persist[c.LIVES] == 0:
          self.next = c.GAME_OVER
      elif self.overhead_info.time == 0:
          self.next = c.TIME_OUT
      else:
          self.next = c.LOAD_SCREEN

  def draw(self, surface):
      self.level.blit(self.background, self.viewport, self.viewport)
      surface.blit(self.level, (0,0), self.viewport)
      self.overhead_info.draw(surface)

class Character(pg.sprite.Sprite):
  def __init__(self, image):
      pg.sprite.Sprite.__init__(self)
      self.image = image
      self.rect = self.image.get_rect()

class Info():
  def __init__(self, game_info, state):
      self.coin_total = game_info[c.COIN_TOTAL]
      self.total_lives = game_info[c.LIVES]
      self.state = state
      self.game_info = game_info
      
      self.create_font_image_dict()
      self.create_info_labels()
      self.create_state_labels()
      self.flashing_coin = FlashCoin(280, 53)
      
  def create_font_image_dict(self):
      self.image_dict = {}
      image_list = []
      
      image_rect_list = [# 0 - 9
                         (3, 230, 7, 7), (12, 230, 7, 7), (19, 230, 7, 7),
                         (27, 230, 7, 7), (35, 230, 7, 7), (43, 230, 7, 7),
                         (51, 230, 7, 7), (59, 230, 7, 7), (67, 230, 7, 7),
                         (75, 230, 7, 7), 
                         # A - Z
                         (83, 230, 7, 7), (91, 230, 7, 7), (99, 230, 7, 7),
                         (107, 230, 7, 7), (115, 230, 7, 7), (123, 230, 7, 7),
                         (3, 238, 7, 7), (11, 238, 7, 7), (20, 238, 7, 7),
                         (27, 238, 7, 7), (35, 238, 7, 7), (44, 238, 7, 7),
                         (51, 238, 7, 7), (59, 238, 7, 7), (67, 238, 7, 7),
                         (75, 238, 7, 7), (83, 238, 7, 7), (91, 238, 7, 7),
                         (99, 238, 7, 7), (108, 238, 7, 7), (115, 238, 7, 7),
                         (123, 238, 7, 7), (3, 246, 7, 7), (11, 246, 7, 7),
                         (20, 246, 7, 7), (27, 246, 7, 7), (48, 246, 7, 7),
                         # -*
                         (68, 249, 6, 2), (75, 247, 6, 6)]
                         
      character_string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ -*'
      
      for character, image_rect in zip(character_string, image_rect_list):
          self.image_dict[character] = get_image(GFX['text_images'], 
                                          *image_rect, (92, 148, 252), 2.9)

  def create_info_labels(self):
      self.score_text = []
      self.coin_count_text = []
      self.mario_label = []
      self.world_label = []
      self.time_label = []
      self.stage_label = []

      self.create_label(self.score_text, '000000', 75, 55)
      self.create_label(self.coin_count_text, '*00', 300, 55)
      self.create_label(self.mario_label, 'MARIO', 75, 30)
      self.create_label(self.world_label, 'WORLD', 450, 30)
      self.create_label(self.time_label, 'TIME', 625, 30)
      self.create_label(self.stage_label, '1-1', 472, 55)

      self.info_labels = [self.score_text, self.coin_count_text, self.mario_label,
                  self.world_label, self.time_label, self.stage_label]

  def create_state_labels(self):
      if self.state == c.MAIN_MENU:
          self.create_main_menu_labels()
      elif self.state == c.LOAD_SCREEN:
          self.create_player_image()
          self.create_load_screen_labels()
      elif self.state == c.LEVEL:
          self.create_level_labels()
      elif self.state == c.GAME_OVER:
          self.create_game_over_labels()
      elif self.state == c.TIME_OUT:
          self.create_time_out_labels()

  def create_player_image(self):
      self.life_times_image = get_image(GFX['text_images'], 
                              75, 247, 6, 6, (92, 148, 252), 2.9)
      self.life_times_rect = self.life_times_image.get_rect(center=(378, 295))
      self.life_total_label = []
      self.create_label(self.life_total_label, str(self.total_lives), 450, 285)
      
      if self.game_info[c.PLAYER_NAME] == c.PLAYER_MARIO:
          rect = (178, 32, 12, 16)
      else:
          rect = (178, 128, 12, 16)
      self.player_image = get_image(GFX['mario_bros'], 
                              *rect, (92, 148, 252), 2.9)
      self.player_rect = self.player_image.get_rect(center=(320, 290))

  def create_main_menu_labels(self):
      mario_game = []
      luigi_game = []
      top = []
      top_score = []

      self.create_label(mario_game, c.PLAYER1, 272, 360)
      self.create_label(luigi_game, c.PLAYER2, 272, 405)
      self.create_label(top, 'TOP - ', 290, 465)
      self.create_label(top_score, '000000', 400, 465)
      self.state_labels = [mario_game, luigi_game, top, top_score,
                          *self.info_labels]
  
  def create_load_screen_labels(self):
      world_label = []
      self.stage_label2 = []

      self.create_label(world_label, 'WORLD', 280, 200)
      self.create_label(self.stage_label2, '1-1', 430, 200)
      self.state_labels = [world_label, self.stage_label2,
              *self.info_labels, self.life_total_label]

  def create_level_labels(self):
      self.time = c.GAME_TIME_OUT
      self.current_time = 0
      self.clock_time_label = []
      self.create_label(self.clock_time_label, str(self.time), 645, 55)
      self.state_labels = [*self.info_labels, self.clock_time_label]

  def create_game_over_labels(self):
      game_label = []
      over_label = []
      
      self.create_label(game_label, 'GAME', 280, 300)
      self.create_label(over_label, 'OVER', 400, 300)
      
      self.state_labels = [game_label, over_label, *self.info_labels]

  def create_time_out_labels(self):
      timeout_label = []
      self.create_label(timeout_label, 'TIME OUT', 290, 310)
      self.state_labels = [timeout_label, *self.info_labels]

  def create_label(self, label_list, string, x, y):
      for letter in string:
          label_list.append(Character(self.image_dict[letter]))
      self.set_label_rects(label_list, x, y)
  
  def set_label_rects(self, label_list, x, y):
      for i, letter in enumerate(label_list):
          letter.rect.x = x + ((letter.rect.width + 3) * i)
          letter.rect.y = y
          if letter.image == self.image_dict['-']:
              letter.rect.y += 7
              letter.rect.x += 2
  
  def update(self, level_info, level=None):
      self.level = level
      self.handle_level_state(level_info)
  
  def handle_level_state(self, level_info):
      self.score = level_info[c.SCORE]
      self.update_text(self.score_text, self.score)
      self.update_text(self.coin_count_text, level_info[c.COIN_TOTAL])
      self.update_text(self.stage_label, level_info[c.LEVEL_NUM])
      self.flashing_coin.update(level_info[c.CURRENT_TIME])
      if self.state == c.LOAD_SCREEN:
          self.update_text(self.stage_label2, level_info[c.LEVEL_NUM])
      if self.state == c.LEVEL:
          if (level_info[c.CURRENT_TIME] - self.current_time) > 1000:
              self.current_time = level_info[c.CURRENT_TIME]
              self.time -= 1
              self.update_text(self.clock_time_label, self.time, True)
  
  def update_text(self, text, score, reset=False):
      if reset and len(text) > len(str(score)):
          text.remove(text[0])
      index = len(text) - 1
      for digit in reversed(str(score)):
          rect = text[index].rect
          text[index] = Character(self.image_dict[digit])
          text[index].rect = rect
          index -= 1
      
  def draw(self, surface):
      self.draw_info(surface, self.state_labels)
      if self.state == c.LOAD_SCREEN:
          surface.blit(self.player_image, self.player_rect)
          surface.blit(self.life_times_image, self.life_times_rect)
      surface.blit(self.flashing_coin.image, self.flashing_coin.rect)
  
  def draw_info(self, surface, label_list):
      for label in label_list:
          for letter in label:
              surface.blit(letter.image, letter.rect)


class FlashCoin(pg.sprite.Sprite):
  def __init__(self, x, y):
      pg.sprite.Sprite.__init__(self)
      self.frame_index = 0
      self.frames = []
      self.load_frames()
      self.image = self.frames[self.frame_index]
      self.rect = self.image.get_rect()
      self.rect.x = x
      self.rect.y = y
      self.animation_timer = 0
      
  def load_frames(self):
      sheet = GFX[c.ITEM_SHEET]
      frame_rect_list = [(1, 160, 5, 8), (9, 160, 5, 8),
                      (17, 160, 5, 8), (9, 160, 5, 8)]
      for frame_rect in frame_rect_list:
          self.frames.append(get_image(sheet, *frame_rect, 
                          c.BLACK, c.BRICK_SIZE_MULTIPLIER))

  def update(self, current_time):
      time_list = [375, 125, 125, 125]
      if self.animation_timer == 0:
          self.animation_timer = current_time
      elif (current_time - self.animation_timer) > time_list[self.frame_index]:
          self.frame_index += 1
          if self.frame_index == 4:
              self.frame_index = 0
          self.animation_timer = current_time
      
      self.image = self.frames[self.frame_index]

class Control():
  def __init__(self):
      self.screen = pg.display.get_surface()
      self.done = False
      self.clock = pg.time.Clock()
      self.fps = 60
      self.current_time = 0.0
      self.keys = pg.key.get_pressed()
      self.state_dict = {}
      self.state_name = None
      self.state = None
  
  def setup_states(self, state_dict, start_state):
      self.state_dict = state_dict
      self.state_name = start_state
      self.state = self.state_dict[self.state_name]
  
  def update(self):
      self.current_time = pg.time.get_ticks()
      if self.state.done:
          self.flip_state()
      self.state.update(self.screen, self.keys, self.current_time)
  
  def flip_state(self):
      previous, self.state_name = self.state_name, self.state.next
      persist = self.state.cleanup()
      self.state = self.state_dict[self.state_name]
      self.state.startup(self.current_time, persist)

  def event_loop(self):
      for event in pg.event.get():
          if event.type == pg.QUIT:
              self.done = True
          elif event.type == pg.KEYDOWN:
              self.keys = pg.key.get_pressed()
          elif event.type == pg.KEYUP:
              self.keys = pg.key.get_pressed()
  
  def main(self):
      while not self.done:
          self.event_loop()
          self.update()
          pg.display.update()
          self.clock.tick(self.fps)

def get_image(sheet, x, y, width, height, colorkey, scale):
      image = pg.Surface([width, height])
      rect = image.get_rect()

      image.blit(sheet, (0, 0), (x, y, width, height))
      image.set_colorkey(colorkey)
      image = pg.transform.scale(image,
                                 (int(rect.width*scale),
                                  int(rect.height*scale)))
      return image

def load_all_gfx(directory, colorkey=(255,0,255), accept=('.png', '.jpg', '.bmp', '.gif')):
  graphics = {}
  for pic in os.listdir(directory):
      name, ext = os.path.splitext(pic)
      if ext.lower() in accept:
          img = pg.image.load(os.path.join(directory, pic))
          if img.get_alpha():
              img = img.convert_alpha()
          else:
              img = img.convert()
              img.set_colorkey(colorkey)
          graphics[name] = img
  return graphics

# pygame related initial code 
pg.init()
pg.event.set_allowed([pg.KEYDOWN, pg.KEYUP, pg.QUIT])
pg.display.set_caption(c.ORIGINAL_CAPTION)
SCREEN = pg.display.set_mode(c.SCREEN_SIZE)
SCREEN_RECT = SCREEN.get_rect()

GFX = load_all_gfx(os.path.join("resources","graphics"))

if __name__=='__main__':
  game = Control()
  state_dict = {c.MAIN_MENU: Menu(),
                c.LOAD_SCREEN: LoadScreen(),
                c.LEVEL: Level(),
                c.GAME_OVER: GameOver(),
                c.TIME_OUT: TimeOut()}
  game.setup_states(state_dict, c.MAIN_MENU)
  game.main()

需要的图片 

1.10b371b1b74f482dae26cb890edf417c.png

2.

c5088eb3e34b4d91b6f6e82de7bdecbd.png3.

81572bb2f5a1474a9b5435f63228133c.png4.

4b5adf1d3ec3425db6798072f629cb67.png5.

1a5b9b8435314e98b7e32761329d6dad.png6.

c90f15734aba441e872067267879f079.png

7.a13ea2d739c6480ba05ed62582effe60.png

8.d660650a9d92472ebcbec4bd1268bab7.png 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2190426.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows应急响应-Auto病毒

文章目录 应急背景分析样本开启监控感染病毒查看监控分析病毒行为1.autorun.inf分析2.异常连接3.进程排查4.启动项排查 查杀1.先删掉autorun.inf文件2.使用xuetr杀掉进程3.启动项删除重启排查入侵排查正常流程 应急背景 运维人员准备通过windows共享文档方式为公司员工下发软件…

【Java】Java面试题笔试

[赠送]面试视频指导简历面试题 Java面试笔试题题库华为 java笔试面试题2014.files 就业相关java 面试题 面试题库 视频笔记 java笔试题大集合及答案 java面试书籍源码 java算法大全源码包8张图解 java.docx25个经典的Spring面试问答.docx 25个经典的Spring面试问答.docx 100家大…

知识图谱入门——10:使用 spaCy 进行命名实体识别(NER)的进阶应用:基于词袋的实体识别与知识抽取

在构建知识图谱的过程中&#xff0c;如何准确地识别和提取实体是关键。spaCy 提供了强大的命名实体识别&#xff08;NER&#xff09;功能&#xff0c;我们可以结合自定义规则和工具来实现更精准的实体抽取。本文将详细探讨如何在 spaCy 中实现自定义实体抽取&#xff0c;包括使…

OpenAI 推出 Canvas 工具,助力用户与 ChatGPT 协作写作和编程

OpenAI 近日推出了一款名为 Canvas 的新工具&#xff0c;旨在帮助用户更高效地与 ChatGPT 协作进行写作与编程。 Canvas 允许用户在一个独立窗口中与 ChatGPT 实时协作修改内容。无论是改进文本、调整语言风格、审查代码&#xff0c;还是在不同编程语言间转换&#xff0c;Canv…

Js逆向分析+Python爬虫结合

JS逆向分析Python爬虫结合 特别声明&#x1f4e2;&#xff1a;本教程只用于教学&#xff0c;大家在使用爬虫过程中需要遵守相关法律法规&#xff0c;否则后果自负&#xff01;&#xff01;&#xff01; 完整代码地址Github&#xff1a;https://github.com/ziyifast/ziyifast-co…

自闭症干预寄宿学校:为孩子搭建沟通与社交的桥梁

在探索自闭症儿童教育的广阔天地里&#xff0c;一所优秀的寄宿学校不仅是知识的殿堂&#xff0c;更是孩子们学习沟通与社交技能的桥梁。位于广州的星贝育园自闭症儿童寄宿制学校&#xff0c;正是这样一所专注于为自闭症儿童提供全面、个性化教育服务的机构&#xff0c;它以其独…

Linux-du命令使用方法

Linux-du&#xff08;disk useage&#xff09;命令 du 命令用于查看文件和目录占用的磁盘空间。 du [选项] [文件或目录]-h (human-readable)&#xff1a; 将输出格式转为人类可读的形式&#xff0c;使用 KB、MB 等单位。 du -h /path/to/directory1.5M /path/to/directory…

Pikachu-SSRF(curl / file_get_content)

SSRF SSRF是Server-side Request Forge的缩写&#xff0c;中文翻译为服务端请求伪造。产生的原因是由于服务端提供了从其他服务器应用获取数据的功能且没有对地址和协议等做过滤和限制。常见的一个场景就是&#xff0c;通过用户输入的URL来获取图片。这个功能如果被恶意使用&am…

Linux 之 安装软件、GCC编译器、Linux 操作系统基础

安装软件、GCC编译器、Linux 操作系统基础 学习任务&#xff1a; 安装 Vmware虚拟机、掌握Ubuntu 系统的使用认识 Ubuntu 操作系统的终端和 Shell掌握软件安装、文件系统、掌握磁盘管理与解压缩掌握 VIM 编辑器、Makefile 基本语法熟悉 Linux 常见指令操作 安装好开发软件&…

力扣189.轮转数组

给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 3 步: [5,6,7,1,2,3,4…

数据库(MySQL):使用命令从零开始在Navicat创建一个数据库及其数据表(一).创建基础表

一. 使用工具和命令 1.1 使用的工具 Navicat Premium 17 &#xff1a;“Navicat”是一套可创建多个连接的数据库管理工具。 MySQL版本8.0.39 。 1.2 使用的命令 Navicat中使用的命令 命令命令解释SHOW DATABASES&#xff1b;展示所有的数据库CREATE DATABASE 数据库名称; 创…

10以内数的分解

// 10以内数的分解.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 //#include <iostream> using namespace std; int main(int argc, char* argv[]){for (int i 2; i < 10; i){for (int j 1; j < i; j){printf("%d%d%d ",j…

CSS样式基础样式选择器(案例+代码实现+效果图)

目录 1.css样式的规则 2.引入css样式的方式 1)行内式 2)内嵌式 3)外链式 1-link导入 2-import导入 4)总 3.css基础选择器 1)标签选择器 案例&#xff1a;使用标签选择器编写一个圆 1.代码 2.效果 2)类选择器 案例&#xff1a;使用类选择器为div添加背景色 1.代码 2.效果 3)id…

深度探索Kali Linux的精髓与实践应用

Kali Linux简介 Kali Linux作为全球网络安全领域的首选操作系统之一&#xff0c;其强大的功能性及广泛的适用范围令人瞩目。除了上述基础介绍外&#xff0c;让我们深入探究Kali Linux的几个关键特性及其在实际操作中的具体应用案例。 Kali工具集成&#xff1a;全面的安全工具…

加湿器模块(5V STM32)

目录 一、介绍 二、模块原理 1.原理图 2.引脚描述 3.尺寸介绍 三、程序设计 main.c文件 jsq.h文件 jsq.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 加湿器模块通常是指在智能家居设备中负责增加室内空气湿度的部分&#xff0c;这种模块设计旨在改善干燥环…

osg 矩阵相关

下面结果是一样的 osg::Matrix mtrixx;mtrixx.makeRotate(90 / 180.f * osg::PI, osg::Vec3(1, 0, 0));osg::Matrix mtrixx12 osg::Matrix::rotate(90 / 180.f * osg::PI, 1, 0, 0); 备注&#xff1a; rotate或makerotate第一个参数是弧度&#xff0c;可以用 弧度值osg::in…

Pre-trained Natural Language Understanding for Task-Oriented Dialogue

前言 众所周知,预训练BERT语言模型在许多NLP任务重大放异彩,用来文本内容和语义的表征学习很有效果,而且大大降低了下游任务的训练时间。但是由于普通文本和任务型对话之间的语言模式的潜在差异,使得现在的预训练语言模型在实际使用中作用不大。 至于对话领域的预训练语言…

MS-900认证:Microsoft 365 Certified: Fundamentals

一、什么是MS-900认证&#xff1f; MS900认证&#xff0c;全称是 Microsoft 365 Fundamentals&#xff0c;是微软提供的一项认证考试&#xff0c;它旨在验证考生对 Microsoft 365 服务和功能的理解&#xff0c;包括云服务概念、核心服务、安全性、合规性、隐私以及支持和定价信…

【CTF Web】Pikachu CSRF(get) Writeup(CSRF+GET请求+社会工程学)

CSRF(跨站请求伪造)概述 Cross-site request forgery 简称为“CSRF”&#xff0c;在CSRF的攻击场景中攻击者会伪造一个请求&#xff08;这个请求一般是一个链接&#xff09;&#xff0c;然后欺骗目标用户进行点击&#xff0c;用户一旦点击了这个请求&#xff0c;整个攻击就完成…

IDEA的lombok插件不生效了?!!

记录一下&#xff0c;防止找不到解决方案&#xff0c;已经遇到好几次了 前面啰嗦的多&#xff0c;可以直接跳到末尾的解决方法&#xff0c;点击一下 问题现场情况 排查过程 确认引入的依赖正常 —》&#x1f197; idea 是否安装了lombok插件 --》&#x1f197; 貌似没有问题…