基于Python实现超级玛丽游戏的示例代码
作者:梦执.py 发布时间:2022-02-14 16:48:00
标签: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


猜你喜欢
- 一个可能你似曾相识的场景阅读内容包含大量英文的 PPT、Word、Excel 或者记事本时,由于英语不熟悉,为了流利地阅读,需要打开浏览器进
- __str__和__repr__的异同?字符串的表示形式我们都知道,Python的内置函数repr()能够把对象用字符串的形式表达出来,方便
- 处理上传的文件: f1 = request.FILES['pic'] fname = '%s/%s' % (
- 最近需要爬取某网站,无奈页面都是JS渲染后生成的,普通的爬虫框架搞不定,于是想到用Phantomjs搭一个代理。Python调用Phanto
- 技术背景对于各行各业的研究人员来说,经常会面临这样的一个问题:有一篇不错的文章里面有很好的数据,但是这个数据在文章中仅以图片的形式出现。而假
- Python安装为什么默认安装到c盘?所有的软件如果你不对安装过程的路径进行设置的话都是默认安装到c盘的,不仅仅是Python。那安装到c盘
- 代码如下:Function getTreeRootId(pNodeId) getSQL = "select note_id,par
- 前言最近遇到一个临时需求,需要将客户环境中一个服务每天的日志进行一系列复杂处理,并生成数据报表。由于数据处理逻辑复杂,且需要存入数据库,在客
- 今天我去隽辰的博客去看他的文章,在读完他的文章之后,我很自然的就去读网友们给他留的评论,在读的时候我发现他的评论是顺序的,也就是最早的评论在
- 本文实例为大家分享了Vue+Flask实现图片传输功能的具体代码,供大家参考,具体内容如下完整流程:1.图片转为formdata 传输到后端
- setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。语法:setTimeout(code,millisec)参数:cod
- 案例:该数据集的是一个关于每个学生成绩的数据集,接下来我们对该数据集进行分析,判断学生是否适合继续深造数据集特征展示1 GRE
- 本文实例讲述了php 多个变量指向同一个引用($b = &$a)用法。分享给大家供大家参考,具体如下:引用是什么? 引用就是多个变量
- 如题在SQL中 SELECT ... FROM ... ORDER BY abc ASC; 如果abc是字符串,那么结果会按照a-z 中文按
- Select字句在逻辑上是SQL语句最后进行处理的最后一步,所以,以下查询会发生错误:SELECT YEAR(OrderDate) AS O
- 数据可视化是以图形格式呈现数据。它通过以简单易懂的格式汇总和呈现大量数据,帮助人们理解数据的重要性,并有助于清晰有效地传达信息。考虑这个给定
- 本文将结合实例给大家演示如何使用ASP读取一个目录结构(及包含的文件信息)。演示页面中遍历显示了代码吾爱站点上若干目录文件夹——其中包含它们
- 第一步,下载依赖yarn add kindeditor第二步,建立kindeditor.vue组件<template> <
- 主要作用为指定图片像素:matplotlib.rcParams[‘figure.figsize']#图片像素 matplotlib.
- 函数函数的英文单词是 Function,这个单词还有着功能的意思。在 Go 语言中,函数是实现某一特定功能的代码块。函数代表着某个功能,可以