python小欢喜(八)俄罗斯方块 (7) 连续生成下落的方块

2023-10-11 13:30

本文主要是介绍python小欢喜(八)俄罗斯方块 (7) 连续生成下落的方块,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前面的文章《python小欢喜(八)俄罗斯方块 (6) 源码文件的初步组织》实现了一个方块组合下落的效果,接下来实现一个方块组合停在了底部之后,一个新的方块组合紧接着从顶部落下的效果。

固定形状的方块组合组合连续下落的效果如下:
在这里插入图片描述
为了实现上述效果,当下落的方块组合碰到底部后,要停下来,并且新的方块组合从顶部落下,为此在底部方块组合类BottomGroup中添加了一个方法 eat,

#吃掉下落的方块def eat(self,fallingGroup):for d in fallingGroup.sprites():self.add(d)fallingGroup.empty()

修改下落方块组合类FallingGroup 中的 down方法:

 #方块组合向下移动def down(self, speed):if not self.bottomGroup.collided(self):self.rect.y += speedfor block in self.sprites():block.down(speed)           else:#self.reset()self.bottomGroup.eat(self)          

当下落的方块组合碰到了底部方块组合时,调用 底部方块组合 对象的eat 方法,将下落方块“吃”住。

然后在main.py的 animate函数中添加如下语句:

#如果下落的方块组合已经被底部方块组合“吃”掉了,则生成新的下落方块组合if len(fallingGroup.sprites())<=0:fallingGroup = FallingGroup(typeIdx=1,bottomGroup=bottomGroup)

从以上的编码过程可知,如果在生成下落方块组合时,随机地给出形状参数索引typeIdx,则可以随机地生成不同的形状。

为此在main.py中添加一个函数,随机地生成不同形状的下落方块组合

#随机生成下落方块组合
def randomFallingGroup():return FallingGroup(typeIdx=random.randint(0,8),bottomGroup=bottomGroup)

实际效果如下:
在这里插入图片描述

完整的代码如下:

config.py

# config.py
# 配置数据,全局变量的定义#颜色常量的定义
BLACK = (0,0,0)       # 用RGB值定义黑色
WHITE = (255,255,255) # 用RGB值定义白色#配置参数类
class Config():def __init__(self):passscreenWidth = 600screenHeight= 800blockWidth = 40speed = 40#方块移动的速度
speed = Config.speed#方块组合形状的二维矩阵图示,1表示该处有方块,0表示没有
shapeGraph=[
(
[1,1,1,1],
[0,0,0,0],
[0,0,0,0],
[0,0,0,0],
),
(
[0,1,0,0],
[1,1,1,0],
[0,0,0,0],
[0,0,0,0],
),
(
[1,0,0,0],
[1,0,0,0],
[1,0,0,0],
[1,0,0,0],
),
(
[1,1,1,0],
[1,0,0,0],
[0,0,0,0],
[0,0,0,0],
),
(
[1,0,0,0],
[1,0,0,0],
[1,1,0,0],
[0,0,0,0],
),
(
[1,1,0,0],
[1,0,0,0],
[1,0,0,0],
[0,0,0,0],
),
(
[1,0,0,0],
[1,1,0,0],
[1,0,0,0],
[0,0,0,0],
),
(
[1,1,0,0],
[0,1,1,0],
[0,0,0,0],
[0,0,0,0],
),
(
[1,1,0,0],
[1,1,0,0],
[0,0,0,0],
[0,0,0,0],
),
]#将形状图转换为形状坐标列表
def shpaeGraph2List(shapeGraph):shapeList =[]for g in shapeGraph:shape=[]for y in range(4):for x in range(4):if g[y][x] == 1 :shape.append([x*Config.blockWidth,y*Config.blockWidth])shapeList.append(shape)return shapeList#存放形状初始坐标列表的全局变量 shapeList
shapeList = shpaeGraph2List(shapeGraph)

block.py

# block.py
# 方块及方块组合类的定义import pygame
from config import *# 方块类
class Block(pygame.sprite.Sprite):def __init__(self,x,y):self.inix = xself.iniy = ypygame.sprite.Sprite.__init__(self)self.image = pygame.image.load("block.png")self.rect = self.image.get_rect()        self.rect.x = xself.rect.y = y#重置初始位置def reset(self):self.rect.x = self.inixself.rect.y = self.iniy#方块向下移动def down(self, speed):# 向下移动self.rect.centery += speed        #方块左右移动def move(self, speed):# 左右移动self.rect.centerx += speed# 表示下落中的多个方块的组合,typeIdx指明组合形状在shapeList中的索引
class FallingGroup(pygame.sprite.Group):def __init__(self, typeIdx,bottomGroup):self.bottomGroup = bottomGrouppygame.sprite.Group.__init__(self)iniX = int((Config.screenWidth/2)/Config.blockWidth)*Config.blockWidthshape = shapeList[typeIdx]       for xyPair in shape:x = iniX+xyPair[0]y = xyPair[1]             self.add(Block(x,y)) #得到组合对象的包络矩形    self.rect = self.boundingRect()#记录初始位置,此处要使用copy方法    self.iniRect = self.rect.copy()#重置初始位置def reset(self):#恢复初始位置,此处要使用copy方法  self.rect = self.iniRect.copy()       for block in self.sprites():block.reset()#方块组合向下移动def down(self, speed):if not self.bottomGroup.collided(self):self.rect.y += speedfor block in self.sprites():block.down(speed)           else:#self.reset()self.bottomGroup.eat(self)              #方块组合左右移动def move(self, speed):#print([self.rect.x,self.rect.y,self.rect.width,self.rect.height])if (speed > 0 and self.rect.x < Config.screenWidth-self.rect.width) or (speed < 0 and self.rect.x > 0):self.rect.x += speedfor block in self.sprites():block.move(speed) #求出包围组合对象的矩形def boundingRect(self):minX = Config.screenWidth+100minY = Config.screenHeight+100maxX = -100maxY = -100for block in self.sprites():if block.rect.x < minX:minX = block.rect.xif block.rect.y < minY:minY = block.rect.yif block.rect.x > maxX:maxX = block.rect.xif block.rect.y > maxY:maxY = block.rect.yreturn pygame.Rect(minX,minY,maxX-minX+Config.blockWidth,maxY-minY+Config.blockWidth)#旋转def rotate(self):#取组合对象的中心点作为旋转中心,旋转中心应位于网格点上    cx=int((self.rect.x+self.rect.width/2)/Config.blockWidth)*Config.blockWidthcy=int((self.rect.y+self.rect.height/2)/Config.blockWidth)*Config.blockWidthfor block in self.sprites():#求出当前方块的中心与旋转中心的距离差dx = block.rect.centerx -cxdy = block.rect.centery -cy#距离差组成的复数 乘上 复数 i ,得到的复数是 原复数逆时针旋转90度的结果r  = complex(dx,dy)*complex(0,1)#得到旋转之后的结果block.rect.centerx = cx + r.real + Config.blockWidthblock.rect.centery = cy + r.imag#取得包络矩形的原始水平位置lastRectX = self.rect.x            #更新组合对象的包络矩形self.rect = self.boundingRect()dx =  lastRectX - self.rect.x #使得旋转后的组合对象的水平位置保持不变self.rect.x += dxfor block in self.sprites():block.rect.x+=dx# 表示底部方块的组合
class BottomGroup(pygame.sprite.Group):def __init__(self):pygame.sprite.Group.__init__(self)#预设一行方块,放置在窗口下边界之下,不会显示,但可用于让下落的方块停下来n = int(Config.screenWidth/Config.blockWidth)for i in range(n):#测试时故意让预设的一行方块向上移动一行,这样就可显示出来,可以看到碰撞检测的效果y= Config.screenHeight-Config.blockWidth#y= Config.screenHeightx= i*Config.blockWidthself.add(Block(x,y))#检查下落的方块是否与底部方块发生了碰撞def collided(self,fallingGroup):for d in fallingGroup.sprites():for b in self.sprites():if b.rect.y - d.rect.y <=Config.blockWidth and b.rect.x == d.rect.x:return Truereturn False#吃掉下落的方块def eat(self,fallingGroup):for d in fallingGroup.sprites():self.add(d)fallingGroup.empty()

main.py

# main.py
# 俄罗斯方块,主程序所在文件import pygame
from block import *
import random#随机生成下落方块组合
def randomFallingGroup():return FallingGroup(typeIdx=random.randint(0,8),bottomGroup=bottomGroup)# 重绘显示区域,形成动画效果
def animate():global fallingGroup,bottomGroup#设置屏幕为黑色screen.fill(BLACK)#下落方块组合执行下落方法fallingGroup.down(speed)#如果下落的方块组合已经被底部方块组合“吃”掉了,则生成新的下落方块组合if len(fallingGroup.sprites())<=0:fallingGroup = randomFallingGroup()#下落方块组合执行绘制方法fallingGroup.draw(screen) #底部方块组合执行绘制方法bottomGroup.draw(screen)   #刷新屏幕 pygame.display.flip() # ------------------------main---------------------------------------------------------------------# 初始化各种对象
pygame.init()
#游戏窗口的屏幕
screen = pygame.display.set_mode([Config.screenWidth,Config.screenHeight])
#用黑色填充背景
screen.fill(BLACK)
#设置图形窗口标题
pygame.display.set_caption("俄罗斯方块") 
#游戏时钟
clock = pygame.time.Clock()#生成底部方块组合对象
bottomGroup =BottomGroup()#随机生成一个下落方块组合对象
fallingGroup = randomFallingGroup()# 事件处理循环
running = True
while running:#设定每秒帧数,为了实现俄罗斯方块一格一格的下落效果,将帧率设得很低,相应的下降速度(每秒位移量)等于方块的边长clock.tick(2) for event in pygame.event.get():    if event.type == pygame.QUIT: running = Falseif event.type == pygame.KEYDOWN:          # 如果按下了键盘上的键if event.key == pygame.K_LEFT:        # 如果按下了向左的方向键fallingGroup.move(-1*speed)elif event.key == pygame.K_RIGHT:     #如果按下了向右的方向键fallingGroup.move(speed)elif event.key == pygame.K_UP:        #如果按下了向上的方向键fallingGroup.rotate()animate()  
pygame.quit() #退出pygame

特别提示:

以上代码只是演示连续不断地生成下落的方块。随着时间的推移,会不断地生成新的方块对象,程序占用的内存会不断地增长。所以不适合运行很长的时间。在后面的文章中会对程序做进一步的完善。

这篇关于python小欢喜(八)俄罗斯方块 (7) 连续生成下落的方块的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/188379

相关文章

Python中__new__()方法适应及注意事项详解

《Python中__new__()方法适应及注意事项详解》:本文主要介绍Python中__new__()方法适应及注意事项的相关资料,new()方法是Python中的一个特殊构造方法,用于在创建对... 目录前言基本用法返回值单例模式自定义对象创建注意事项总结前言new() 方法在 python 中是一个

Python批量调整Word文档中的字体、段落间距及格式

《Python批量调整Word文档中的字体、段落间距及格式》这篇文章主要为大家详细介绍了如何使用Python的docx库来批量处理Word文档,包括设置首行缩进、字体、字号、行间距、段落对齐方式等,需... 目录关键代码一级标题设置  正文设置完整代码运行结果最近关于批处理格式的问题我查了很多资料,但是都没

Python依赖库的几种离线安装方法总结

《Python依赖库的几种离线安装方法总结》:本文主要介绍如何在Python中使用pip工具进行依赖库的安装和管理,包括如何导出和导入依赖包列表、如何下载和安装单个或多个库包及其依赖,以及如何指定... 目录前言一、如何copy一个python环境二、如何下载一个包及其依赖并安装三、如何导出requirem

python中列表list切分的实现

《python中列表list切分的实现》列表是Python中最常用的数据结构之一,经常需要对列表进行切分操作,本文主要介绍了python中列表list切分的实现,文中通过示例代码介绍的非常详细,对大家... 目录一、列表切片的基本用法1.1 基本切片操作1.2 切片的负索引1.3 切片的省略二、列表切分的高

基于Python实现一个PDF特殊字体提取工具

《基于Python实现一个PDF特殊字体提取工具》在PDF文档处理场景中,我们常常需要针对特定格式的文本内容进行提取分析,本文介绍的PDF特殊字体提取器是一款基于Python开发的桌面应用程序感兴趣的... 目录一、应用背景与功能概述二、技术架构与核心组件2.1 技术选型2.2 系统架构三、核心功能实现解析

通过Python脚本批量复制并规范命名视频文件

《通过Python脚本批量复制并规范命名视频文件》本文介绍了如何通过Python脚本批量复制并规范命名视频文件,实现自动补齐数字编号、保留原始文件、智能识别有效文件等功能,听过代码示例介绍的非常详细,... 目录一、问题场景:杂乱的视频文件名二、完整解决方案三、关键技术解析1. 智能路径处理2. 精准文件名

基于Python开发PDF转Doc格式小程序

《基于Python开发PDF转Doc格式小程序》这篇文章主要为大家详细介绍了如何基于Python开发PDF转Doc格式小程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用python实现PDF转Doc格式小程序以下是一个使用Python实现PDF转DOC格式的GUI程序,采用T

Python使用PIL库将PNG图片转换为ICO图标的示例代码

《Python使用PIL库将PNG图片转换为ICO图标的示例代码》在软件开发和网站设计中,ICO图标是一种常用的图像格式,特别适用于应用程序图标、网页收藏夹图标等场景,本文将介绍如何使用Python的... 目录引言准备工作代码解析实践操作结果展示结语引言在软件开发和网站设计中,ICO图标是一种常用的图像

使用Python开发一个图像标注与OCR识别工具

《使用Python开发一个图像标注与OCR识别工具》:本文主要介绍一个使用Python开发的工具,允许用户在图像上进行矩形标注,使用OCR对标注区域进行文本识别,并将结果保存为Excel文件,感兴... 目录项目简介1. 图像加载与显示2. 矩形标注3. OCR识别4. 标注的保存与加载5. 裁剪与重置图像

使用Python实现表格字段智能去重

《使用Python实现表格字段智能去重》在数据分析和处理过程中,数据清洗是一个至关重要的步骤,其中字段去重是一个常见且关键的任务,下面我们看看如何使用Python进行表格字段智能去重吧... 目录一、引言二、数据重复问题的常见场景与影响三、python在数据清洗中的优势四、基于Python的表格字段智能去重