import random
import sys
import time
from bisect import bisect
from copy import deepcopy
import pygame
from blocks import BLOCKS
SCREEN_WIDTH, SCREEN_HEIGHT = 450, 750
BLOCK_COL_NUM = 10 # 每行的方格数
BLOCK_ROW_NUM = 25 # 每列的方个数
SIZE = 30 # 每个小方格大小
BG_COLOR = (40, 40, 60) # 背景色
RED = (200, 30, 30) # 红色,GAME OVER 的字体颜色
WHITE = (255,255,255) # 白色
BLACK = (0,0,0) # 黑色
GREEN = (60, 128, 80) # 绿色
STOP_LST = [[0 for _ in range(BLOCK_COL_NUM)]
for _ in range(BLOCK_ROW_NUM)]
# 消除逻辑
def judgeLines(stopLst):
# 记录刚刚消除的行数
i, N, count = 0, len(stopLst), 0
for i in range(N):
if 0 not in stopLst[i]:
line = [0]*len(stopLst.pop(i))
stopLst.insert(0, line)
count += 10
return count
# 将停止移动的block添加到堆积方块
def addToStopLst(stopLst, block, stRow, stCol):
for row, line in enumerate(block):
for col, b in enumerate(line):
if b: stopLst[stRow + row][stCol + col] = 1
def rotateBlock(block):
newBlock = [[[] for _ in block] for b in block[0]]
for i,row in enumerate(block, 1):
for j,r in enumerate(row, 0):
newBlock[j][-i] = r
return newBlock
# 判断是否可以向左右移动
# isR为True,判断能否向右移动;isR为False,判断能否向左移动
def judgeMoveLR(block, stCol, isR):
nCol = len(block[0])
cols = range(nCol-1, -1, -1) if isR else range(nCol)
for col in cols:
lstCol = [line[col] for line in block]
if 1 not in lstCol:
continue
if not 0 <= stCol + col < BLOCK_COL_NUM:
return False
return True
# 相左或者向右移动
def moveLR(block, stCol, key):
isR = key == pygame.K_RIGHT
stCol = stCol + 1 if isR else stCol - 1
if judgeMoveLR(block ,stCol, isR):
return 1 if isR else -1
return 0
# 判断是否可以继续下落
def judgeMoveDown(block, stRow, stCol, stopLst):
# 堆积方块的位置
stopPosition = list()
for row, line in enumerate(stopLst):
for col, b in enumerate(line):
if b: stopPosition.append((row, col))
# 判断碰撞
for row, line in enumerate(block):
if 1 in line and stRow + row >= BLOCK_ROW_NUM:
return False
for col, b in enumerate(line):
if b and (stRow + row, stCol + col) in stopPosition:
return False
return True
def canMove(block, stRow, stCol, stopLst):
flag = judgeMoveLR(block, stCol, False)
flag &= judgeMoveLR(block, stCol, True)
flag &= judgeMoveDown(block, stRow, stCol, stopLst)
return flag
# 创建一个图形
def newBlock():
block = random.choice(BLOCKS)
for _ in range(random.randint(0,4)):
block = rotateBlock(block)
return block
def drawBackground(screen):
screen.fill(BG_COLOR)
width = SIZE * BLOCK_COL_NUM
pygame.draw.line(screen, BLACK, (width, 0), (width, SCREEN_HEIGHT), 4)
for x in range(BLOCK_COL_NUM):
pygame.draw.line(screen, BLACK, (x * SIZE, 0), (x * SIZE, SCREEN_HEIGHT), 1)
for y in range(BLOCK_ROW_NUM):
pygame.draw.line(screen, BLACK, (0, y * SIZE), (width, y * SIZE), 1)
def drawRight(screen, score, speedInfo):
fontPath = r'C:\Windows\Fonts\msyh.ttc'
font = pygame.font.Font(fontPath, 24) # 黑体24
posDct = {
'得分: ':10, str(score): 50,
'速度: ':100, speedInfo: 150,
'下一个:':200
}
for k,v in posDct.items():
msg = font.render(k, True, WHITE)
screen.blit(msg, (BLOCK_COL_NUM * SIZE + 10, v))
def drawBlock(screen, row, col, stRow, stCol):
stRow += row * SIZE
stCol += SIZE * col
rect = pygame.Rect(stCol, stRow, SIZE, SIZE)
pygame.draw.rect(screen, GREEN, rect, 0)
pygame.draw.rect(screen, BLACK, rect, 1)
def drawBlocks(screen, block, stRow, stCol):
for row, line in enumerate(block):
for col, b in enumerate(line):
if not b: continue
drawBlock(screen, row, col, stRow, stCol)
def drawGamerOver(screen):
fontPath = r'C:\Windows\Fonts\msyh.ttc'
font = pygame.font.Font(fontPath, 72)
w, h = font.size('GAME OVER')
msg = font.render('GAME OVER', True, RED)
screen.blit(msg, ((SCREEN_WIDTH - w) // 2, (SCREEN_HEIGHT - h) // 2))
# 显示"鼠标点击任意位置,再来一局"
font = pygame.font.Font(fontPath, 24)
w, h = font.size('点击任意位置,再来一局')
msg = font.render('点击任意位置,再来一局', True, RED)
screen.blit(msg, ((SCREEN_WIDTH - w) // 2, (SCREEN_HEIGHT - h) // 2 + 80))
def changeSpeed(score):
scores = [20, 50, 100, 200]
infos = "12345"
speeds = [0.5, 0.4, 0.3, 0.2, 0.1]
ind = bisect(scores, score)
return infos[ind], speeds[ind]
def initBlock(nextBlock=None):
stRow, stCol = -2, 4
nowBlock = nextBlock if nextBlock else newBlock()
nextBlock = newBlock()
return stRow, stCol, nowBlock, nextBlock
def main():
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('俄罗斯方块')
# 初始化当前图形的位置,当前图形,以及下一个图形
stRow, stCol, nowBlock, nextBlock = initBlock()
last_time = time.time()
speed, speedInfo = 0.5, '1'
score, gameOver = 0, False
stopLst = deepcopy(STOP_LST)
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key in [pygame.K_LEFT, pygame.K_RIGHT]:
stCol += moveLR(nowBlock, stCol, event.key)
elif event.key == pygame.K_UP:
rotBlock = rotateBlock(nowBlock)
if canMove(rotBlock, stRow, stCol, stopLst):
nowBlock = rotBlock
elif event.key == pygame.K_DOWN:
# 判断是否可以向下移动,如果碰到底部或者其它的图形就不能移动了
while judgeMoveDown(nowBlock, stRow + 1, stCol, stopLst):
stRow += 1
if gameOver:
stRow, stCol, nowBlock, nextBlock = initBlock()
stopLst = deepcopy(STOP_LST)
score = 0
gameOver = False
# 判断是否修改当前图形显示的起始行
if not gameOver and time.time() - last_time > speed:
last_time = time.time()
# 可以向下移动的情形
if judgeMoveDown(nowBlock, stRow + 1, stCol, stopLst):
stRow += 1
else:
# 不可向下移动,则需新建一个block然后下落
addToStopLst(stopLst, nowBlock, stRow, stCol)
score += judgeLines(stopLst)
gameOver = 1 in stopLst[0] # 第一行中间有1则游戏结束
speedInfo, speed = changeSpeed(score) # 调整速度
stRow, stCol, nowBlock, nextBlock = initBlock(nextBlock)
drawBackground(screen)
drawRight(screen, score, speedInfo)
drawBlocks(screen, nowBlock, stRow*SIZE, stCol*SIZE) # 当前方块
drawBlocks(screen, stopLst, 0, 0) # 堆积方块
drawBlocks(screen, nextBlock, 300, 320) # 下一个方块
# 显示游戏结束画面
if gameOver:
drawGamerOver(screen)
pygame.display.update()
clock.tick(60) # 通过一定的延时,实现1秒钟能够循环60次
if __name__ == '__main__':
main()
微小冷
- 粉丝: 2w+
- 资源: 47
最新资源
- ProvideInjectError解决办法.md
- http故障分析http故障分析PDF
- 基于java+ssm+mysql的素材网站任务书.doc
- NSUrlSessionError如何解决.md
- StopIteration.md
- 基于java+ssm+mysql的图书馆预约占座系统开题报告.doc
- 基于Python实现KNN算法手写数字识别源码+数据 (高分项目)
- 带移栽机构的输送机上料机含工程图sw14可编辑全套技术开发资料100%好用.zip
- 石头迷阵项目文档-破天版.zip
- 电机行业生产线倍速线(含bom工程图)sw18可编辑全套技术开发资料100%好用.zip
- 微信小程序开发框架PDF
- 大杏切分去核机sw17可编辑全套技术开发资料100%好用.zip
- jsonjsonjson11111
- 分布式作业3:使用uDDS之客户端
- 2020宜昌市赛+网络答案.zip
- 二维平面抓取物块动画含动画视频sw18可编辑全套技术开发资料100%好用.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈