为了练习自己的Python基础语法,我用pygame写了一个打砖块闯关的游戏

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 这里的BOSS战是我自己想的,打不动的砖块实在是没有什么意思,于是这个版本我更新了两场BOSS战,我们终于可以打BOSS(其实目前只是会动的大砖块)了。我打算实现道具,并为第一个BOSS加上技能,同时为游戏添加BGM,最后为了给我其他没学过Python的同学测评,我将其编译成了。那是一个百无聊赖的夜晚,我回顾了自己自大学以来的经历,感觉生活十分平淡,学习了许多计算机知识,但是似乎什么东西都没有用上。游戏诞生的喜悦,使我改变了最开始只是简单复现的计划,我打算写进去更多的东西,更完整地复现功能,最好还能有点。
✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。
🍎个人主页: 小嗷犬的博客
🍊个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。
🥭本文内容:为了练习自己的Python基础语法,我用pygame写了一个打砖块闯关的游戏

1.事件之始

那是一个百无聊赖的夜晚,我回顾了自己自大学以来的经历,感觉生活十分平淡,学习了许多计算机知识,但是似乎什么东西都没有用上。

考虑到我的Python有些生疏了,我便计划练习一下Python,我像往常一样点开网课,带上耳机,准备慢慢地听。

只听了3分钟,我便没了耐心,听谁还不会啊,关键还是要写,为了缓解大学以来的无味,也为了练习Python,我决定写点有趣的东西。

pip install pygame
于是我在命令行里输入了上面的代码。

我的第一个游戏应允而生。


2.萌新复现经典游戏打砖块

最开始,我本来只是想简单复现一下经典游戏,我学习了一下 pygame的基本用法,就开始动手了。

在我一段时间的埋头苦写之下,一个大概150行代码的小游戏就诞生了:

'''
Time    : 2022-4-18
Author  : Marquis
FileName: Dog打砖块1.0.py
Software: VScode
'''

import pygame
import sys
import pygame.freetype
import os
import random
# 初始化
os.chdir(os.path.dirname(sys.argv[0]))
pygame.init()
pygame.display.set_icon(pygame.image.load(r".\img\dog50x.jpg"))
size = width, height = 1500, 700
speed = [2, -2]
Black = 0, 0, 0
Red = 255, 0, 0
White = 255, 255, 255
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Dog Ball2")
ball = pygame.image.load("./img/dog50x.jpg")
board = pygame.image.load("./img/board160x20.png")
ballrect = ball.get_rect()
boardrect = board.get_rect()
f1 = pygame.freetype.Font("C:/Windows/Fonts/msyh.ttc", 36)
fps = 160
fclock = pygame.time.Clock()
pause = 1
flag = 0
boardrect = boardrect.move(0, 600)
ballrect = ballrect.move(700, 450)
brick_list = []
brick_color = []
for i in range(0, 20):
    for j in range(0, 10):
        # 随机生成砖块(可调节概率)
        if random.randint(0, 3) == 1:
            brick_list.append(pygame.Rect(i*75, j*30, 75, 30))
            brick_color.append((random.randint(100, 200), random.randint(
                100, 200), random.randint(100, 200)))
beginsurf, beginrect = f1.render("<按下空格键开始游戏>", fgcolor=White, size=60)
screen.blit(beginsurf, (450, 300))
pygame.display.update()

# 游戏主体
while True:
    # 运行循环
    while not pause:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            # 挡板跟随鼠标移动
            elif event.type == pygame.MOUSEMOTION:
                boardrect = boardrect.move(
                    event.pos[0]-(boardrect.left+boardrect.right)/2, 0)
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    sys.exit()
                # 5档变速
                elif event.key == pygame.K_1:
                    speed[0], speed[1] = speed[0] / \
                        abs(speed[0])*1, speed[1]/abs(speed[1])*1
                elif event.key == pygame.K_2:
                    speed[0], speed[1] = speed[0] / \
                        abs(speed[0])*2, speed[1]/abs(speed[1])*2
                elif event.key == pygame.K_3:
                    speed[0], speed[1] = speed[0] / \
                        abs(speed[0])*3, speed[1]/abs(speed[1])*3
                elif event.key == pygame.K_4:
                    speed[0], speed[1] = speed[0] / \
                        abs(speed[0])*4, speed[1]/abs(speed[1])*4
                elif event.key == pygame.K_5:
                    speed[0], speed[1] = speed[0] / \
                        abs(speed[0])*5, speed[1]/abs(speed[1])*5
                elif event.key == pygame.K_SPACE:
                    pause = 1

        # 球的移动
        ballrect = ballrect.move(speed[0], speed[1])
        # 球与板的撞击判断
        if ballrect.colliderect(boardrect):
            if ballrect.top <= boardrect.bottom and ballrect.bottom > boardrect.bottom and speed[1] < 0:
                speed[1] = -speed[1]
            elif ballrect.bottom >= boardrect.top and ballrect.top < boardrect.top and speed[1] > 0:
                speed[1] = -speed[1]
            elif ballrect.left <= boardrect.right and ballrect.right > boardrect.right and speed[0] < 0:
                speed[0] = -speed[0]
            elif ballrect.right >= boardrect.left and ballrect.left < boardrect.right and speed[0] > 0:
                speed[0] = -speed[0]
        # 球与边界的撞击判断
        if (ballrect.left < 0 and speed[0] < 0) or (ballrect.right > width and speed[0] > 0):
            speed[0] = -speed[0]
        if ballrect.top < 0 and speed[1] < 0:
            speed[1] = -speed[1]
        for brick in brick_list:
            if ballrect.colliderect(brick):
                if ballrect.left <= brick.right and ballrect.right > brick.right and speed[0] < 0:
                    speed[0] = -speed[0]
                elif ballrect.right >= brick.left and ballrect.left < brick.left and speed[0] > 0:
                    speed[0] = -speed[0]
                elif ballrect.top <= brick.bottom and ballrect.bottom > brick.bottom and speed[1] < 0:
                    speed[1] = -speed[1]
                elif ballrect.bottom >= brick.top and ballrect.top < brick.top and speed[1] > 0:
                    speed[1] = -speed[1]
                brick_color.pop(brick_list.index(brick))
                brick_list.pop(brick_list.index(brick))
                break

        # 屏幕的更新
        screen.fill(Black)
        # 小提示
        tip1surf, tip1rect = f1.render("<按空格键暂停游戏>", fgcolor=White, size=20)
        tip2surf, tip2rect = f1.render("<按ESC键退出游戏>", fgcolor=White, size=20)
        tip3surf, tip3rect = f1.render(
            "<按数字键1-5调速(默认为2)>", fgcolor=White, size=20)
        screen.blit(tip1surf, (0, 640))
        screen.blit(tip2surf, (0, 660))
        screen.blit(tip3surf, (0, 680))
        # 砖、球、板的绘制
        for brick in brick_list:
            pygame.draw.rect(
                screen, brick_color[brick_list.index(brick)], brick)
        screen.blit(ball, ballrect)
        screen.blit(board, boardrect)
        # 游戏结束的判断
        if ballrect.bottom > height:
            f1surf, f1rect = f1.render("GAME OVER", fgcolor=Red, size=100)
            screen.blit(f1surf, (450, 300))
            flag = 1
            pause = 1
        if not brick_list:
            f1surf, f1rect = f1.render("YOU WIN", fgcolor=Red, size=100)
            screen.blit(f1surf, (500, 300))
            flag = 1
            pause = 1
        pygame.display.update()
        fclock.tick(fps)
    # 暂停循环
    while pause:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    sys.exit()
                elif event.key == pygame.K_SPACE:
                    if not flag:
                        pause = 0
并为其命名 Dog打砖块1.0

当时游戏十分简陋,没有BGM,也没有什么游戏性;从代码上来说,当时没有学习类与对象,对pygame的熟悉程度也不足,有很多现成方法没有使用。

但是当时我是很高兴的,毕竟游戏可以运行了嘛。

让我们看看当时我的试玩视频:

[video(video-RNV6NRBq-1662467256647)(type-bilibili)(url-https://player.bilibili.com/player.html?aid=980874119)(image-https://ucc.alicdn.com/images/user-upload-01/img_convert/94512568ae674cc9d17a9f5c6a67611f.jpeg)(title-萌新复现经典游戏打砖块)]


3.打砖块1.1版本,全新出炉

游戏诞生的喜悦,使我改变了最开始只是简单复现的计划,我打算写进去更多的东西,更完整地复现功能,最好还能有点自己的想法

当天我就更新了下一个版本,代码量从150增加到240

这里我就不贴代码了,更新的东西虽然不多,但是我还是试着写了更新日志:
1.1版本更新日志

  1. 更新了少量bug
  2. 提高了默认速度
  3. 增加了音效与得分系统
  4. 新增两场BOSS战

这里的BOSS战是我自己想的,打不动的砖块实在是没有什么意思,于是这个版本我更新了两场BOSS战,我们终于可以打BOSS(其实目前只是会动的大砖块)了。

其中音效素材来源于网络,BOSS的美术素材出自游戏泰拉瑞亚,让我们看看1.1版本的试玩视频:

[video(video-zizx0Bgm-1662468163692)(type-bilibili)(url-https://player.bilibili.com/player.html?aid=640840573)(image-https://ucc.alicdn.com/images/user-upload-01/img_convert/afc86447822797a1b39b5951f6e95050.jpeg)(title-打砖块1.1版本,全新出炉)]


4.打砖块1.2!!!BOSS技能

原有的版本还是太空洞了,无论是不动的砖块还是会动的砖块,它们只能挨打,根本没有游戏难度,同时,传统打砖块在打掉砖块后可能会掉落道具,这一点我之前没有实现。

我打算实现道具,并为第一个BOSS加上技能,同时为游戏添加BGM,最后为了给我其他没学过Python的同学测评,我将其编译成了.exe文件。

第一个BOSS是一个飞碟,我希望它能够发射激光,对玩家造成一定的干扰,触碰激光会使挡板宽度减小。

这个版本添加了四种道具:

  1. +道具:拾取后加长挡板宽度
  2. -道具:拾取后减小挡板宽度
  3. S道具:拾取后加快球的速度
  4. A道具:拾取后增加一点攻击力

于是,我连肝两天,更新了1.2版本,下面是更新日志:
打砖块1.2更新日志

  1. 增加道具系统,实现部分道具功能,打砖块会随机掉落
  2. 优化BOSS行为,使之更加正常,降低了BOSS血量
  3. 对BOSS的技能进行了补全
  4. 得分现在不再与速度挂钩,删除了调速器
  5. 添加了BGM
  6. 修复了已知bug
  7. 编译为exe可执行文件,脱离了对python环境的依赖

代码量从240增加到了410.

同时这个版本,是我没能通关的第一个版本,所以我录视频的时候,为游戏写了一段代码,让挡板能够自己接球:

[video(video-964IdiOA-1662469118854)(type-bilibili)(url-https://player.bilibili.com/player.html?aid=510813876)(image-https://ucc.alicdn.com/images/user-upload-01/img_convert/29e78dbd77bef24774d4ed324956d74d.jpeg)(title-打砖块1.2版本补充视频,程序自玩,摆脱菜鸡作者的下饭操作)]


5.打砖块1.3版本更新,更多模式,更美观的界面

随着游戏性的提升,越来越多的朋友也参与测评了我的游戏,这个版本我为游戏设计了一个动态的开始界面,背景是随机BOSS与自动挡板的运动。

我还更新了3个模式提供给不同人群:

  • 无尽模式:只要还有球,游戏就不会结束,提供给大佬刷分。
  • 娱乐模式:提高道具爆率,并减少道具种类,使道具更集中在某几种上,提供给娱乐玩家。
  • 自动模式:挡板跟球运动,自动过关,提供给手残的我。

值得一提的是,这3个模式可以同时打开。

除此之外,我完善了第二个BOSS,将它的攻击方式设置为主动将球顶出去,同时它在血量低于一半的时候会进入第二阶段,速度会更快,同时受伤会放出粒子,挡板触碰后会为BOSS提供血量回复.

增加了商店,可以用得分来换取一定加成:

  • 消耗2000得分增加1速度
  • 消耗3000得分加宽挡板80
  • 消耗4000得分增加1攻击力

增加了新的道具道具,拾取后会生成一个额外的球。

还有其他各个方面的优化······

下面是1.3版本的更新日志:
1.3版本更新日志

  1. 挡板宽度现在不会小于其厚度了
  2. 由窗口变为全屏模式了
  3. 优化了碰撞反馈,采用了更精确的碰撞模型(完全弹性碰撞)
  4. 修改了部分BOSS的血量和行为,完善了奥库瑞姆的第二阶段
  5. 增加了新道具,“〇”,拾取后会生成一个额外的球
  6. 得分现在可以换取部分加成
  7. 优化了开始界面,使之更加有趣
  8. 加入了无尽模式、娱乐模式、自动模式

这个版本的代码量从上个版本的410增加到了870

这也是目前这个游戏的最新版本,让我们看看最后的视频吧:

[video(video-lcZJ5IY1-1662471305642)(type-bilibili)(url-https://player.bilibili.com/player.html?aid=768389114)(image-https://ucc.alicdn.com/images/user-upload-01/img_convert/aeea5410348e0d830146785c37c06dca.jpeg)(title-打砖块1.3版本更新,更多模式,更美观的界面)]

最后在这里放一个 游戏最新版本的下载链接,感兴趣的朋友可以下载下来体验一下:
https://download.csdn.net/download/qq_63585949/86510795?spm=1001.2014.3001.5503

6.尾声

这个游戏今后可能不会更新了,笔者挺过那段无聊的时期之后,就去自学了 C#Unity ,用 Python写游戏的想法可能不会再有了。

以后更多的是Python其他方面的应用了,我会一直努力学习下去的。

这篇博客,纪念我逝去的青春。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
2月前
|
人工智能 Ubuntu IDE
【Python】基础:环境配置与基础语法
本文介绍了Python编程语言及其环境配置方法。Python由Guido van Rossum于1991年创建,以其简洁、易学和强大的功能著称。文章详细讲解了Python的主要特点、Windows和Ubuntu下的安装配置步骤、基础语法、控制流、函数、文件操作、模块使用及面向对象编程等内容,帮助读者快速入门Python编程。
80 4
|
1月前
|
IDE 数据挖掘 开发工具
Python作为一种广受欢迎的高级编程语言,以其简洁的语法和强大的功能吸引了众多初学者和专业开发者
Python作为一种广受欢迎的高级编程语言,以其简洁的语法和强大的功能吸引了众多初学者和专业开发者
38 7
|
1月前
|
JSON 开发工具 git
基于Python和pygame的植物大战僵尸游戏设计源码
本项目是基于Python和pygame开发的植物大战僵尸游戏,包含125个文件,如PNG图像、Python源码等,提供丰富的游戏开发学习素材。游戏设计源码可从提供的链接下载。关键词:Python游戏开发、pygame、植物大战僵尸、源码分享。
|
1月前
|
存储 索引 Python
Python 的基本语法
这些是 Python 的基本语法要素,掌握它们是学习和使用 Python 的基础。通过不断地实践和应用,你将能够更深入地理解和熟练运用这些语法知识,从而编写出高效、简洁的 Python 代码
62 5
|
1月前
|
存储 Python
Python编程入门:理解基础语法与编写简单程序
本文旨在为初学者提供一个关于如何开始使用Python编程语言的指南。我们将从安装Python环境开始,逐步介绍变量、数据类型、控制结构、函数和模块等基本概念。通过实例演示和练习,读者将学会如何编写简单的Python程序,并了解如何解决常见的编程问题。文章最后将提供一些资源,以供进一步学习和实践。
35 1
|
1月前
|
机器学习/深度学习 数据挖掘 开发者
Python编程入门:理解基础语法与编写第一个程序
【10月更文挑战第37天】本文旨在为初学者提供Python编程的初步了解,通过简明的语言和直观的例子,引导读者掌握Python的基础语法,并完成一个简单的程序。我们将从变量、数据类型到控制结构,逐步展开讲解,确保即使是编程新手也能轻松跟上。文章末尾附有完整代码示例,供读者参考和实践。
|
1月前
|
存储 Python Perl
python正则语法
本文介绍了正则表达式的基础知识及其在 Python 中的应用。首先解释了为什么要使用正则表达式,通过一个判断手机号的示例展示了正则表达式的简洁性。接着详细介绍了 `re` 模块的常用方法,如 `match()`、`search()`、`findall()`、`finditer()` 等,并讲解了正则表达式的基本语法,包括匹配单个字符、数字、锚字符和限定符等。最后,文章还探讨了正则表达式的高级特性,如分组、编译和贪婪与非贪婪模式。
24 2
|
2月前
|
存储 程序员 开发者
Python编程入门:从零开始掌握基础语法
【10月更文挑战第21天】本文将带你走进Python的世界,通过浅显易懂的语言和实例,让你快速了解并掌握Python的基础语法。无论你是编程新手还是想学习一门新的编程语言,这篇文章都将是你的不二之选。我们将一起探索变量、数据类型、运算符、控制结构、函数等基本概念,并通过实际代码示例加深理解。准备好了吗?让我们开始吧!
|
2月前
|
IDE 开发工具 Python
Python扑克游戏编程---摸大点
Python扑克游戏编程---摸大点
64 1
|
2月前
|
存储 C语言 索引
Python 语法及入门 (超全超详细) 专为Python零基础 一篇博客让你完全掌握Python语法
本文全面介绍了Python的基础知识,包括Python的诞生背景、为什么学习Python、Python的应用场景、Python环境的安装、Python的基础语法、数据类型、控制流、函数以及数据容器的使用方法,旨在为Python零基础读者提供一篇全面掌握Python语法的博客。
116 0
Python 语法及入门 (超全超详细) 专为Python零基础 一篇博客让你完全掌握Python语法