网络编程
位置:首页>> 网络编程>> Python编程>> 基于Python实现超级玛丽游戏的示例代码

基于Python实现超级玛丽游戏的示例代码

作者:梦执.py  发布时间:2022-02-14 16:48:00 

标签:Python,超级玛丽,游戏

效果演示

基于Python实现超级玛丽游戏的示例代码

基础源码

1.基础设置(tools部分)

这个部分设置马里奥以及游戏中蘑菇等怪的的移动设置。

import os
import pygame as pg

keybinding = {
   'action':pg.K_s,
   'jump':pg.K_a,
   'left':pg.K_LEFT,
   'right':pg.K_RIGHT,
   'down':pg.K_DOWN
}

class Control(object):
   """Control class for entire project. Contains the game loop, and contains
   the event_loop which passes events to States as needed. Logic for flipping
   states is also found here."""
   def __init__(self, caption):
       self.screen = pg.display.get_surface()
       self.done = False
       self.clock = pg.time.Clock()
       self.caption = caption
       self.fps = 60
       self.show_fps = False
       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.quit:
           self.done = True
       elif 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)
       self.state.previous = previous

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()
               self.toggle_show_fps(event.key)
           elif event.type == pg.KEYUP:
               self.keys = pg.key.get_pressed()
           self.state.get_event(event)

def toggle_show_fps(self, key):
       if key == pg.K_F5:
           self.show_fps = not self.show_fps
           if not self.show_fps:
               pg.display.set_caption(self.caption)

def main(self):
       """Main loop for entire program"""
       while not self.done:
           self.event_loop()
           self.update()
           pg.display.update()
           self.clock.tick(self.fps)
           if self.show_fps:
               fps = self.clock.get_fps()
               with_fps = "{} - {:.2f} FPS".format(self.caption, fps)
               pg.display.set_caption(with_fps)

class _State(object):
   def __init__(self):
       self.start_time = 0.0
       self.current_time = 0.0
       self.done = False
       self.quit = False
       self.next = None
       self.previous = None
       self.persist = {}

def get_event(self, event):
       pass

def startup(self, current_time, persistant):
       self.persist = persistant
       self.start_time = current_time

def cleanup(self):
       self.done = False
       return self.persist

def update(self, surface, keys, current_time):
       pass

def load_all_gfx(directory, colorkey=(255,0,255), accept=('.png', 'jpg', 'bmp')):
   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

def load_all_music(directory, accept=('.wav', '.mp3', '.ogg', '.mdi')):
   songs = {}
   for song in os.listdir(directory):
       name,ext = os.path.splitext(song)
       if ext.lower() in accept:
           songs[name] = os.path.join(directory, song)
   return songs

def load_all_fonts(directory, accept=('.ttf')):
   return load_all_music(directory, accept)

def load_all_sfx(directory, accept=('.wav','.mpe','.ogg','.mdi')):
   effects = {}
   for fx in os.listdir(directory):
       name, ext = os.path.splitext(fx)
       if ext.lower() in accept:
           effects[name] = pg.mixer.Sound(os.path.join(directory, fx))
   return effects

2.设置背景音乐以及场景中的文字(setup部分)

该部分主要设置场景中的背景音乐,以及字体的显示等设置。

import os
import pygame as pg
from . import tools
from .import constants as c

ORIGINAL_CAPTION = c.ORIGINAL_CAPTION

os.environ['SDL_VIDEO_CENTERED'] = '1'
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()

FONTS = tools.load_all_fonts(os.path.join("resources","fonts"))
MUSIC = tools.load_all_music(os.path.join("resources","music"))
GFX   = tools.load_all_gfx(os.path.join("resources","graphics"))
SFX   = tools.load_all_sfx(os.path.join("resources","sound"))

3.设置游戏规则(load_screen)

from .. import setup, tools
from .. import constants as c
from .. import game_sound
from ..components import info

class LoadScreen(tools._State):
   def __init__(self):
       tools._State.__init__(self)

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_overhead_info_state()

self.overhead_info = info.OverheadInfo(self.game_info, info_state)
       self.sound_manager = game_sound.Sound(self.overhead_info)

def set_next_state(self):
       """Sets the next state"""
       return c.LEVEL1

def set_overhead_info_state(self):
       """sets the state to send to the overhead info object"""
       return c.LOAD_SCREEN

def update(self, surface, keys, current_time):
       """Updates the loading screen"""
       if (current_time - self.start_time) < 2400:
           surface.fill(c.BLACK)
           self.overhead_info.update(self.game_info)
           self.overhead_info.draw(surface)

elif (current_time - self.start_time) < 2600:
           surface.fill(c.BLACK)

elif (current_time - self.start_time) < 2635:
           surface.fill((106, 150, 252))

else:
           self.done = True

class GameOver(LoadScreen):
   """A loading screen with Game Over"""
   def __init__(self):
       super(GameOver, self).__init__()

def set_next_state(self):
       """Sets next state"""
       return c.MAIN_MENU

def set_overhead_info_state(self):
       """sets the state to send to the overhead info object"""
       return c.GAME_OVER

def update(self, surface, keys, current_time):
       self.current_time = current_time
       self.sound_manager.update(self.persist, None)

if (self.current_time - self.start_time) < 7000:
           surface.fill(c.BLACK)
           self.overhead_info.update(self.game_info)
           self.overhead_info.draw(surface)
       elif (self.current_time - self.start_time) < 7200:
           surface.fill(c.BLACK)
       elif (self.current_time - self.start_time) < 7235:
           surface.fill((106, 150, 252))
       else:
           self.done = True

class TimeOut(LoadScreen):
   """Loading Screen with Time Out"""
   def __init__(self):
       super(TimeOut, self).__init__()

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

def set_overhead_info_state(self):
       """Sets the state to send to the overhead info object"""
       return c.TIME_OUT

def update(self, surface, keys, current_time):
       self.current_time = current_time

if (self.current_time - self.start_time) < 2400:
           surface.fill(c.BLACK)
           self.overhead_info.update(self.game_info)
           self.overhead_info.draw(surface)
       else:
           self.done = True

4.设置游戏内菜单等(main_menu)


import pygame as pg
from .. import setup, tools
from .. import constants as c
from .. components import info, mario

class Menu(tools._State):
   def __init__(self):
       """Initializes the state"""
       tools._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_STATE: None,
                  c.CAMERA_START_X: 0,
                  c.MARIO_DEAD: False}
       self.startup(0.0, persist)

def startup(self, current_time, persist):
       """Called every time the game's state becomes this one.  Initializes
       certain values"""
       self.next = c.LOAD_SCREEN
       self.persist = persist
       self.game_info = persist
       self.overhead_info = info.OverheadInfo(self.game_info, c.MAIN_MENU)

self.sprite_sheet = setup.GFX['title_screen']
       self.setup_background()
       self.setup_mario()
       self.setup_cursor()

def setup_cursor(self):
       """Creates the mushroom cursor to select 1 or 2 player game"""
       self.cursor = pg.sprite.Sprite()
       dest = (220, 358)
       self.cursor.image, self.cursor.rect = self.get_image(
           24, 160, 8, 8, dest, setup.GFX['item_objects'])
       self.cursor.state = c.PLAYER1

def setup_mario(self):
       """Places Mario at the beginning of the level"""
       self.mario = mario.Mario()
       self.mario.rect.x = 110
       self.mario.rect.bottom = c.GROUND_HEIGHT

def setup_background(self):
       """Setup the background image to blit"""
       self.background = setup.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 = setup.SCREEN.get_rect(bottom=setup.SCREEN_RECT.bottom)

self.image_dict = {}
       self.image_dict['GAME_NAME_BOX'] = self.get_image(
           1, 60, 176, 88, (170, 100), setup.GFX['title_screen'])

def get_image(self, x, y, width, height, dest, sprite_sheet):
       """Returns images and rects to blit onto the screen"""
       image = pg.Surface([width, height])
       rect = image.get_rect()

image.blit(sprite_sheet, (0, 0), (x, y, width, height))
       if sprite_sheet == setup.GFX['title_screen']:
           image.set_colorkey((255, 0, 220))
           image = pg.transform.scale(image,
                                  (int(rect.width*c.SIZE_MULTIPLIER),
                                   int(rect.height*c.SIZE_MULTIPLIER)))
       else:
           image.set_colorkey(c.BLACK)
           image = pg.transform.scale(image,
                                  (int(rect.width*3),
                                   int(rect.height*3)))

rect = image.get_rect()
       rect.x = dest[0]
       rect.y = dest[1]
       return (image, rect)

def update(self, surface, keys, current_time):
       """Updates the state every refresh"""
       self.current_time = current_time
       self.game_info[c.CURRENT_TIME] = self.current_time
       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.mario.image, self.mario.rect)
       surface.blit(self.cursor.image, self.cursor.rect)
       self.overhead_info.draw(surface)

def update_cursor(self, keys):
       """Update the position of the cursor"""
       input_list = [pg.K_RETURN, pg.K_a, pg.K_s]

if self.cursor.state == c.PLAYER1:
           self.cursor.rect.y = 358
           if keys[pg.K_DOWN]:
               self.cursor.state = c.PLAYER2
           for input in input_list:
               if keys[input]:
                   self.reset_game_info()
                   self.done = True
       elif self.cursor.state == c.PLAYER2:
           self.cursor.rect.y = 403
           if keys[pg.K_UP]:
               self.cursor.state = c.PLAYER1

def reset_game_info(self):
       """Resets the game info in case of a Game Over and restart"""
       self.game_info[c.COIN_TOTAL] = 0
       self.game_info[c.SCORE] = 0
       self.game_info[c.LIVES] = 3
       self.game_info[c.CURRENT_TIME] = 0.0
       self.game_info[c.LEVEL_STATE] = None

self.persist = self.game_info

5.main()

from . import setup,tools
from .states import main_menu,load_screen,level1
from . import constants as c

def main():
   """Add states to control here."""
   run_it = tools.Control(setup.ORIGINAL_CAPTION)
   state_dict = {c.MAIN_MENU: main_menu.Menu(),
                 c.LOAD_SCREEN: load_screen.LoadScreen(),
                 c.TIME_OUT: load_screen.TimeOut(),
                 c.GAME_OVER: load_screen.GameOver(),
                 c.LEVEL1: level1.Level1()}

run_it.setup_states(state_dict, c.MAIN_MENU)
   run_it.main()

6.调用以上函数实现

import sys
import pygame as pg
from 小游戏.超级玛丽.data.main import main
import cProfile

if __name__=='__main__':
   main()
   pg.quit()
   sys.exit()

来源:https://blog.csdn.net/m0_70127749/article/details/124581389

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com