用python制作俄罗斯方块

news/2025/2/19 13:56:04/

代码如下,可以直接运行:

import random, pygame, sys, ctypes
from pygame.locals import *FPS = 60
CELL_SIZE = 20
CELLS_WIDE = 16
CELLS_HIGH = 24GRID = []
for x in range(CELLS_WIDE):GRID.append([None] * CELLS_HIGH)WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
DARKGRAY = (40, 40, 40)
BGCOLOR = BLACK
GRID_LINES_COLOR = DARKGRAYWINDOWWIDTH = CELL_SIZE * CELLS_WIDE
WINDOWHEIGHT = CELL_SIZE * CELLS_HIGHDEFAULT_SPEED = 650G_BLOCK = [[[0, 1, 0], [1, 1, 0], [1, 0, 0]],[[2, 0, 0], [2, 2, 0], [0, 2, 0]],[[3, 3, 0], [0, 3, 0], [0, 3, 0]],[[4, 4, 0], [4, 0, 0], [4, 0, 0]],[[0, 5, 0], [5, 5, 5], [0, 0, 0]],[[6, 6], [6, 6]],[[7, 0, 0, 0], [7, 0, 0, 0], [7, 0, 0, 0], [7, 0, 0, 0]],
]BLOCK_COLOR = [(255, 0, 0), (255, 165, 0), (255, 255, 0), (0, 255, 0), (0, 127, 255), (0, 0, 255), (139, 0, 255)]class Block():def __init__(self, _type=None, speed=None):if _type is None:self._type = random.randint(0, 6)else:self._type = _typeif speed is None:self.speed = DEFAULT_SPEEDelse:self.speed = speedself.block = G_BLOCK[self._type]self._len = len(self.block)self.pos = []for i in range(self._len):self.pos.append([7, -1 * (i + 1)])def drop(self):if self.isStop():return FalsesetBlock(True)for pos in iter(self.pos):pos[1] += 1pygame.time.wait(self.speed)return Truedef isStop(self):skip = []for i in range(self._len):if self.pos[i][1] < 0:continuelayer = self.block[self._len - i - 1]for j, _type in enumerate(layer):pos = [self.pos[i][0] + j, self.pos[i][1]]if (_type != 0 and pos[1] + 1 in (-1, CELLS_HIGH)) or (j not in skip and _type != 0 and GRID[pos[0]][pos[1] + 1]):return Trueif _type != 0:skip.append(j)return Falsedef move(self, is_right=False):x = self.pos[0][0]for i, layer in enumerate(self.block):if self.pos[i][1] >= CELLS_HIGH:continuefor j, _type in enumerate(layer):if _type == 0:continueif is_right:if x + j + 1 in (-1, CELLS_WIDE) or GRID[x + j + 1][self.pos[i][1]]:returnelse:if x + j - 1 in (-1, CELLS_WIDE) or GRID[x + j - 1][self.pos[i][1]]:returnsetBlock(True)for pos in iter(self.pos):if is_right:pos[0] += 1else:pos[0] -= 1if self.pos[0][1] >= CELLS_HIGH - 1:setBlock(False)def change(self):if self._type == 5:returnnew_block = []if self._type == 0 or self._type == 1 or self._type == 6:if self.block != G_BLOCK[self._type]:new_block = G_BLOCK[self._type]if len(new_block) == 0:for i in range(self._len):new_block.append([])for i in range(self._len - 1, -1, -1):for j, _type in enumerate(self.block[i]):new_block[j].append(_type)tmp_pos = []for i, layer in enumerate(self.block):for j, _type in enumerate(layer):if _type != 0:tmp_pos.append([self.pos[self._len - i - 1][0] + j, self.pos[self._len - i - 1][1]])x = self.pos[0][0]for i, layer in enumerate(new_block):for j, _type in enumerate(layer):if _type == 0:continueif [x + j, self.pos[i][1]] in tmp_pos:continueif x + j in (-1, CELLS_WIDE) or GRID[x + j][self.pos[i][1]]:returnsetBlock(True)self.block = new_blockdef setBlock(clear_old):for i, pos in enumerate(g_block.pos):if pos[1] < 0:continueblock = g_block.block[g_block._len - i - 1]for j, _type in enumerate(block):if _type != 0:if clear_old:GRID[pos[0] + j][pos[1]] = Noneelse:GRID[pos[0] + j][pos[1]] = BLOCK_COLOR[_type - 1]def checkCleanLine():clean_row = 0for i in range(CELLS_HIGH - 1, -1, -1):flag = Truefor j in range(CELLS_WIDE - 1, -1, -1):if GRID[j][i + clean_row] is None:flag = Falsebreakif flag:for j in range(CELLS_WIDE - 1, -1, -1):GRID[j].pop(i + clean_row)GRID[j].insert(0, None)clean_row += 1def gameOver():ctypes.windll.user32.MessageBoxA(0, "Don't lose heart, try it again", 'Game Over', 0)def handleEvents():for event in pygame.event.get():  # event handling loopif (event.type == QUIT) or (event.type == KEYDOWN and event.key == K_ESCAPE):pygame.quit()sys.exit()elif event.type == KEYDOWN or event.type == KEYUP:handleControl(event)def handleControl(event):if event.type == KEYDOWN:if event.key == K_LEFT:g_block.move()elif event.key == K_RIGHT:g_block.move(True)elif event.key == K_SPACE or event.key == K_UP:g_block.change()elif event.key == K_DOWN:g_block.speed -= 600elif event.type == KEYUP and event.key == K_DOWN:g_block.speed = DEFAULT_SPEEDdef drawGrid():DISPLAYSURF.fill(BGCOLOR)for x in range(0, WINDOWWIDTH, CELL_SIZE):pygame.draw.line(DISPLAYSURF, GRID_LINES_COLOR, (x, 0), (x, WINDOWHEIGHT))for y in range(0, WINDOWHEIGHT, CELL_SIZE):pygame.draw.line(DISPLAYSURF, GRID_LINES_COLOR, (0, y), (WINDOWWIDTH, y))for x in range(0, CELLS_WIDE):for y in range(0, CELLS_HIGH):if GRID[x][y] is None:continuecolor = GRID[x][y]darkerColor = (max(color[0] - 50, 0), max(color[1] - 50, 0), max(color[2] - 50, 0))pygame.draw.rect(DISPLAYSURF, darkerColor, (x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE))pygame.draw.rect(DISPLAYSURF, color, (x * CELL_SIZE + 4, y * CELL_SIZE + 4, CELL_SIZE - 8, CELL_SIZE - 8))def main():global FPSCLOCK, DISPLAYSURFglobal g_blockpygame.init()FPSCLOCK = pygame.time.Clock()DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))pygame.display.set_caption('Tetris')g_block = Block(6)while True:handleEvents()if not g_block.drop():checkCleanLine()del g_blockg_block = Block(6)setBlock(False)drawGrid()pygame.display.update()FPSCLOCK.tick(FPS)if __name__ == '__main__':main()

http://www.ppmy.cn/news/55185.html

相关文章

【Unity入门】19.定时调用Invoke

【Unity入门】定时调用Invoke 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity入门系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;计时器 &#xff08;1&#xff09;Invoke 单词调用 计时器我们并不陌生&#xff0c;在cocos上有着schedule类是…

Docker安装在Linux系统上(纯步骤)

Docker安装在Linux系统上操作步骤 本文章只有操作步骤&#xff0c;没有原理解释&#xff0c;只是用来提醒自己安装步骤 下面是docker官网&#xff0c;也有安装详情 https://docs.docker.com/engine/install/centos/ 安装分为四步走 我使用的是CentOS7版本&#xff0c;下面命令…

【AI实战】微小目标检测模型SSPNet--训练环境从零开始搭建

【AI实战】微小目标检测模型SSPNet--训练环境从零开始搭建 SSPNet介绍环境搭建安装依赖参考 SSPNet介绍 SSPNet: Scale Selection Pyramid Network for Tiny Person Detection from UAV Images 官方连接 https://github.com/MingboHong/SSPNetarxiv https://arxiv.org/abs/210…

2023-04-26 力扣LeetCode上的DP动态规划问题分类汇总

2023-04-26 力扣LeetCode上的DP动态规划问题分类汇总 1、线性 DP 最经典单串&#xff1a; 300. 最长上升子序列最经典双串&#xff1a; 1143. 最长公共子序列经典问题&#xff1a; 120. 三角形最小路径和 53. 最大子序和 152. 乘积最大子数组 887. 鸡蛋掉落&#xff08;DP二分…

【嵌入式环境下linux内核及驱动学习笔记-(7-内核 I/O)-多路复用】

目录 2、多路复用2.1 函数select相关2.1.1 应用层select()2.1.2 FD_ZERO2.1.3 FD_SET2.1.4 FD_ISSET 2.2 函数poll相关2.2.1 poll函数 2.3 驱动层 函数2.4 实例 接上篇&#xff0c;继续内核 I/O的五种模式的解读。 2、多路复用 select&#xff0c;poll&#xff0c;epoll都是IO…

C++刷题--选择题3

1&#xff0c; 在上下文和头文件均正常情况下&#xff0c;以下程序的输出结果是&#xff08;&#xff09; int x 1; do{ printf("%2d\n",x); }while(x--);A 1 B 无任何输出 C 2 D 陷入死循环 解析 &#xff1a; D&#xff0c;do-while语句&#xff0c; do里面的先…

ChatGPT会一直火热下去吗?他会是下一个AR,区块链吗?

目录 前言 VR 热潮 区块链热潮 元宇宙热潮 ChatGPT 热潮 理智看待 ChatGPT 前言 如果在今年年底评选 2023 年的年度科技热词&#xff0c;以 ChatGPT 目前的热度&#xff0c;毫无疑问会是今年排名第一的科技热词。 即使今年才过去四个月&#xff0c;但我很难想象还有什么科…

SCADA平台的HMI功能

01 前言 虹科Panorama SCADA平台支持桌面HMI、Web HMI和移动HMI的功能。桌面HMI主要是在桌面工作站实现数据可视化&#xff0c;能够获取到最全面的数据信息以及实现功能&#xff1b;Web HMI可以通过在软件中添加Web HMI服务器&#xff0c;运行程序后&#xff0c;可以在Web 客户…