草庐IT

python快速实现简易超级玛丽小游戏

ASS-ASH 2023-04-11 原文

《超级玛丽》是一款超级马里奥全明星的同人作品,也是任天堂公司出品的著名横版游戏。

《超级马里奥》是一款经典的像素冒险过关游戏。最早在红白机上推出,有多款后续作品,迄今多个版本合共销量已突破4000万套。其中的主角马里奥路易碧琪公主奇诺比奥等等已成为任天堂的招牌人物。主角马里奥日文原名マリオ,英文译作Mario,在译成中文时因时代不同,华语圈地区不同而译作"马力欧""玛丽"等情况也确有存在。根据任天堂公布的官方中文译名和牛津词典,一般称为"马里奥"。 

完整代码如下:

import numpy as np
import random, sys
import pgzrun
class Brick(Actor):
    def react(self):
        if np.abs(mario.center[1]+mario.size[1]/2-self.center[1]+self.size[1]/2)<15: # z gory
            mario.vy = 0
            mario.bottom = self.top
        elif np.abs(mario.center[1]-mario.size[1]/2-self.center[1]-self.size[1]/2)<15: # z dolu
            mario.vy = 0
            mario.top = self.bottom
        elif np.abs(mario.center[0]+mario.size[0]/2-self.center[0]+self.size[0]/2)<15: # z prawej
            moveall(6)
        elif np.abs(mario.center[0]-mario.size[0]/2-self.center[0]-self.size[0]/2)<15: # z lewej
            moveall(-6)
    def move(self):
        pass

class Coin(Actor):
    def react(self):
        if mario.colliderect(self):
            #sounds.coin.play()
            objs.remove(self)
            mario.points=mario.points+1
    def move(self):
        pass

class Block(Actor):
    def react(self):
        if np.abs(mario.center[1]+mario.size[1]/2-self.center[1]+self.size[1]/2)<15: # z gory
            mario.vy = 0
            mario.bottom = self.top
        elif np.abs(mario.center[1]-mario.size[1]/2-self.center[1]-self.size[1]/2)<15: # z dolu
            mario.vy = 0
            mario.top = self.bottom
            animate(self, pos=(self.center[0], -10000))
        elif np.abs(mario.center[0]+mario.size[0]/2-self.center[0]+self.size[0]/2)<15: # z prawej
            moveall(6)
        elif np.abs(mario.center[0]-mario.size[0]/2-self.center[0]-self.size[0]/2)<15: # z lewej
            moveall(-6)
    def move(self):
        pass

class Mushroom(Actor):
    def react(self):
        if self.colliderect(mario):
            mario.small=False
            objs.remove(self)
    def move(self):
        for obj in objs:
            if obj!=self and self.colliderect(obj) and not obj.image in ["bush.png","brick.png","hill.png"]:
                self.dir=-self.dir

        self.x=self.x+self.dir

        uy=self.vy
        self.vy=self.vy+2000.0*0.015
        self.y=self.y+(uy+self.vy)*0.5*0.015

        for obj in objs:
            if self.colliderect(obj) and np.abs(self.center[1]+self.size[1]/2-obj.center[1]+obj.size[1]/2)<15:
                self.vy = 0
                self.bottom = obj.top

class Question(Actor):
    def react(self):
        if np.abs(mario.center[1]+mario.size[1]/2-self.center[1]+self.size[1]/2)<15: # z gory
            mario.vy = 0
            mario.bottom = self.top
        elif np.abs(mario.center[1]-mario.size[1]/2-self.center[1]-self.size[1]/2)<15: # z dolu
            mario.vy = 0
            mario.top = self.bottom
            if self.image=="question.png":
                self.image = "question2.png"
                objs.append(Mushroom("mushroom.png",(self.center[0],self.center[1]-50)))
                objs[-1].dir=1
                objs[-1].vy=0
                animate(objs[-1],pos=(self.center[0],self.center[1]-objs[-1].size[1]+2))
        elif np.abs(mario.center[0]+mario.size[0]/2-self.center[0]+self.size[0]/2)<15: # z prawej
            moveall(6)
        elif np.abs(mario.center[0]-mario.size[0]/2-self.center[0]-self.size[0]/2)<15: # z lewej
            moveall(-6)
    def move(self):
        pass

class Cloud(Actor):
    def react(self):
        pass
    def move(self):
        self.x=(self.x-1)%7000

class Monster(Actor):
    def react(self):
        if np.abs(mario.center[1]+mario.size[1]/2-self.center[1]+self.size[1]/2)<15: # z gory
            mario.vy = 0
            mario.bottom = self.top
            animate(self, pos=(self.right+50, HEIGHT+50))
        elif np.abs(mario.center[1]-mario.size[1]/2-self.center[1]-self.size[1]/2)<15: # z dolu
            mario.vy = 0
            mario.top = self.bottom
        elif np.abs(mario.center[0]+mario.size[0]/2-self.center[0]+self.size[0]/2)<15: # z prawej
            if mario.small:
                mario.dead = True
                newgame()
            else:
                animate(self, pos=(self.right+50, HEIGHT+50))
                mario.small=True
        elif np.abs(mario.center[0]-mario.size[0]/2-self.center[0]-self.size[0]/2)<15: # z lewej
            if mario.small:
                mario.dead = True
                newgame()
            else:
                animate(self, pos=(self.right+50, HEIGHT+50))
                mario.small=True

    def move(self):
        for obj in objs:
            if obj!=self and self.colliderect(obj) and not obj.image in ["bush.png","brick.png","hill.png"]:
                self.dir=-self.dir

        if self.dir==1 and self.image in ["turtle.png","turtleleft.png"]:
            self.image = "turtle.png"
        elif self.dir==-1 and self.image in ["turtle.png","turtleleft.png"]:
            self.image = "turtleleft.png"

        self.x=self.x+self.dir

class Bush(Actor):
    def react(self):
        pass
    def move(self):
        pass

def newgame():
    mario.pos=(200,HEIGHT-120)
    mario.vy=0
    mario.time=0
    mario.dir="right"
    mario.dead=False
    mario.small=True
    mario.s="s"
    mario.points=0
    mario.win=False

    for i in range(len(objs)):
        objs.remove(objs[0])
    file = open(sys.path[0] + "\\level1.dat")

    i = 0
    for line in file:
        for j in range(len(line)):
            if line[j]=="O":
                objs.append(Brick("brick.png",(j*32,32*i)))
            elif line[j]=="B":
                objs.append(Brick("brick2.png",(j*32,32*i)))
            elif line[j]=="D":
                objs.append(Block("block.png",(j*32,32*i)))
            elif line[j]=="Q":
                objs.append(Question("question.png",(j*32,32*i)))
            elif line[j]=="c":
                objs.append(Cloud("cloud.png",(j*32,32*i)))
            elif line[j]=="h":
                objs.append(Bush("hill.png",(j*32,32*i-22)))
            elif line[j]=="b":
                objs.append(Bush("bush.png",(j*32,32*i-12)))
            elif line[j]=="E":
                objs.append(Monster("enemy1.png",(j*32,32*i)))
                objs[-1].dir = 1
            elif line[j]=="T":
                objs.append(Monster("turtle.png",(j*32,32*i)))
                objs[-1].dir = 1
            elif line[j]=="p":
                objs.append(Coin("coin.png",(j*32,32*i)))

        i = i + 1

        music.play("theme.mp3")

def draw():
    screen.fill((148, 146, 255))
    for obj in objs:
        obj.draw()
    mario.draw()
    screen.draw.text(str(mario.points),color="black",midtop=(WIDTH/8*7,10),fontsize=70,shadow=(0,0))
    if mario.win:
        screen.draw.text("You win!",color="black",midtop=(WIDTH/2,10),fontsize=170,shadow=(0,0))

def moveall(x):
    if x>0:
        if 0<=mario.x:
            mario.x=mario.x-x
        elif mario.x<0:
            mario.x=0
    else:
        if 0<=mario.x<WIDTH/2:
            mario.x=mario.x-x
        elif mario.x>WIDTH/2:
            mario.x=WIDTH/2
        elif mario.x>=WIDTH/2:
            for obj in objs:
                obj.x=obj.x+x

def move(dt):
    if mario.dir=="right":
        mario.image= mario.s + "mario.png"
    else:
        mario.image= mario.s + "marioleft.png"

    uy=mario.vy
    mario.vy=mario.vy+2000.0*dt
    mario.y=mario.y+(uy+mario.vy)*0.5*dt

    if keyboard.right:
        if mario.small:
            moveall(-2)
        else:
            moveall(-3)
        mario.dir="right"
        if mario.time<8:
            mario.image= mario.s + "mariomove.png"
        else:
            mario.image= mario.s + "mariomove2.png"
    if keyboard.left:
        if mario.small:
            moveall(2)
        else:
            moveall(3)
        mario.dir="left"
        if mario.time<8:
            mario.image= mario.s + "mariomoveleft.png"
        else:
            mario.image= mario.s + "mariomoveleft2.png"

    for obj in objs:
        if  mario.colliderect(obj):
            obj.react()

    if mario.vy !=0 and mario.dir=="right":
        mario.image= mario.s + "mariojump.png"
    elif mario.vy !=0 and mario.dir=="left":
        mario.image= mario.s + "mariojumpleft.png"

    if mario.bottom>HEIGHT:
        mario.dead = True

def update(dt):
    if mario.small:
        mario.s="s"
    else:
        mario.s=""
    mario.time=(mario.time+1)%16
    if not mario.win:
        move(dt)
        for obj in objs:
            obj.move()
            if obj.image=="castle.png":
                if np.abs(obj.center[0]-mario.center[0])<20:
                    mario.win=True
    if mario.dead:
        #music.pause()
        #sounds.gameover.play()
        #from pygame import time
        #mario.dead = False
        #time.wait(3000)
        newgame()

def on_key_down(key):
    if key==keys.SPACE and mario.vy==0:
        mario.vy=-800


HEIGHT=640
WIDTH=1024
TITLE="Mario"

mario=Actor("smario.png",(200,HEIGHT-120))
mario.vy=0
mario.time=0
mario.dir="right"
mario.dead=False
mario.small=True
mario.s="s"
mario.points=0
mario.win=False
objs = []
newgame()
pgzrun.go()

运行效果如下:

 关于项目运行的说明:

操作方式:键盘方向键左右移动,空格键跳跃

一、完整项目(游戏素材+代码)获取方式如下:

阿里云盘分享

其中music文件夹和sounds文件夹为空,music文件夹下为mp3格式的游戏背景音乐,可根据需要自行应用,放置在music文件夹下重命名为 theme 即可

如,直接在qq音乐中搜索下载游戏的经典背景音乐

sounds文件夹应该是吃金币的音效文件,暂未补充,可以将22行的代码注释以此消除吃金币时产生的闪退问题

 二、pyzrun导入失败问题

需要安装pyzero包,pip install pyzero即可

三、地图问题

地图根据项目资源中的level1.dat构建

c代表云朵,p代表金币,D代表可撞碎的方块,Q代表包含变大蘑菇的问号方块,B代表地图中帮助跳跃的不可撞碎的方块,h为小山背景,b为灌木丛背景,E为蘑菇怪敌人,T为乌龟敌人,O为地面

 对比图:

自行在level1.dat中最后部分增加的地图:

 

 

主要参考来源

Python编写超级玛丽竟如此简单?不信你试试_qianer的博客-CSDN博客

有关python快速实现简易超级玛丽小游戏的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  3. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  4. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  5. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  6. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

  7. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  8. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  9. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  10. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

随机推荐