【Pygame】细致讲解开发Flappy Bird小游戏

这篇具有很好参考价值的文章主要介绍了【Pygame】细致讲解开发Flappy Bird小游戏。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

加载素材(图片、音效)

方式1:

# 加载图片

Picture = pygame.image.load(“picture.png”)

# 加载音乐

Sound = pygame.mixer.Sound(sound.wav)

调用sound.play()即可播放音效。

方式2:

利用python的字典查找图片。

通过python的内置模块os(operatingsystem) 来提供一些和操作系统有关的用法,使用os.listdir方法列出文件夹中的所有文件,利用os.splitext 分割文件名和后缀。 文件名+后缀(“小鸟”+”.png”),利用os.path.join拼接文件路径,最后利用pygame装载图片。

每个图片的文件名都是字典中用来查找的键,而值则是pygame加载好的图片。

# Materials 加载素材
IMAGES = {}
for image in os.listdir('assets/sprites'):
    name, extension = os.path.splitext(image)
    path = os.path.join('assets/sprites',image)
    IMAGES[name] = pygame.image.load(path)

AUDIO = {}
for audio in os.listdir('assets/audio'):
    name, extension = os.path.splitext(audio)
    path = os.path.join('assets/audio',audio)
    AUDIO[name] = pygame.mixer.Sound(path)

图片绘制

1.背景图

因为设置的窗口大小和背景图的大小是一致的,所以背景图直接绘制在原点即可。

地板和开始菜单信息图的画面定位绘制。

2.地板

地板的x坐标肯定是0,从最左边画到最右边,地板的y坐标floor_y是屏幕的高减去地板自身的高度:H-floor.get_height()。

注:自身的高可以使用图片的get_height方法获得。

3.开始菜单的信息图

因为pygame中坐标系左上角为(0,0),X即为屏幕的宽减去图片自身的宽,再除以2,Y方向 考虑到应放在地板和天花板的中间,应当用地板所在的y减去游戏说明的高,然后再除以2即可得到。

【Pygame】细致讲解开发Flappy Bird小游戏

主界面开场画面的设计

怎么动起来?

1.地板的运动(向左移动)

首先计算游戏地板图片的宽和游戏背景图片的宽两者之差,设置地板的x坐标为0。

到循环中,帧与帧之间每次都让地板的x-4,意思是往左移动4个像素。当地板溢出画面时,让地板的x重置为0即可。

# 地板运动
        floor_x -= 4
        if floor_x <= - floor_gap:
            floor_x = 0
  1. 小鸟的上下漂浮动画

bird_y_vel = 1
    bird_y_range = [bird_y - 8,bird_y +8]
    idx = 0       # 序号
    repeat = 5
    frmes = [0] * repeat + [1] * repeat + [2] * repeat + [1] * repeat

首先小鸟在y方向上要有一个速度,代表帧与帧之间小鸟上下移动一个像素,然后设置小鸟的移动范围bird_y_range。初始位置上下8个像素。

在循环中每次根据小鸟的速度改变小鸟的位置坐标,一旦小鸟超出了设定的移动范围,就把速度方向反向。

# 小鸟漂浮
        bird_y += bird_y_vel
        if bird_y < bird_y_range[0] or bird_y > bird_y_range[1]:
            bird_y_vel *= -

3.小鸟拍动翅膀的动画

我们之前已经将小鸟状态的每一帧都存在了图片列表中,所以我们想要取得小鸟的帧造型,只需要IMAGES[‘birds’] 和对应的帧序号即可。

在循环中帧与帧之间,idx序号+1,但是序号不能无限增加,如果超过了总帧数,就得重新回到0,这里我使用了一个取余,可以巧妙的节约一个if语句。

# 小鸟拍动翅膀
        idx += 1
        idx %= len(frmes)

为什么0,1,2 后面还有一个1呢?为什么要重复5遍呢?

因为一个完整的拍动翅膀的周期就是上中下中上中下中…..我们游戏的fps帧数设置为每秒钟30帧,意味着每秒钟就要画30副游戏画面,但是小鸟的帧造型不能每一个画面都得切换,不然切换的太快,小鸟就会变得很鬼畜,而每5帧左右切换一个造型看起来比较自然。当然如果你想要一只非常“亢奋”的小鸟,那就另当别论了。

主角登场!

每轮游戏我们都会随机生成一个小鸟的颜色、随机天气、随机水管的颜色。

通过random模块随机选择黑夜和白天的背景图,很简单通过随机的结果作为新的键bgpic的值。

小鸟的这边会稍微复杂一点,我们首先先随机一个颜色。小鸟有三种帧造型,分别是翅膀向上,向中和向下。我们可以通过字符串的拼接放到一个列表里。

水管也是同样的操作,但是我们选定一根水管之后会有一根相反的水管造型和它对应,我们可以通过pygame.transform.flip()方法即可搞定。

        IMAGES['bgpic'] = IMAGES[random.choice(['day', 'night'])]      # 随机天气
        color = random.choice(['red', 'yellow', 'blue'])               # 随机小鸟的颜色
        IMAGES['birds'] = [IMAGES[color+'-up'],IMAGES[color+'-mid'],IMAGES[color+'-down']]
        pipe = IMAGES[random.choice(['green-pipe', 'red-pipe'])]
        IMAGES['pipes'] = [pipe, pygame.transform.flip(pipe,False,True)]

小鸟飞高

怎么通过按下空格让小鸟飞起来?

我们知道在pygame的世界的向上运动,对应的y坐标就要不断减少,因此我们要定义小鸟在y方向的速度为-10,y方向的最大速度10,和重力加速度1。

在更新方法中:首先要更新y速度,加载重力加速度。同时要考虑速度不会超过最大速度。

所以小鸟所在矩形的y坐标的每次变化量就是小鸟的y速度。

做个简单数学计算:第一帧数小鸟的速度更新为-9,小鸟向上移动9个像素,第二帧速度为-8,小鸟向上移动8个像素,以此类推,直到y方向速度变为0,小鸟飞到最高点,接着y方向速度开始向下不断增大,小鸟开始向下掉落。

细节决定成败:飞起来时候小鸟角度的变化

【Pygame】细致讲解开发Flappy Bird小游戏

我们通过初始化小鸟的旋转角度初始是45度斜向上,定义帧与帧之间不断减小3度,与更新小鸟上下移动类似,完成小鸟飞行角度的变化。

小鸟拍动翅膀飞起来

我们定义小鸟拍动翅膀后的y速度和角度,在更新方法中,通过如果拍动了翅膀,即给了小鸟能量,无论小鸟此刻状态下的y速度和角度是多少,都重置为初始的值。在循环中,设置flap = False,默认没有拍动翅膀,接着可以处理键盘事件,按下空格,让flap的值变为true,并且发出拍动翅膀的声音,最后调用更新方法传入flag参数即可。

水管登场!

我们可以使用pygame的精灵组定义水管类,继承精灵类,并且调用父类的init方法。

要注意的是水管永远是成对出现的,在定义初始化属性的时候要对上下两根水管做不同的定义。

水管的运动原理等同于地板的运动:

一旦水管移除屏幕的左边,消灭这些水管,生成新的水管,这样水管与水管之间相互独立。

每次取出排在第一位的水管,也就是最左边的水管,判断水管最右端的x坐标是否小于0,如果他小于0,代表整个水管移除了屏幕的左边,那么就新添加一根水管,新水管的x坐标为第一根水管的x坐标 + 水管数量*水管之间的距离。

游戏的输赢判断

碰到天花板、地板、水管都代表游戏结束。

碰撞检测:首先碰到天花板和地板比较简单,只需要判断bird矩形的y坐标是否大于FLOOR_Y 或者小于0即可。

关于小鸟与水管的碰撞检测:

我们可以通过以下两幅图来理解:

【Pygame】细致讲解开发Flappy Bird小游戏

如果我们把上面这几种情况全部写成if else 条件判断,那么将会很麻烦。我们不妨换一个物理思维的角度,如果两个矩形碰撞,意味着两个矩形之间一定会有重合的面积,有重合的面积就一定会有重叠的宽和高,如果这样想,逻辑判断的部分就会简单许多,我们可以计算两个矩形所构成的整体,用最右端的x坐标减去最左端的x坐标,看看差值是不是比两个矩形各自的宽之和要小,如果小,说明宽的部分有重叠,同理,计算两个矩形所在整体最上方的y减去最下端的y,是不是比两个矩形各自的高之和要小。宽和高都有重叠,就说明两者碰撞了。

分数检测:

【Pygame】细致讲解开发Flappy Bird小游戏

结局画面定格:在游戏界面和结束界面传递信息。

使用一个result结果字典,存放游戏结束时需要从游戏场景传递到结束场景的数据信息(例如死亡的小鸟,游戏分数,游戏时间等等),在结束窗口中我们取出这些信息画到屏幕上即可。

为了追求细节,我们可以在小鸟的类中定义一个死亡的方法,让小鸟不论是碰到了天花板还是碰到了水管死亡之后都会掉落到地板上。让这个方法在结束场景中调用即可。

实现这个方法也非常的简单,判断此刻小鸟是不是还在地板之上,如果是的话,就以垂直于地面的角度和最大的速度往下掉即可。

源代码

import random
import os
import pygame

# Constants 常量
W ,H = 288,512           # W宽 H高
FPS = 30                 # 每秒的帧速率

# Setup 设置
pygame.init()
SCREEN = pygame.display.set_mode((W,H))
pygame.display.set_caption('Flappy Bird')
CLOCK = pygame.time.Clock()


# Materials 加载素材
IMAGES = {}
for image in os.listdir('assets/sprites'):
    name, extension = os.path.splitext(image)
    path = os.path.join('assets/sprites',image)
    IMAGES[name] = pygame.image.load(path)

AUDIO = {}
for audio in os.listdir('assets/audio'):
    name, extension = os.path.splitext(audio)
    path = os.path.join('assets/audio',audio)
    AUDIO[name] = pygame.mixer.Sound(path)




FLOOR_Y = H - IMAGES['floor'].get_height()

def main():
    while True:
        AUDIO['start'].play()
        IMAGES['bgpic'] = IMAGES[random.choice(['day', 'night'])]      # 随机天气
        color = random.choice(['red', 'yellow', 'blue'])               # 随机小鸟的颜色
        IMAGES['birds'] = [IMAGES[color+'-up'],IMAGES[color+'-mid'],IMAGES[color+'-down']]
        pipe = IMAGES[random.choice(['green-pipe', 'red-pipe'])]
        IMAGES['pipes'] = [pipe, pygame.transform.flip(pipe,False,True)]
        # 三个界面依次跳转
        menu_window()             # 菜单
        result = game_window()    # 游戏
        end_window(result)        # 结尾


# 主界面
def menu_window():

    floor_gap = IMAGES['floor'].get_width() - W
    floor_x = 0

    guide_x = (W - IMAGES['guide'].get_width())/2
    guide_y = (FLOOR_Y - IMAGES['guide'].get_height())/2
    bird_x = W * 0.2
    bird_y = (H - IMAGES['birds'][0].get_height())/2

    bird_y_vel = 1
    bird_y_range = [bird_y - 8,bird_y +8]
    idx = 0       # 序号
    repeat = 5
    frmes = [0] * repeat + [1] * repeat + [2] * repeat + [1] * repeat
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()
            if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                return
        # 地板运动
        floor_x -= 4
        if floor_x <= - floor_gap:
            floor_x = 0
        # 小鸟漂浮
        bird_y += bird_y_vel
        if bird_y < bird_y_range[0] or bird_y > bird_y_range[1]:
            bird_y_vel *= -1
        # 小鸟拍动翅膀
        idx += 1
        idx %= len(frmes)


        SCREEN.blit(IMAGES['bgpic'], (0, 0))
        SCREEN.blit(IMAGES['floor'], (floor_x, FLOOR_Y))
        SCREEN.blit(IMAGES['guide'], (guide_x, guide_y))
        SCREEN.blit(IMAGES['birds'][frmes[idx]], (bird_x, bird_y))
        pygame.display.update()
        CLOCK.tick(FPS)



def game_window():

    score = 0
    AUDIO['flap'].play()   # 一进入游戏界面就播放音效
    floor_gap = IMAGES['floor'].get_width() - W
    floor_x = 0
    bird = Bird(W * 0.2, H * 0.4)    # 生成小鸟对象
    pipe_group = pygame.sprite.Group()
    n_pairs = 5                            # 水管的数量
    distance = random.randint(150,200)     # 水管之间的距离
    pipe_gap = random.randint(80,100)    # 上下两个水管间的距离

    for i in range(n_pairs):
        pipe_y = random.randint(int(H*0.3),int(H*0.7))
        pipe_up = Pipe(W + i * distance,pipe_y,True)
        pipe_down = Pipe(W + i * distance, pipe_y - pipe_gap, False)
        pipe_group.add(pipe_up)
        pipe_group.add(pipe_down)

    while True:
        flap = False
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    flap = True
                    AUDIO['flap'].play()
        floor_x -= 4
        if floor_x <= - floor_gap:
            floor_x = 0

        bird.update(flap)

        first_pipe_up = pipe_group.sprites()[0]
        first_pipe_down = pipe_group.sprites()[1]
        if first_pipe_up.rect.right < 0:
            pipe_y = random.randint(int(H * 0.3), int(H * 0.7))   # 随机水管的y坐标,范围自拟
            new_pipe_up = Pipe(first_pipe_up.rect.x + n_pairs * distance, pipe_y,True)
            new_pipe_down = Pipe(first_pipe_down.rect.x + n_pairs * distance, pipe_y - pipe_gap,False)
            pipe_group.add(new_pipe_up)
            pipe_group.add(new_pipe_down)
            first_pipe_up.kill()
            first_pipe_down.kill()
        pipe_group.update()

        if bird.rect.y > FLOOR_Y or bird.rect.y < 0 or pygame.sprite.spritecollideany(bird,pipe_group):
            bird.dying = True
            AUDIO['hit'].play()
            AUDIO['die'].play()
            result = {'bird': bird,'pipe_group':pipe_group, 'score':score}
            return result

        # 碰撞检测
        # for pipe in pipe_group.sprites():
        #     # 不确定哪个矩形代表水管和小鸟,用max方法取得整体的最右端和最左端
        #     rigth_to_left = max(bird.rect.right, pipe.rect.right) - min(bird.rect.left, pipe.rect.left)
        #     bottom_to_top = max(bird.rect.bottom, pipe.rect.bottom) - min(bird.rect.top, pipe.rect.top)
        #     if rigth_to_left < bird.rect.width + pipe.rect.width and bottom_to_top < bird.rect.height + pipe.rect.height:
        #         AUDIO['hit'].play()
        #         AUDIO['die'].play()
        #         result = {'bird': bird,'pipe_group':pipe_group, 'score':score}
        #         return result

        # 分数
        #                 前                                中心线                     后
        if bird.rect.left + first_pipe_up.x_vel < first_pipe_up.rect.centerx < bird.rect.left:
            AUDIO['score'].play()
            score += 1


        SCREEN.blit(IMAGES['bgpic'], (0, 0))
        pipe_group.draw(SCREEN)
        SCREEN.blit(IMAGES['floor'], (floor_x, FLOOR_Y))
        Show_score(score)
        SCREEN.blit(bird.image,bird.rect)   # 在画图中把对应的帧皮肤和矩形传入
        pygame.display.update()
        CLOCK.tick(FPS)



def end_window(result):
    gameover_x = (W - IMAGES['gameover'].get_width())/2
    gameover_y = (FLOOR_Y - IMAGES['gameover'].get_height())/2

    bird = result['bird']
    pipe_group = result['pipe_group']
    while True:

        if bird.dying:
            bird.go_die()
        else:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    quit()
                if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                    return
        bird.go_die()
        SCREEN.blit(IMAGES['bgpic'], (0, 0))
        pipe_group.draw(SCREEN)
        SCREEN.blit(IMAGES['floor'], (0, FLOOR_Y))
        SCREEN.blit(IMAGES['gameover'], (gameover_x, gameover_y))
        Show_score(result['score'])
        SCREEN.blit(bird.image,bird.rect)
        pygame.display.update()
        CLOCK.tick(FPS)


# 定义显示分数的函数
def Show_score(score):
    score_str = str(score)
    n = len(score_str)
    w = IMAGES['0'].get_width() * 1.1    # 计算每个数字的宽度,*1.1 让每个数字之间有所间隔
    x = (W - n * w) / 2
    y = H * 0.1
    for number in score_str:
        SCREEN.blit(IMAGES[number], (x, y))
        x += w


# 小鸟类
class Bird:
    def __init__(self,x,y):
        self.frames = [0] * 5 + [1] * 5 + [2] * 5 + [1] * 5    # 帧序号列表
        self.idx = 0  # 帧序号
        self.images = IMAGES['birds']      # 所有的帧造型
        self.image = self.images[self.frames[self.idx]]
        self.rect = self.image.get_rect()  # 帧所在的矩形
        self.rect.x = x
        self.rect.y = y
        self.y_vel = -10      # 小鸟的y方向速度
        self.max_y_vel = 10   # y方向上的最大速度10
        self.gravity = 1      # 重力加速度1
        self.rotate = 45      # 旋转角度初始45度斜向上
        self.max_rotate = -20
        self.rotate_vel = -3  # 帧与帧之间角度不断减小三度
        self.y_vel_after_flap = -10  # 拍动翅膀后的y速度,也就是初始的y速度
        self.rotate_after_flap = 45  # 拍动翅膀后的角度
        self.dying = False

    # 定义帧与帧之间的更新方法
    def update(self,flap = False):
        self.idx += 1
        self.idx %= len(self.frames)
        self.image = self.images[self.frames[self.idx]]   # 切换帧造型
        # 上下移动
        self.y_vel = min(self.y_vel + self.gravity, self.max_y_vel)
        self.rect.y += self.y_vel
        # 倾斜移动
        self.rotate = max(self.rotate + self.rotate_vel,self.max_rotate)
        self.image = pygame.transform.rotate(self.image,self.rotate)

        # 如果拍动了翅膀,即给了小鸟能量,无论小鸟此时的速度和角度是多少,都重置为初始值
        if flap:
            self.y_vel = self.y_vel_after_flap
            self.rotate = self.rotate_after_flap


    def go_die(self):
        if self.rect.y < FLOOR_Y:
            self.rect.y += self.max_y_vel
            self.rotate = -90
            self.image = self.images[self.frames[self.idx]]
            self.image = pygame.transform.rotate(self.image,self.rotate)
        else:
            self.dying = False

# 水管类
class Pipe(pygame.sprite.Sprite):
    def __init__(self,x,y,upwards=True):    # 默认是向上的水管
        pygame.sprite.Sprite.__init__(self)
        if upwards:
            self.image = IMAGES['pipes'][0]
            self.rect = self.image.get_rect()  # 获得水管所在的矩形
            self.rect.x = x   # 根据传入的x更新矩形的位置
            self.rect.top = y
        else:
            self.image = IMAGES['pipes'][1]
            self.rect = self.image.get_rect()
            self.rect.x = x
            self.rect.bottom = y
        self.x_vel = -4          # 水管跟地面一样,需要向左移动,设置x方向的速度为-4

    def update(self):
        self.rect.x += self.x_vel      # 根据速度更新坐标

if __name__ == '__main__':
    main()

项目压缩包

链接:https://pan.baidu.com/s/1v_dGetGRDhNOMWn96w97ew

提取码:oesi文章来源地址https://www.toymoban.com/news/detail-412540.html

到了这里,关于【Pygame】细致讲解开发Flappy Bird小游戏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 小游戏实战丨基于PyGame的贪吃蛇小游戏

    本期内容:基于pygame的贪吃蛇小游戏 下载地址:https://download.csdn.net/download/m0_68111267/88700188 实验环境 python3.11及以上 pycharm pygame 安装pygame的命令: pygame是一个开源的Python模块,专门用于编写电子游戏。它使用简单、功能强大,因此非常适合初学者入门。pygame的主要特点包括图

    2024年02月03日
    浏览(62)
  • pygame自制小游戏

    pygame——游戏视频 简单的来写一个pygame小游戏,我的画面比较卡哇伊各位可以自己换图片哈。 就是一个最基本的pygame小游戏,可以控制人物,攻击敌人,打到敌人使敌人消失,如果敌人到达边缘仍然没有被消灭,游戏就会失败。 1.鼠标移动人物跟随移动,播放背景音乐,可以摁下

    2024年02月11日
    浏览(47)
  • pygame飞机大战小游戏(python大作业)

      python大作业,在查看了老师给的链接发现教学视频不完整,所以借用了同学的《Python编程 从入门到实践》中的一个项目,学习模仿。 二、游戏具体介绍 这是一款由辉辉亲自打造的太空对战小游戏。 游戏背景:在广袤无垠的太空里有一群蓝精灵(不是)有一群邪恶的坏人,

    2024年02月11日
    浏览(58)
  • 使用Python+pygame实现贪吃蛇小游戏

    使用第三方库pygame,关于Python中pygame游戏模块的安装使用可见 https://blog.csdn.net/cnds123/article/details/119514520 给出两种实现。 第一种 运行效果如下: 游戏源码如下: 第二种 就不给出运行效果图了,你可以运行看看。 下面给出另一种实现源码: OK! 

    2024年01月16日
    浏览(79)
  • 【python】 pygame学习示例 --飞机大战小游戏制作

    python版本:3.8.5 所需模块:pygame random os pygame版本:20.1 开发环境:pycharm专业版 硬件环境:win11 8G内存以上 使用python的第三方库–pygame 制作飞机大战小游戏 小游戏的内容包括: 玩家player的移动 子弹的发射 陨石的随机掉落(包括旋转 大小 下落角度) 玩家 子弹 陨石的碰撞交互

    2024年02月04日
    浏览(54)
  • Python版基于pygame的玛丽快跑小游戏源代码,玛丽冒险小游戏代码,支持双人模式

    基于pygame的玛丽快跑小游戏源代码,玛丽冒险小游戏代码,支持双人模式 按空格进入单人模式,按‘t’进入双人模式,双人模式下玛丽1采用空格键上跳,玛丽2采用方向上键上跳。 完整代码下载地址:Python版基于pygame的玛丽快跑小游戏源代码 完整代码下载地址:Python版基于

    2024年02月11日
    浏览(63)
  • 【python大作业】pygame实战(python编写2048小游戏)

    本文介绍基于pygame编写的2048小游戏程序 包含四个文件 运行效果: 点击此处下载完整程序,下载即可运行 其中config.py用于设置游戏参数 包括游戏窗口大小,刷新率,方块颜色等 game.py中定义了游戏实现的函数,设置方块的产生,移动与计算,并判断游戏进行的程度,判断游

    2024年02月13日
    浏览(63)
  • pygame超详细教程!!做python小游戏必看框架!

    # 导入需要的模块 # 定义一个游戏管理总类 # 定义一个check_event 方法用于阻塞事件,并在检测到\\\"QUIT\\\"事件时关闭窗口 # run 方法则是游戏的主循环,不断调用 check_event 方法, 加上flip()  , 每次添加新功能,即可更新画布 # 调用gm实例 到这里,我们就能做出一个空白的黑窗体了,

    2024年02月07日
    浏览(47)
  • 用Python编写的超级马里奥小游戏(基于Pygame)

    在本文中,我将向您展示如何使用Python编写一个简单的超级马里奥小游戏,使用Pygame库来处理游戏的图形和输入。 首先,我们需要确保已安装Pygame库。您可以使用以下命令在终端或命令提示符中安装Pygame: 一旦安装完成,我们就可以开始编写代码了。下面是完整的Python代码

    2024年01月16日
    浏览(49)
  • 基于Python+Pygame实现一个俄罗斯方块小游戏【完整代码】

    俄罗斯方块,一款起源于上世纪80年代的经典电子游戏,凭借简单的规则和独特的魅力,一跃成为全球家喻户晓的经典。你知道其实只需要一些基础的编程知识,就可以自己实现它吗?今天,我们将使用Python的Pygame库,一步步带你构建属于自己的俄罗斯方块小游戏! 游戏初始

    2024年02月04日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包