用Python写一个超级玛丽游戏(附源码)

Python3.8

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

前言

小时候最喜欢玩的小游戏就是超级玛丽了,有刺激有又技巧,通关真的很难,救下小公主还被抓走了,唉,心累,最后还是硬着头皮继续闯,终于要通关了,之后再玩还是没有那么容易,哈哈,不知道现在能不能通关,今天就来简单实现一下,如果有时间会实现完整的闯关版。

超级玛丽

图片

运行起来是这样的,里面内置了两关,可以简单作为试玩。

图片

绘制金币:

class Coin(EntityBase):    def __init__(self, screen, spriteCollection, x, y, gravity=0):        super(Coin, self).__init__(x, y, gravity)        self.screen = screen        self.spriteCollection = spriteCollection        self.animation = copy(self.spriteCollection.get("coin").animation)        self.type = "Item"    def update(self, cam):        if self.alive:            self.animation.update()            self.screen.blit(self.animation.image, (self.rect.x + cam.x, self.rect.y))

绘制玛丽:

spriteCollection = Sprites().spriteCollectionsmallAnimation = Animation(    [        spriteCollection["mario_run1"].image,        spriteCollection["mario_run2"].image,        spriteCollection["mario_run3"].image,    ],    spriteCollection["mario_idle"].image,    spriteCollection["mario_jump"].image,)bigAnimation = Animation(    [        spriteCollection["mario_big_run1"].image,        spriteCollection["mario_big_run2"].image,        spriteCollection["mario_big_run3"].image,    ],    spriteCollection["mario_big_idle"].image,    spriteCollection["mario_big_jump"].image,)class Mario(EntityBase):    def __init__(self, x, y, level, screen, dashboard, sound, gravity=0.8):        super(Mario, self).__init__(x, y, gravity)        self.camera = Camera(self.rect, self)        self.sound = sound        self.input = Input(self)        self.inAir = False        self.inJump = False        self.powerUpState = 0        self.invincibilityFrames = 0        self.traits = {            "jumpTrait": JumpTrait(self),            "goTrait": GoTrait(smallAnimation, screen, self.camera, self),            "bounceTrait": bounceTrait(self),        }        self.levelObj = level        self.collision = Collider(self, level)        self.screen = screen        self.EntityCollider = EntityCollider(self)        self.dashboard = dashboard        self.restart = False        self.pause = False        self.pauseObj = Pause(screen, self, dashboard)    def update(self):        if self.invincibilityFrames > 0:            self.invincibilityFrames -= 1        self.updateTraits()        self.moveMario()        self.camera.move()        self.applyGravity()        self.checkEntityCollision()        self.input.checkForInput()    def moveMario(self):        self.rect.y += self.vel.y        self.collision.checkY()        self.rect.x += self.vel.x        self.collision.checkX()    def checkEntityCollision(self):        for ent in self.levelObj.entityList:            collisionState = self.EntityCollider.check(ent)            if collisionState.isColliding:                if ent.type == "Item":                    self._onCollisionWithItem(ent)                elif ent.type == "Block":                    self._onCollisionWithBlock(ent)                elif ent.type == "Mob":                    self._onCollisionWithMob(ent, collisionState)    def _onCollisionWithItem(self, item):        self.levelObj.entityList.remove(item)        self.dashboard.points += 100        self.dashboard.coins += 1        self.sound.play_sfx(self.sound.coin)    def _onCollisionWithBlock(self, block):        if not block.triggered:            self.dashboard.coins += 1            self.sound.play_sfx(self.sound.bump)        block.triggered = True    def _onCollisionWithMob(self, mob, collisionState):        if isinstance(mob, RedMushroom) and mob.alive:            self.powerup(1)            self.killEntity(mob)            self.sound.play_sfx(self.sound.powerup)        elif collisionState.isTop and (mob.alive or mob.bouncing):            self.sound.play_sfx(self.sound.stomp)            self.rect.bottom = mob.rect.top            self.bounce()            self.killEntity(mob)        elif collisionState.isTop and mob.alive and not mob.active:            self.sound.play_sfx(self.sound.stomp)            self.rect.bottom = mob.rect.top            mob.timer = 0            self.bounce()            mob.alive = False        elif collisionState.isColliding and mob.alive and not mob.active and not mob.bouncing:            mob.bouncing = True            if mob.rect.x < self.rect.x:                mob.leftrightTrait.direction = -1                mob.rect.x += -5                self.sound.play_sfx(self.sound.kick)            else:                mob.rect.x += 5                mob.leftrightTrait.direction = 1                self.sound.play_sfx(self.sound.kick)        elif collisionState.isColliding and mob.alive and not self.invincibilityFrames:            if self.powerUpState == 0:                self.gameOver()            elif self.powerUpState == 1:                self.powerUpState = 0                self.traits['goTrait'].updateAnimation(smallAnimation)                x, y = self.rect.x, self.rect.y                self.rect = pygame.Rect(x, y + 32, 32, 32)                self.invincibilityFrames = 60                self.sound.play_sfx(self.sound.pipe)    def bounce(self):        self.traits["bounceTrait"].jump = True    def killEntity(self, ent):        if ent.__class__.__name__ != "Koopa":            ent.alive = False        else:            ent.timer = 0            ent.leftrightTrait.speed = 1            ent.alive = True            ent.active = False            ent.bouncing = False        self.dashboard.points += 100    def gameOver(self):        srf = pygame.Surface((640, 480))        srf.set_colorkey((255, 255, 255), pygame.RLEACCEL)        srf.set_alpha(128)        self.sound.music_channel.stop()        self.sound.music_channel.play(self.sound.death)        for i in range(500, 20, -2):            srf.fill((0, 0, 0))            pygame.draw.circle(                srf,                (255, 255, 255),                (int(self.camera.x + self.rect.x) + 16, self.rect.y + 16),                i,            )            self.screen.blit(srf, (0, 0))            pygame.display.update()            self.input.checkForInput()        while self.sound.music_channel.get_busy():            pygame.display.update()            self.input.checkForInput()        self.restart = True    def getPos(self):        return self.camera.x + self.rect.x, self.rect.y    def setPos(self, x, y):        self.rect.x = x        self.rect.y = y            def powerup(self, powerupID):        if self.powerUpState == 0:            if powerupID == 1:                self.powerUpState = 1                self.traits['goTrait'].updateAnimation(bigAnimation)                self.rect = pygame.Rect(self.rect.x, self.rect.y-32, 32, 64)                self.invincibilityFrames = 20


绘制土坯,金币盒子,动物,乌龟等的文件:

class CoinBox(EntityBase):    def __init__(self, screen, spriteCollection, x, y, sound, dashboard, gravity=0):        super(CoinBox, self).__init__(x, y, gravity)        self.screen = screen        self.spriteCollection = spriteCollection        self.animation = copy(self.spriteCollection.get("CoinBox").animation)        self.type = "Block"        self.triggered = False        self.time = 0        self.maxTime = 10        self.sound = sound        self.dashboard = dashboard        self.vel = 1        self.item = Item(spriteCollection, screen, self.rect.x, self.rect.y)    def update(self, cam):        if self.alive and not self.triggered:            self.animation.update()        else:            self.animation.image = self.spriteCollection.get("empty").image            self.item.spawnCoin(cam, self.sound, self.dashboard)            if self.time < self.maxTime:                self.time += 1                self.rect.y -= self.vel            else:                if self.time < self.maxTime * 2:                    self.time += 1                    self.rect.y += self.vel        self.screen.blit(            self.spriteCollection.get("sky").image,            (self.rect.x + cam.x, self.rect.y + 2),        )        self.screen.blit(self.animation.image, (self.rect.x + cam.x, self.rect.y - 1))

直接运行main.py文件就可以进入游戏了:

windowSize = 640, 480def main():    pygame.mixer.pre_init(44100, -16, 2, 4096)    pygame.init()    screen = pygame.display.set_mode(windowSize)    max_frame_rate = 60    dashboard = Dashboard("./img/font.png", 8, screen)    sound = Sound()    level = Level(screen, sound, dashboard)    menu = Menu(screen, dashboard, level, sound)    while not menu.start:        menu.update()    mario = Mario(0, 0, level, screen, dashboard, sound)    clock = pygame.time.Clock()    while not mario.restart:        pygame.display.set_caption("Super Mario running with {:d} FPS".format(int(clock.get_fps())))        if mario.pause:            mario.pauseObj.update()        else:            level.drawLevel(mario.camera)            dashboard.update()            mario.update()        pygame.display.update()        clock.tick(max_frame_rate)    return 'restart'if __name__ == "__main__":    exitmessage = 'restart'    while exitmessage == 'restart':        exitmessage = main()

需要游戏素材,和完整代码,可以扫码加我薇获取,包括Python学习资料以及更多好玩的Python代码分享:

 Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

图片​​​​​​

视频教程

大信息时代,传统媒体远不如视频教程那么生动活泼,一份零基础到精通的全流程视频教程分享给大家

图片​​​​​​

实战项目案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

图片​​​​​​

图片​​​​​​

副业兼职路线

​​​​​​

今天的分享就到这里,希望感兴趣的同学关注我,每天都有新内容,不限题材,不限内容,你有想要分享的内容,也可以私聊我!

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值