赞
踩
哈喽!大家好,这里是cwt的成长日记!
有多少人还记得“超级玛丽”这款经典游戏?
有多少人还记得那个戴帽子、大胡子、穿着背带裤的马里奥!
前段时间给大家更新了超级玛丽的基础版,只包含了第一关的部分功能。此次更新完善了第一关细节,并且更新到第4关。大家可以一口气玩四关喽。
后续关卡细节方面大家可以自由发挥,制作出属于自己独一无二的超级玛丽!!!
语言:python3
编译器:pycharm(好用)
#各自官网均可下载
主要模块:pygame (pip install pygame 即可安装该模块)
main.py游戏主入口 source components成分,部件 -box.py 盒子(游戏中带问号的方格) -brick.py 砖块 def __init__(self,x,y,brick_type,group,color=None,name='brick'): -coin.py 金币 -enemy.py 敌人 -player.py 主角 def __init__(self,name): pygame.sprite.Sprite.__init__(self) self.name = name self.load_data() #加载角色数据,各种造型帧即其各种状态的速度 self.setup_states() #初始化角色各种状态 self.setup_velocities() #设置速率 self.setup_timers() #设置计时器 self.load_images() #载入主角的各种帧造型 def update(self,keys,level): self.current_time = pygame.time.get_ticks() #以毫秒为单位获取时间 self.handle_states(keys,level) #处理各种状态 self.is_hurt_immune() #判断是否为无敌模式 def handle_states(self,keys,level): #处理各种状态 -powerup.py 强化(游戏中蘑菇) def create_powerup(centerx,centery,type,flag): """create powerup based on type and mario state""" if flag ==0: return Mushroom(centerx,centery) elif flag ==1: return Fireflower(centerx, centery) elif flag ==2: return LifeMushroom(centerx, centery) elif flag == 3: return Star(centerx, centery) -stuff.py 物品(不起眼的小道具,旗子水管等) class Item(pygame.sprite.Sprite): def __init__(self,x,y,w,h,name): '''每个物品都有了隐形的轮廓,方便使用,方便进行碰撞检测,不需要传入图像,因为地图上有这些的图像了''' pygame.sprite.Sprite.__init__(self) class Checkpoint(Item): '''检查点实际就是一个长方体精灵,碰到之后才会触发下面的事件''' def __init__(self, x, y, w, h, checkint_type, enemy_groupid=None, name='checkpoint'): Item.__init__(self,x,y,w,h,name) self.checkpoint_type = checkint_type self.enemy_groupid = enemy_groupid -info.py 游戏信息(显示在屏幕上方的英文字体等) def __init__(self,state): self.state = state self.create_state_lable() #创某阶段特有的文字 self.create_info_labels() #创建各阶段通用性息 self.flash_coin = coin.FlashingCoin() #初始化金币类 def create_state_lable(self): #创造某阶段特有的文字 def create_info_labels(self): #创建各阶段通用性息 def create_lable(self,label,size=40,width_scale=1.25,height_csale=1): #文字生成图片 def update(self): #调用金币类更新类更新方法,实现金币闪烁 def draw(self,surface): #把静态文字,动态金币等信息画上去 states状态 -main_menu.py 主页面(游戏刚进入的主菜单) -MainMenu()类 def __init__(self): #初始化游戏信息字典 game_info={ } def start(self,game_info,current_time): #使用start函数对该状态进行初始化, self.current_time=current_time self.game_info=game_info self.setup_background() #设置背景底图 self.setup_cursor() #设置光标 self.setup_palyer() #设置游戏角色 self.info=info.Info('main_menu',self.game_info) #初始化该类,设置文字信息 self.finished=False #主页面是否结束(状态机) self.next = 'load_screen' def update() -load_screen.py 载入页面 def start(self,game_info,current_time): self.game_info=game_info #获取信息 self.game_info['statue']='load_screen' #修改游戏状态 self.finished= False #告诉程序当前状态未结束 self.next = 'level' #下个关卡为level self.duration=2000 #持续时间 self.timer = 0 #定时器 self.info = info.Info('load_screen',self.game_info) #初始化页面信息 def update(): def draw(): -level.py 游戏关卡 def start(self,game_info,current_time): self.current_time=current_time self.game_info=game_info self.game_info['statue'] = 'level' self.finished= False self.next = 'game_over' self.info=info.Info('level',self.game_info) #self.flag=plagpole.Flag(470,116) self.load_map_data() #加载关卡数据 self.setup_background() #设置背景,新建了一个北京大小的图层 self.setup_start_posotions()#新建起始位置的方法 self.setup_player() self.setup_ground_items() #设置大地,管道,楼梯,加载到精灵组 self.setup_brick_and_box() self.setup_enemy() self.setup_checkpoints() #初始化检查点 self.setup_flag() self.sound=sound.Sound(self) constants.py 存储游戏常量 sound.py 音效/音乐 set_up.py 启动代码(如设置屏幕宽高,载入素材等) tools.py 主控,工具代码 (好用的工具,如图片加载工具) -Game()类,游戏主控. Game().run运行游戏. Game().update更新游戏 def __init__(self,state_dict,start_state): self.screen=pygame.display.get_surface() #获取当前显示的 Surface 对象,获得屏幕 self.clock=pygame.time.Clock()#创建一个时钟,控制帧率 self.keys=pygame.key.get_pressed() #获取按键状态 self.state_dict=state_dict #获取主菜单的状态字典 self.state=self.state_dict[start_state] #保存传入的状态(初始化该状态的类) def update(self): -判断游戏当前状态是否结束,如果结束就传入下一个状态,初始化该状态并调用该状态的start()方法,目的是传递游戏数据。没有结束就调用当前状态的更新方法 def run(self): -循环获取事件,监听事件状态(键盘按键) -调用自身update方法 -更新屏幕 -设置游戏帧率(越大越流畅) -load_graphics(path:图片路径)函数:加载图片 return:graphics{name:img} 本项目加载的是一张大图,大图上有很多小图 -pygame.image.load("图片路径").convert() -get_image(sheet:传入加载后的图片,x:图片在大图的x坐标,y:图片在大图的y坐标,width:图片宽,height:图片高,colorkey:改颜色设置为透明,scale:放大倍速) -load_all_music(directory, accept=('.wav', '.mp3', '.ogg', '.mdi')): #加载音乐 -load_all_sound(directory, accept=('.wav','.mpe','.ogg','.mdi')): #加载按键声 难点: Mario的位置:由其速度决定,由速度计算出位置 画面跟随:简单解决方法,1.锁定主角移动背景(略显沉闷) 2.主角动,背景也动 -新建一个新图层 -把游戏里的事件正常画在该图层 -把游戏窗口显示的画面渲染到屏幕上 碰撞检测: 常规做法: -要把所有可能与Mario发生碰撞的物体一一罗列出来,依次做碰撞检测 -python中,可用精灵组加碰撞检测api实现 柱子水管等: - 从json文件中读出坐标,逐个个实例化 - 创建了一个精灵组,把所有相同类型的放入同一组 - 然后在Mario位置更新函数中进行配置 信息传递:在第一个调用类的初始化函数中初始化game_info,用start函数代替初始化函数初始化类的各种函数,这样start可以反复调用,实现该阶段重置效果 传递到其他类中传入game_info 宝箱顶起4过程:1正常状态,2被顶了下,3微微隆起,4打开破碎 检查点技术:实际就是一个无形的矩形(为了解决Mario不论速度快慢都能见到对应阶段的野怪) bug:mario从右边碰到物体会身体会嵌入一些 精灵组:为了方便碰撞检测和统一操作 mario吃蘑菇变身时只写了x方向检测,注意y方向检车会使mario变成fall状态
#编写者:cwt #时间:2022/7/4 20:39 #游戏入口 from source import tools,setup from source.statues import main_menu,level,load_screen,level2 import pygame def main(): state_dict = { 'main_menu' : main_menu.MainMenu(), 'load_screen' : load_screen.LoadScreen(), 'level' : level.Level(), 'game_over': load_screen.GameDver(), 'level2': level.Level2(), 'load_level2': load_screen.Load_level2(), 'level3': level.Level3(), 'load_level3': load_screen.Load_level3(), 'level4': level.Level4(), 'load_level4': load_screen.Load_level4() } '''test''' game=tools.Game(state_dict,'main_menu') #初始化游戏主控 # state=main_menu.MainMenu() #初始化主页面 # state = level.Level() # state = load_screen.LoadScreen() game.run() #运行游戏 if __name__ == '__main__': main()
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_sound(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] = pygame.mixer.Sound(os.path.join(directory, fx)) return effects
#编写者:cwt #时间:2022/7/4 21:23 #关卡 class Level: def start(self,game_info): self.game_info=game_info self.finished= False self.next = 'game_over' self.info=info.Info('level',self.game_info) print(self.flag) self.load_map_data() self.setup_background() self.setup_start_posotions()#新建起始位置的方法 self.setup_player() self.setup_ground_items() self.setup_brick_and_box() self.setup_enemy() self.setup_checkpoints() #初始化检查点 self.setup_flag() class Level2(Level): def __init__(self): Level.__init__(self) def load_map_data(self): file_name = 'level_2.json' file_path = os.path.join('D:/Users/Administrator/PycharmProjects/superMario/source/data/maps/', file_name) with open(file_path) as f: self.map_data = json.load(f) def is_or_not_finished(self,keys): #print(self.player.baoqi,self.player.rect.y) if keys[pygame.K_9]: self.finished = True self.next = 'load_level3' if self.player.baoqi== True and self.player.rect.y>400: self.finished=True self.next = 'load_level3' class Level3(Level): def __init__(self): Level.__init__(self) def load_map_data(self): file_name = 'level_3.json' file_path = os.path.join('D:/Users/Administrator/PycharmProjects/superMario/source/data/maps/', file_name) with open(file_path) as f: self.map_data = json.load(f) def is_or_not_finished(self,keys): # print(self.player.baoqi,self.player.rect.y) if keys[pygame.K_9]: self.finished = True self.next = 'load_level4' if self.player.baoqi == True and self.player.rect.y > 400: self.finished = True self.next = 'load_level4' class Level4(Level): def __init__(self): Level.__init__(self) def load_map_data(self): file_name = 'level_4.json' file_path = os.path.join('D:/Users/Administrator/PycharmProjects/superMario/source/data/maps/', file_name) with open(file_path) as f: self.map_data = json.load(f) def setup_flag(self): self.pole_group = pygame.sprite.Group() self.flag_group = pygame.sprite.Group() self.finial_group = pygame.sprite.Group() '''测试用''' for item in [{"x":6470, "y":116, "type":0}, {"x":6500, "y": 97, "type":1}, {"x":6500, "y":137, "type":1}, {"x":6500, "y":177, "type":1}, {"x":6500, "y":217, "type":1}, {"x":6500, "y":257, "type":1}, {"x":6500, "y":297, "type":1}, {"x":6500, "y":337, "type":1}, {"x":6500, "y":377, "type":1}, {"x":6500, "y":417, "type":1}, {"x":6500, "y":450, "type":1}, {"x":6500, "y": 97, "type":2}]: # for item in self.map_data['flagpole']: x, y, type = item['x'], item['y'], item['type'] if type == 0: self.flag_group.add(plagpole.Flag(x, y)) elif type == 1: self.pole_group.add(plagpole.Pole(x, y)) else: self.finial_group.add(plagpole.Finial(x, y)) def is_or_not_finished(self,keys): # print(self.player.baoqi,self.player.rect.y) if keys[pygame.K_8]: self.player.hurt_imune =True #伤害免疫 if keys[pygame.K_7]: self.player.hurt_imune = False # 伤害免疫 if keys[pygame.K_9]: self.finished = True self.next = 'load_screen' if self.player.baoqi == True and self.player.rect.y > 400: self.finished = True self.next = 'load_screen'
class Sound(object): """Handles all sound for the game""" def __init__(self, level): """Initialize the class""" self.sound_dict = setup.SOUND self.music_dict = setup.MUSIC self.level =level # self.overhead_info = overhead_info # self.game_info = overhead_info.game_info self.set_music_mixer() def set_music_mixer(self): """Sets music for level""" if self.level.player.dead: pg.mixer.music.load(self.music_dict['death']) pg.mixer.music.play() self.state = c.GAME_OVER else: pg.mixer.music.load(self.music_dict['main_theme']) pg.mixer.music.play() self.state = c.NORMAL def update(self, game_info, mario): """Updates sound object with game info""" self.game_info = game_info self.mario = mario self.handle_state() def handle_state(self): """Handles the state of the soundn object""" #print('444') if self.state == c.NORMAL: if self.mario.dead: self.play_music('death', c.MARIO_DEAD) def play_music(self, key, state): """Plays new music""" pg.mixer.music.load(self.music_dict[key]) pg.mixer.music.play() self.state = state def stop_music(self): """Stops playback""" pg.mixer.music.stop()
python制作超级玛丽,好玩到飞起!
地址:https://www.bilibili.com/video/BV1x24y1o7xN/?spm_id_from=333.999.0.0&vd_source=fb2219609a4ef30c028c05ca593238e9
本项目参考B站up主教程,完整代码已上传github,持续更新优化,需要的小伙伴自取:https://github.com/cwt2022/Mario
对游戏感兴趣的小伙伴儿赶紧自己动手造一个吧~~
有问题的小伙伴可以在评论区留言,大家一起学习共同进步!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。