吴裕雄--天生自然python学习笔记:python 用pygame模块开发俄罗斯方块游戏
俄罗斯方块游戏
多年前,游戏机中最流行的游戏就是“俄罗斯方块”了。时至今日,虽然网络
游戏日新月异 ,但“俄罗斯方块”这款小游戏仍在许多人心中 占有一席之地。本例中,
我们将亲手设计一个简单的俄罗斯方块游戏 。
应用程序总览
开始时游戒窗门的下方会显示“单击鼠标左键开始游戏”的提示信息,用户单
击左键后显示游戏画面 。 用户移动鼠标控制滑板,滑板只能左右移动,其位置与鼠
标的 x 坐标相同:共有 6 0 个方块 , 被球撞到的方块会消失 ,同时分数会增加 , 球撞
到方块及滑板会发出不同声音 。

如果球体碰到下地界就表示球体己出界,显示“失败,再接再厉!”的信息并
结束游戏 : 若全部方块都消失则显示“恭喜,挑战成功 !”的信息并结束游戏。

球体、方块、滑板的角色类
本游戏主角是球体 、 方块及滑板,都设计为角色类 。首先是球体角色
import pygame, random, math, time class Ball(pygame.sprite.Sprite): #球体角色
dx = 0 #x位移量
dy = 0 #y位移量
x = 0 #球x坐标
y = 0 #球y坐标
direction = 0 #球移动方向
speed = 0 #球移动速度 def __init__(self, sp, srx, sry, radium, color):
pygame.sprite.Sprite.__init__(self)
self.speed = sp
self.x = srx
self.y = sry
self.image = pygame.Surface([radium*2, radium*2]) #绘制球体背景区域
self.image.fill((255,255,255)) #设置背景区域为白色(与游戏窗口背景色相同)
pygame.draw.circle(self.image, color, (radium,radium), radium, 0)
self.rect = self.image.get_rect() #取得球体区域
self.rect.center = (srx,sry) #初始位置
self.direction = random.randint(40,70) #移动角度 def update(self): #球体移动
radian = math.radians(self.direction) #角度转为弧度
self.dx = self.speed * math.cos(radian) #球水平运动速度
self.dy = -self.speed * math.sin(radian) #球垂直运动速度
self.x += self.dx #计算球的新坐标
self.y += self.dy
self.rect.x = self.x #移动球
self.rect.y = self.y
if(self.rect.left <= 0 or self.rect.right >= screen.get_width()-10): #到达左右边界
self.bouncelr()
elif(self.rect.top <= 10): #到达上边界
self.rect.top = 10
self.bounceup()
if(self.rect.bottom >= screen.get_height()-10): #到达下边界出界
return True
else:
return False def bounceup(self): #上边界反弹
self.direction = 360 - self.direction def bouncelr(self): #左右边界反弹
self.direction = (180 - self.direction) % 360
球体碰到上边界时的反弹处理函数 : 反弹角度=360 -原来角度。 例如
下图中原来角度为 30 ° , 则反弹后 的角度为 330 ° 。

球体碰到左、右边界时的反弹处理函数:反弹角度 = 1 80- 原来角度 。
因为反弹角度可能得到负值,所以通过除以 360 取余的方法将其转化
为正数 。 例如下图中运动角度为 30 。 ,反弹角度为 1 50 。。

class Brick(pygame.sprite.Sprite): #方块角色
def __init__(self, color, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([38, 13]) #方块38x13
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y class Pad(pygame.sprite.Sprite): #滑板角色
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("media\\pad.png") #滑板图片
self.image.convert()
self.rect = self.image.get_rect()
self.rect.x = int((screen.get_width() - self.rect.width)/2) #滑板位置
self.rect.y = screen.get_height() - self.rect.height - 20 def update(self): #滑板位置随鼠标移动
pos = pygame.mouse.get_pos() #取得鼠标坐标
self.rect.x = pos[0] #鼠标的x坐标
if self.rect.x > screen.get_width() - self.rect.width: #不要移出右边界
self.rect.x = screen.get_width() - self.rect.width
自定义方法及主程序
自定义 gameover 方法,实现在球出界或全部方块消失的情况下结束程序的功能。
def gameover(message): #结束程序
global running
text = font1.render(message, 1, (255,0,255)) #显示讯息
screen.blit(text, (screen.get_width()/2-100,screen.get_height()/2-20))
pygame.display.update() #更新画面
time.sleep(3) #暂停3秒
running = False #结束程序
主程序创建各种角色及初值设定。
pygame.init()
score = 0 #得分
font = pygame.font.SysFont("SimHei", 20) #设置下方提示信息的字体
font1 = pygame.font.SysFont("SimHei", 32) #结束程序信息字体
soundhit = pygame.mixer.Sound("media\\hit.wav") #碰到方块的声音
soundpad = pygame.mixer.Sound("media\\pad.wav") #碰到滑板的声音
screen = pygame.display.set_mode((600, 400))
pygame.display.set_caption("俄罗斯方块游戏")
background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((255,255,255))
allsprite = pygame.sprite.Group() #建立全部角色组
bricks = pygame.sprite.Group() #建立砖块角色组
ball = Ball(5, 300, 350, 10, (255,0,0)) #建立红色球对象
allsprite.add(ball) #加入全部角色组
pad = Pad() #建立滑板对象
allsprite.add(pad) #加入全部角色组
clock = pygame.time.Clock()
for row in range(0, 4): #3行方块
for column in range(0, 15): #每行15个方块
if row == 0 or row == 1: #1,2行为绿色方块
brick = Brick((0,255,0), column * 40 + 1, row * 15 + 1)
if row == 2 or row == 3: #3,4行为蓝色方块
brick = Brick((0,0,255), column * 40 + 1, row * 15 + 1)
bricks.add(brick) #加入方块角色组
allsprite.add(brick) #加入全部角色组
msgstr = "单击鼠标左键开始游戏!" #提示信息
playing = False #开始时球不会移动
running = True
创建 4 行 15 列的方块:长宽为 38 × 13 ,第 100 行和第 102 行代码设
定方块的位置为 40 × 15 ,留 2 像素作为方块间隔。
方块要同时加入全部角色组及方块角色组。全部角色组用于绘制图
形,方块角色组用于侦测与球体的碰撞 。
设定程序开始时显示的信息 。
设定程序开始时球体不会移动 。
主程序(无限循环动画)代码 。
while running:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
buttons = pygame.mouse.get_pressed() #或取鼠标按键状态
if buttons[0]: #单击鼠标左键后球可移动
playing = True
if playing == True: #游戏进行中
screen.blit(background, (0,0)) #清除绘图窗口
fail = ball.update() #移动球体
if fail: #球出界
gameover("失败,再接再励!")
pad.update() #更新滑板位置
hitbrick = pygame.sprite.spritecollide(ball, bricks, True) #检查球和方块碰撞
if len(hitbrick) > 0: #球和方块发生碰撞
score += len(hitbrick) #计算分数
soundhit.play() #球撞方块声
ball.rect.y += 20 #球向下移
ball.bounceup() #球反弹
if len(bricks) == 0: #所有方块消失
gameover("恭喜,挑战成功!")
hitpad = pygame.sprite.collide_rect(ball, pad) #检查球和滑板碰撞
if hitpad: #球和滑板发生碰撞
soundpad.play() #球撞滑板声音
ball.bounceup() #球反弹
allsprite.draw(screen) #绘制所有角色
msgstr = "得分:" + str(score)
msg = font.render(msgstr, 1, (255,0,255))
screen.blit(msg, (screen.get_width()/2-60,screen.get_height()-20)) #显示信息
pygame.display.update()
pygame.quit()
import pygame, random, math, time class Ball(pygame.sprite.Sprite): #球体角色
dx = 0 #x位移量
dy = 0 #y位移量
x = 0 #球x坐标
y = 0 #球y坐标
direction = 0 #球移动方向
speed = 0 #球移动速度 def __init__(self, sp, srx, sry, radium, color):
pygame.sprite.Sprite.__init__(self)
self.speed = sp
self.x = srx
self.y = sry
self.image = pygame.Surface([radium*2, radium*2]) #绘制球体背景区域
self.image.fill((255,255,255)) #设置背景区域为白色(与游戏窗口背景色相同)
pygame.draw.circle(self.image, color, (radium,radium), radium, 0)
self.rect = self.image.get_rect() #取得球体区域
self.rect.center = (srx,sry) #初始位置
self.direction = random.randint(40,70) #移动角度 def update(self): #球体移动
radian = math.radians(self.direction) #角度转为弧度
self.dx = self.speed * math.cos(radian) #球水平运动速度
self.dy = -self.speed * math.sin(radian) #球垂直运动速度
self.x += self.dx #计算球的新坐标
self.y += self.dy
self.rect.x = self.x #移动球
self.rect.y = self.y
if(self.rect.left <= 0 or self.rect.right >= screen.get_width()-10): #到达左右边界
self.bouncelr()
elif(self.rect.top <= 10): #到达上边界
self.rect.top = 10
self.bounceup()
if(self.rect.bottom >= screen.get_height()-10): #到达下边界出界
return True
else:
return False def bounceup(self): #上边界反弹
self.direction = 360 - self.direction def bouncelr(self): #左右边界反弹
self.direction = (180 - self.direction) % 360 class Brick(pygame.sprite.Sprite): #方块角色
def __init__(self, color, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([38, 13]) #方块38x13
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y class Pad(pygame.sprite.Sprite): #滑板角色
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("F:\\pythonBase\\pythonex\\ch14\\media\\pad.png") #滑板图片
self.image.convert()
self.rect = self.image.get_rect()
self.rect.x = int((screen.get_width() - self.rect.width)/2) #滑板位置
self.rect.y = screen.get_height() - self.rect.height - 20 def update(self): #滑板位置随鼠标移动
pos = pygame.mouse.get_pos() #取得鼠标坐标
self.rect.x = pos[0] #鼠标的x坐标
if self.rect.x > screen.get_width() - self.rect.width: #不要移出右边界
self.rect.x = screen.get_width() - self.rect.width def gameover(message): #结束程序
global running
text = font1.render(message, 1, (255,0,255)) #显示讯息
screen.blit(text, (screen.get_width()/2-100,screen.get_height()/2-20))
pygame.display.update() #更新画面
time.sleep(3) #暂停3秒
running = False #结束程序 pygame.init()
score = 0 #得分
font = pygame.font.SysFont("SimHei", 20) #设置下方提示信息的字体
font1 = pygame.font.SysFont("SimHei", 32) #结束程序信息字体
soundhit = pygame.mixer.Sound("F:\\pythonBase\\pythonex\\ch14\\media\\hit.wav") #碰到方块的声音
soundpad = pygame.mixer.Sound("F:\\pythonBase\\pythonex\\ch14\\media\\pad.wav") #碰到滑板的声音
screen = pygame.display.set_mode((600, 400))
pygame.display.set_caption("俄罗斯方块游戏")
background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((255,255,255))
allsprite = pygame.sprite.Group() #建立全部角色组
bricks = pygame.sprite.Group() #建立砖块角色组
ball = Ball(5, 300, 350, 10, (255,0,0)) #建立红色球对象
allsprite.add(ball) #加入全部角色组
pad = Pad() #建立滑板对象
allsprite.add(pad) #加入全部角色组
clock = pygame.time.Clock()
for row in range(0, 4): #3行方块
for column in range(0, 15): #每行15个方块
if row == 0 or row == 1: #1,2行为绿色方块
brick = Brick((0,255,0), column * 40 + 1, row * 15 + 1)
if row == 2 or row == 3: #3,4行为蓝色方块
brick = Brick((0,0,255), column * 40 + 1, row * 15 + 1)
bricks.add(brick) #加入方块角色组
allsprite.add(brick) #加入全部角色组 msgstr = "单击鼠标左键开始游戏!" #提示信息
playing = False #开始时球不会移动
running = True
while running:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
buttons = pygame.mouse.get_pressed() #或取鼠标按键状态
if buttons[0]: #单击鼠标左键后球可移动
playing = True
if playing == True: #游戏进行中
screen.blit(background, (0,0)) #清除绘图窗口
fail = ball.update() #移动球体
if fail: #球出界
gameover("失败,再接再励!")
pad.update() #更新滑板位置
hitbrick = pygame.sprite.spritecollide(ball, bricks, True) #检查球和方块碰撞
if len(hitbrick) > 0: #球和方块发生碰撞
score += len(hitbrick) #计算分数
soundhit.play() #球撞方块声
ball.rect.y += 20 #球向下移
ball.bounceup() #球反弹
if len(bricks) == 0: #所有方块消失
gameover("恭喜,挑战成功!")
hitpad = pygame.sprite.collide_rect(ball, pad) #检查球和滑板碰撞
if hitpad: #球和滑板发生碰撞
soundpad.play() #球撞滑板声音
ball.bounceup() #球反弹
allsprite.draw(screen) #绘制所有角色
msgstr = "得分:" + str(score)
msg = font.render(msgstr, 1, (255,0,255))
screen.blit(msg, (screen.get_width()/2-60,screen.get_height()-20)) #显示信息
pygame.display.update()
pygame.quit()


吴裕雄--天生自然python学习笔记:python 用pygame模块开发俄罗斯方块游戏的更多相关文章
- 吴裕雄--天生自然HADOOP学习笔记:hadoop集群实现PageRank算法实验报告
实验课程名称:大数据处理技术 实验项目名称:hadoop集群实现PageRank算法 实验类型:综合性 实验日期:2018年 6 月4日-6月14日 学生姓名 吴裕雄 学号 15210120331 班 ...
- 吴裕雄--天生自然MySQL学习笔记:MySQL UPDATE 更新
如果需要修改或更新 MySQL 中的数据,我们可以使用 SQL UPDATE 命令来操作. 语法 以下是 UPDATE 命令修改 MySQL 数据表数据的通用 SQL 语法: UPDATE table ...
- 吴裕雄--天生自然MySQL学习笔记:MySQL 插入数据
MySQL 表中使用 INSERT INTO SQL语句来插入数据. 可以通过 mysql> 命令提示窗口中向数据表中插入数据,或者通过PHP脚本来插入数据. 以下为向MySQL数据表插入数据通 ...
- 吴裕雄--天生自然MySQL学习笔记:MySQL简介
MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用 ...
- 吴裕雄--天生自然 oracle学习笔记:oracle理论学习详解及各种简单操作例子
1. 数据库的发展过程 层次模型 -->网状模型 -->关系模型 -->对象关系模型 2. 关于数据库的概念 DB:数据库(存储信息的仓库) DBMS:数据库管理系统(用于管理数据库 ...
- 吴裕雄--天生自然HADOOP学习笔记:基本环境配置
实验目的 学习安装Java 学习配置环境变量 学习设置免密码登陆的方法 掌握Linux环境下时间同步的配置 实验原理 1.Java的安装 java是大数据的黄金语言,这和java跨平台的特性是密不可分 ...
- 吴裕雄--天生自然HADOOP学习笔记:使用yum安装更新软件
实验目的 了解yum的原理及配置 学习软件的更新与安装 学习源代码编译安装 实验原理 1.编译安装 前面我们讲到了安装软件的方式,因为linux是开放源码的,我们可以直接获得源码,自己编译安装.例如: ...
- 吴裕雄--天生自然HADOOP学习笔记:Shell工具使用
实验目的 学习使用xshell工具连接Linux服务器 在连上的服务器中进入用户目录 熟悉简单的文件操作命令 实验原理 熟悉shell命令是熟悉使用linux环境进行开发的第一步,我们在linux的交 ...
- 吴裕雄--天生自然HTML学习笔记:HTML 布局
网页布局对改善网站的外观非常重要. 请慎重设计您的网页布局. <!DOCTYPE html> <html> <head> <meta charset=&qu ...
- 吴裕雄--天生自然MySQL学习笔记:MySQL 安装
所有平台的 MySQL 下载地址为: MySQL 下载:https://dev.mysql.com/downloads/mysql/ 注意:安装过程我们需要通过开启管理员权限来安装,否则会由于权限不足 ...
随机推荐
- 尝试用kotlin做一个app(写在前面)
学kotlin的目的好像就是做一个app,不一定有什么想做的项目,只是单纯想掌握这一门技术,确切地说只是单纯想学会做app.对于概念的东西,我也没兴趣深究,用得到的学一下,用不到的,就算了.我也不知道 ...
- Vue-router的介绍
1.路由基础介绍 (1)什么是前端路由: 路由是根据不同的URL地址展示不同的内容或页面. 前端路由就是把不同路由对应不同的内容或页面的任务交给前端来做.之前是通过服务端根据URL的不同返回不同的页面 ...
- python期末考试复习
期末考试复习 补修的python跟着大一一起学,考试肯定不会出难,于是就敲了一些代码,把他们放到博客上,来记录一下 代码都是一段一段的,且python代码不是很多,所以我都写到了一个文件里,作为练习 ...
- php对象:__autoload()函数及单入口文件,__set(), __get(), get_class_methods(),get_class_vars()
__autoload():当类中找不到相关类的时候,会自动执行__autoload()函数,可以自动加载相关文件 __set() : 当对类的私有变量进行调用赋值时,自动调用该方法. __get() ...
- Try setting a different JdbcType for this parameter or a different configuration property. Cause: org.postgresql.util.PSQLException: 栏位索引超过许可范围:2,栏位数:1
执行mybaits sql <delete id="delete4BatchesByLineCi" parameterType="java.util.List&qu ...
- art-template常用总结
高性能JavaScript模板引擎原理解析:http://cdc.tencent.com/2012/06/15/%E9%AB%98%E6%80%A7%E8%83%BDjavascript%E6%A8% ...
- 题解 洛谷P2158 【[SDOI2008]仪仗队】
本文搬自本人洛谷博客 题目 本文进行了一定的更新 优化了 Markdown 中 Latex 语句的运用,加强了可读性 补充了"我们仍不曾知晓得 消失的 性质5 ",加强了推导的严谨 ...
- Nginx模块-ngx_http_mirror_module-流量复制【转】
Nginx流量复制# 需求# 将生产环境的流量拷贝到预上线环境或测试环境,这样做有很多好处,比如: 可以验证功能是否正常,以及服务的性能: 用真实有效的流量请求去验证,又不用造数据,不影响线上正常访问 ...
- 64)vertor 简单使用
1)简单 代码样例:我的理解 vector 其实就是一个简单的数组,然后通过迭代器来进行 遍历数组中的值,而且有自带push_back()来添加元素 #include<iostream&g ...
- LGOJ1344 追查坏牛奶
Description link 题意概述:给一张图,每条边有边权,求让点 \(1\) 和点 \(n\) 不连通的"最小破坏边权和" 和 "在此基础上的最小破坏边数&qu ...