You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

728 lines
28 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import math, pygame, sys, copy, random
import pygame.gfxdraw
from pygame.locals import *
# 定义游戏的常量
FPS = 120 #帧率
WINDOWWIDTH = 640 #窗口宽度
WINDOWHEIGHT = 480 # 窗口高度
TEXTHEIGHT = 20 # 文本高度
BUBBLERADIUS = 20 # 泡泡半径
BUBBLEWIDTH = BUBBLERADIUS * 2 # 泡泡宽度
BUBBLELAYERS = 5 # 泡泡层数
BUBBLEYADJUST = 5 # 泡泡垂直调整
STARTX = WINDOWWIDTH / 2 # 开始 X 坐标
STARTY = WINDOWHEIGHT - 27 # 开始 Y 坐标
ARRAYWIDTH = 16 # 数组宽度
ARRAYHEIGHT = 14 # 数组高度
# 定义左右移动的常量
RIGHT = 'right'
LEFT = 'left'
BLANK = '.' # 空白符号
## COLORS ##
# 定义颜色常量
#RGB
# 每个元组代表一种颜色,格式为 (红, 绿, 蓝)
GRAY = (100, 100, 100)
NAVYBLUE = (60, 60, 100)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
ORANGE = (255, 128, 0)
PURPLE = (255, 0, 255)
CYAN = (0, 255, 255)
BLACK = (0, 0, 0)
COMBLUE = (233, 232, 255)
BGCOLOR = WHITE #背景颜色
COLORLIST = [RED, GREEN, BLUE, YELLOW, ORANGE, PURPLE, CYAN] #泡泡颜色列表
# 定义泡泡类继承自pygame.sprite.Sprite
class Bubble(pygame.sprite.Sprite):
def __init__(self, color, row=0, column=0):
pygame.sprite.Sprite.__init__(self)
# 初始化泡泡属性
self.rect = pygame.Rect(0, 0, 30, 30) #创建了一个表示气泡的矩形区域,初始位置在(0, 0)宽和高都是30像素。
self.rect.centerx = STARTX
self.rect.centery = STARTY
self.speed = 10
self.color = color
self.radius = BUBBLERADIUS
self.angle = 0
self.row = row
self.column = column
# 更新泡泡位置的方法
def update(self):
global xmove, ymove
if self.angle == 90:
xmove = 0
ymove = self.speed * -1
elif self.angle < 90:
xmove = self.xcalculate(self.angle)
ymove = self.ycalculate(self.angle)
elif self.angle > 90:
xmove = self.xcalculate(180 - self.angle) * -1
ymove = self.ycalculate(180 - self.angle)
self.rect.x += xmove
self.rect.y += ymove
# 绘制泡泡的方法
def draw(self):
pygame.gfxdraw.filled_circle(DISPLAYSURF, self.rect.centerx, self.rect.centery, self.radius, self.color)
pygame.gfxdraw.aacircle(DISPLAYSURF, self.rect.centerx, self.rect.centery, self.radius, GRAY)
# 计算X轴移动距离的方法
def xcalculate(self, angle):
radians = math.radians(angle)
xmove = math.cos(radians) * (self.speed)
return xmove
# 计算Y轴移动距离的方法
def ycalculate(self, angle):
radians = math.radians(angle)
ymove = math.sin(radians) * (self.speed) * -1
return ymove
# 定义箭头类继承自pygame.sprite.Sprite
class Arrow(pygame.sprite.Sprite):
# 初始化箭头属性
def __init__(self):
"""
初始化箭头对象。
该方法对箭头对象进行初始化,包括加载箭头图像、设置初始角度、确定箭头在屏幕上的初始位置。
"""
# 调用父类pygame.sprite.Sprite的初始化方法
pygame.sprite.Sprite.__init__(self)
self.angle = 90 # 将箭头的初始角度设置为90度指向正上方
# 加载箭头图像并进行透明处理
arrowImage = pygame.image.load('Arrow.png')
arrowImage.convert_alpha()
# 获取箭头图像的矩形区域
arrowRect = arrowImage.get_rect()
self.image = arrowImage # 将处理后的图像赋值给箭头对象的image属性
self.transformImage = self.image # 初始化transformImage为箭头的初始图像
self.rect = arrowRect # 将图像的矩形区域赋值给箭头对象的rect属性
# 设置箭头在屏幕上的初始位置
self.rect.centerx = STARTX
self.rect.centery = STARTY
# 更新箭头方向的方法
def update(self, direction):
if direction == LEFT and self.angle < 176:
self.angle += 2 # 如果按下左箭头键且当前角度小于180度则增加角度
elif direction == RIGHT and self.angle > 4:
self.angle -= 2 # 如果按下右箭头键且当前角度大于0度则减少角度
self.transformImage = pygame.transform.rotate(self.image, self.angle)
self.rect = self.transformImage.get_rect()
self.rect.centerx = STARTX # 保持箭头在水平中心位置
self.rect.centery = STARTY # 保持箭头在垂直起始位置
# 绘制箭头的方法
def draw(self):
DISPLAYSURF.blit(self.transformImage, self.rect)
# 定义分数类
class Score(object):
def __init__(self):
self.total = 0
self.font = pygame.font.SysFont('Helvetica', 15)
self.render = self.font.render('Score: ' + str(self.total), True, BLACK, WHITE)
self.rect = self.render.get_rect()
self.rect.left = 5
self.rect.bottom = WINDOWHEIGHT - 5
# 更新分数的方法
def update(self, deleteList):
self.total += ((len(deleteList)) * 10)
self.render = self.font.render('Score: ' + str(self.total), True, BLACK, WHITE)
# 绘制分数的方法
def draw(self):
DISPLAYSURF.blit(self.render, self.rect)
# 主函数
def main():
global FPSCLOCK, DISPLAYSURF, DISPLAYRECT, MAINFONT # 引用全局变量
pygame.init() # 初始化Pygame
FPSCLOCK = pygame.time.Clock() # 创建一个时钟对象,用于控制游戏帧率
pygame.display.set_caption('泡泡天堂小游戏') # 设置游戏窗口标题
MAINFONT = pygame.font.SysFont('Helvetica', TEXTHEIGHT) # 设置游戏使用的默认字体
DISPLAYSURF, DISPLAYRECT = makeDisplay() # 创建游戏显示的表面和矩形
while True: # 进入游戏主循环
score, winorlose = runGame() # 运行游戏,返回得分和游戏结果
endScreen(score, winorlose) # 显示游戏结束画面
# 运行游戏的函数
def runGame():
# 初始化音乐列表
musicList = ['知更鸟 _ HOYO-MiX _ Chevy - 使一颗心免于哀伤.ogg', '知更鸟 _ HOYO-MiX _ Chevy - 希望有羽毛和翅膀.ogg',
'知更鸟 _ HOYO-MiX _ Chevy - 在银河中孤独摇摆.ogg']
pygame.mixer.music.load(musicList[0])
pygame.mixer.music.play()
track = 0 # 音乐曲目索引
# 初始化游戏颜色列表和游戏颜色数组
gameColorList = copy.deepcopy(COLORLIST)
direction = None # 玩家控制的方向
launchBubble = False # 是否发射气泡
newBubble = None # 将要发射或正在移动的气泡
# 初始化箭头、游戏面板(气泡数组)和得分
arrow = Arrow()
bubbleArray = makeBlankBoard()
setBubbles(bubbleArray, gameColorList)
nextBubble = Bubble(gameColorList[0]) # 下一个要发射的气泡
nextBubble.rect.right = WINDOWWIDTH - 5
nextBubble.rect.bottom = WINDOWHEIGHT - 5
score = Score()
while True:
DISPLAYSURF.fill(BGCOLOR) # 填充游戏背景
# 处理事件:退出、按键等
for event in pygame.event.get():
if event.type == QUIT:
terminate()
elif event.type == KEYDOWN:
if (event.key == K_LEFT):
direction = LEFT
elif (event.key == K_RIGHT):
direction = RIGHT
elif event.type == KEYUP:
direction = None
if event.key == K_SPACE:
launchBubble = True
elif event.key == K_ESCAPE:
terminate()
# 如果按下发射气泡的按键
if launchBubble == True:
if newBubble == None:
newBubble = Bubble(nextBubble.color)
newBubble.angle = arrow.angle
newBubble.update()
newBubble.draw()
# 反转气泡下落方向
if newBubble.rect.right >= WINDOWWIDTH - 5:
newBubble.angle = 180 - newBubble.angle
elif newBubble.rect.left <= 5:
newBubble.angle = 180 - newBubble.angle
# 处理气泡发射和消除逻辑
launchBubble, newBubble, score = stopBubble(bubbleArray, newBubble, launchBubble, score)
# 检查游戏是否结束
finalBubbleList = []
for row in range(len(bubbleArray)):
for column in range(len(bubbleArray[0])):
if bubbleArray[row][column] != BLANK:
finalBubbleList.append(bubbleArray[row][column])
if bubbleArray[row][column].rect.bottom > (WINDOWHEIGHT - arrow.rect.height - 10):
return score.total, 'lose'
# 游戏胜利条件检查
if len(finalBubbleList) < 1:
return score.total, 'win'
# 更新游戏颜色列表并随机排序
gameColorList = updateColorList(bubbleArray)
random.shuffle(gameColorList)
# 重置下一个要发射的气泡
if launchBubble == False:
nextBubble = Bubble(gameColorList[0])
nextBubble.rect.right = WINDOWWIDTH - 5
nextBubble.rect.bottom = WINDOWHEIGHT - 5
# 绘制游戏元素
nextBubble.draw()
if launchBubble == True:
coverNextBubble() # 遮挡下一个气泡
arrow.update(direction) # 更新箭头方向
arrow.draw() # 绘制箭头
setArrayPos(bubbleArray) # 更新气泡数组位置
drawBubbleArray(bubbleArray) # 绘制气泡数组
score.draw() # 绘制得分
# 切换音乐
if pygame.mixer.music.get_busy() == False:
if track == len(musicList) - 1:
track = 0
else:
track += 1
pygame.mixer.music.load(musicList[track])
pygame.mixer.music.play()
pygame.display.update()
FPSCLOCK.tick(FPS) # 控制游戏帧率
# 创建空白游戏板的函数
def makeBlankBoard():
array = [] # 初始化一个空的一维列表,用于存放棋盘的每一行
# 循环创建ARRAYHEIGHT行
for row in range(ARRAYHEIGHT):
column = [] # 初始化一个空的一维列表,用于存放当前行的列
# 循环创建ARRAYWIDTH列每列都初始化为BLANK
for i in range(ARRAYWIDTH):
column.append(BLANK)
array.append(column) # 将当前行的列添加到棋盘数组中
return array # 返回创建好的空棋盘
# 在游戏板上设置泡泡的函数
def setBubbles(array, gameColorList):
for row in range(BUBBLELAYERS): # 遍历气泡层数
for column in range(len(array[row])): # 遍历每一层的气泡列数
random.shuffle(gameColorList) # 随机重洗颜色列表
newBubble = Bubble(gameColorList[0], row, column) # 创建新的气泡对象
array[row][column] = newBubble # 将新的气泡对象设置到对应的位置
setArrayPos(array) # 更新气泡数组的位置信息
# 设置游戏板上泡泡位置的函数def setArrayPos(array):
# 初始化元素位置
for row in range(ARRAYHEIGHT):
for column in range(len(array[row])):
if array[row][column] != BLANK:
array[row][column].rect.x = (BUBBLEWIDTH * column) + 5
array[row][column].rect.y = (BUBBLEWIDTH * row) + 5
# 调整奇数行元素的 x 坐标
for row in range(1, ARRAYHEIGHT, 2):
for column in range(len(array[row])):
if array[row][column] != BLANK:
array[row][column].rect.x += BUBBLERADIUS
# 调整所有行元素的 y 坐标
for row in range(1, ARRAYHEIGHT):
for column in range(len(array[row])):
if array[row][column] != BLANK:
array[row][column].rect.y -= (BUBBLEYADJUST * row)
# 删除多余气泡
deleteExtraBubbles(array)
#设置游戏板上泡泡位置的函数
def setArrayPos(array):
# 初始化元素位置
for row in range(ARRAYHEIGHT):
for column in range(len(array[row])):
if array[row][column] != BLANK:
array[row][column].rect.x = (BUBBLEWIDTH * column) + 5
array[row][column].rect.y = (BUBBLEWIDTH * row) + 5
# 调整奇数行元素的 x 坐标
for row in range(1, ARRAYHEIGHT, 2):
for column in range(len(array[row])):
if array[row][column] != BLANK:
array[row][column].rect.x += BUBBLERADIUS
# 调整所有行元素的 y 坐标
for row in range(1, ARRAYHEIGHT):
for column in range(len(array[row])):
if array[row][column] != BLANK:
array[row][column].rect.y -= (BUBBLEYADJUST * row)
# 删除多余气泡
deleteExtraBubbles(array)
#(删除超出游戏区域的泡泡)
def deleteExtraBubbles(array):
for row in range(ARRAYHEIGHT): # 遍历每一行
for column in range(len(array[row])): # 遍历当前行的每个元素
# 如果当前元素不为空
if array[row][column] != BLANK:
# 如果气泡的右边界超出窗口宽度
if array[row][column].rect.right > WINDOWWIDTH:
# 将该气泡设置为空
array[row][column] = BLANK
# 更新颜色列表的函数
def updateColorList(bubbleArray):
newColorList = []
# 遍历气泡数组,将非空气泡的颜色添加到新颜色列表中
for row in range(len(bubbleArray)):
for column in range(len(bubbleArray[0])):
if bubbleArray[row][column] != BLANK:
newColorList.append(bubbleArray[row][column].color)
colorSet = set(newColorList) # 使用集合去重
# 如果集合为空,说明气泡数组中没有非空气泡,返回包含白色的列表
if len(colorSet) < 1:
colorList = []
colorList.append(WHITE)
return colorList
else:
return list(colorSet) # 返回去重后的颜色列表
#(检查孤立泡泡)
def checkForFloaters(bubbleArray):
# 遍历数组第一行找出非空列的索引存储到bubbleList中
bubbleList = [column for column in range(len(bubbleArray[0]))
if bubbleArray[0][column] != BLANK]
newBubbleList = []
# 筛选出bubbleList中需要处理的列即数值间隔大于1的列
for i in range(len(bubbleList)):
if i == 0:
newBubbleList.append(bubbleList[i])
elif bubbleList[i] > bubbleList[i - 1] + 1:
newBubbleList.append(bubbleList[i])
# 深拷贝bubbleArray以用于后续操作避免修改原数组
copyOfBoard = copy.deepcopy(bubbleArray)
# 清空原数组中的所有元素,准备进行浮选物处理
for row in range(len(bubbleArray)):
for column in range(len(bubbleArray[0])):
bubbleArray[row][column] = BLANK
# 对需要处理的列调用popFloaters函数进行浮选物处理
for column in newBubbleList:
popFloaters(bubbleArray, copyOfBoard, column)
def popFloaters(bubbleArray, copyOfBoard, column, row=0):
if (row < 0 or row > (len(bubbleArray) - 1)
or column < 0 or column > (len(bubbleArray[0]) - 1)):
return
elif copyOfBoard[row][column] == BLANK:
return
elif bubbleArray[row][column] == copyOfBoard[row][column]:
return
bubbleArray[row][column] = copyOfBoard[row][column]
if row == 0:
popFloaters(bubbleArray, copyOfBoard, column + 1, row)
popFloaters(bubbleArray, copyOfBoard, column - 1, row)
popFloaters(bubbleArray, copyOfBoard, column, row + 1)
popFloaters(bubbleArray, copyOfBoard, column - 1, row + 1)
elif row % 2 == 0:
popFloaters(bubbleArray, copyOfBoard, column + 1, row)
popFloaters(bubbleArray, copyOfBoard, column - 1, row)
popFloaters(bubbleArray, copyOfBoard, column, row + 1)
popFloaters(bubbleArray, copyOfBoard, column - 1, row + 1)
popFloaters(bubbleArray, copyOfBoard, column, row - 1)
popFloaters(bubbleArray, copyOfBoard, column - 1, row - 1)
else:
popFloaters(bubbleArray, copyOfBoard, column + 1, row)
popFloaters(bubbleArray, copyOfBoard, column - 1, row)
popFloaters(bubbleArray, copyOfBoard, column, row + 1)
popFloaters(bubbleArray, copyOfBoard, column + 1, row + 1)
popFloaters(bubbleArray, copyOfBoard, column, row - 1)
popFloaters(bubbleArray, copyOfBoard, column + 1, row - 1)
# 这个函数处理泡泡停止时的逻辑,包括判断泡泡是否到达了发射的终点,以及是否与其它泡泡发生碰撞。
def stopBubble(bubbleArray, newBubble, launchBubble, score):
global newRow, newColumn
deleteList = [] # 用于存储需要消除的气泡位置
popSound = pygame.mixer.Sound('popcork.ogg') # 播放气泡消除音效
# 遍历气泡数组,检查新气泡与现有气泡的碰撞
for row in range(len(bubbleArray)):
for column in range(len(bubbleArray[row])):
# 如果当前位置有气泡,并且有新气泡即将落下
if (bubbleArray[row][column] != BLANK and newBubble != None):
# 检查新气泡是否与当前气泡碰撞,或者是否已经越界
if (pygame.sprite.collide_rect(newBubble, bubbleArray[row][column])) or newBubble.rect.top < 0:
# 如果新气泡越界,则把它添加到上方
if newBubble.rect.top < 0:
newRow, newColumn = addBubbleToTop(bubbleArray, newBubble)
# 检查新气泡与当前气泡的中心是否在同一垂直线上
elif newBubble.rect.centery >= bubbleArray[row][column].rect.centery:
# 向上或向下移动新气泡,并考虑奇偶行的规则
if newBubble.rect.centerx >= bubbleArray[row][column].rect.centerx:
if row == 0 or (row) % 2 == 0:
newRow = row + 1
newColumn = column
# 如果目标位置已有气泡,则向上移动一行
if bubbleArray[newRow][newColumn] != BLANK:
newRow = newRow - 1
bubbleArray[newRow][newColumn] = copy.copy(newBubble)
bubbleArray[newRow][newColumn].row = newRow
bubbleArray[newRow][newColumn].column = newColumn
else:
newRow = row + 1
newColumn = column + 1
if bubbleArray[newRow][newColumn] != BLANK:
newRow = newRow - 1
bubbleArray[newRow][newColumn] = copy.copy(newBubble)
bubbleArray[newRow][newColumn].row = newRow
bubbleArray[newRow][newColumn].column = newColumn
# 向左或向右移动新气泡,并考虑奇偶行的规则
elif newBubble.rect.centerx < bubbleArray[row][column].rect.centerx:
if row == 0 or row % 2 == 0:
newRow = row + 1
newColumn = column - 1
if newColumn < 0:
newColumn = 0
if bubbleArray[newRow][newColumn] != BLANK:
newRow = newRow - 1
bubbleArray[newRow][newColumn] = copy.copy(newBubble)
bubbleArray[newRow][newColumn].row = newRow
bubbleArray[newRow][newColumn].column = newColumn
else:
newRow = row + 1
newColumn = column
if bubbleArray[newRow][newColumn] != BLANK:
newRow = newRow - 1
bubbleArray[newRow][newColumn] = copy.copy(newBubble)
bubbleArray[newRow][newColumn].row = newRow
bubbleArray[newRow][newColumn].column = newColumn
# 检查新气泡与当前气泡的中心是否在同一水平线上
elif newBubble.rect.centery < bubbleArray[row][column].rect.centery:
# 向上或向下移动新气泡,并考虑奇偶行的规则
if newBubble.rect.centerx >= bubbleArray[row][column].rect.centerx:
if row == 0 or row % 2 == 0:
newRow = row - 1
newColumn = column
if bubbleArray[newRow][newColumn] != BLANK:
newRow = newRow + 1
bubbleArray[newRow][newColumn] = copy.copy(newBubble)
bubbleArray[newRow][newColumn].row = newRow
bubbleArray[newRow][newColumn].column = newColumn
else:
newRow = row - 1
newColumn = column + 1
if bubbleArray[newRow][newColumn] != BLANK:
newRow = newRow + 1
bubbleArray[newRow][newColumn] = copy.copy(newBubble)
bubbleArray[newRow][newColumn].row = newRow
bubbleArray[newRow][newColumn].column = newColumn
# 向左或向右移动新气泡,并考虑奇偶行的规则
elif newBubble.rect.centerx <= bubbleArray[row][column].rect.centerx:
if row == 0 or row % 2 == 0:
newRow = row - 1
newColumn = column - 1
if bubbleArray[newRow][newColumn] != BLANK:
newRow = newRow + 1
bubbleArray[newRow][newColumn] = copy.copy(newBubble)
bubbleArray[newRow][newColumn].row = newRow
bubbleArray[newRow][newColumn].column = newColumn
else:
newRow = row - 1
newColumn = column
if bubbleArray[newRow][newColumn] != BLANK:
newRow = newRow + 1
bubbleArray[newRow][newColumn] = copy.copy(newBubble)
bubbleArray[newRow][newColumn].row = newRow
bubbleArray[newRow][newColumn].column = newColumn
# 消除选中的气泡,并处理连消和得分
popBubbles(bubbleArray, newRow, newColumn, newBubble.color, deleteList)
# 如果消除的气泡数量达到3个或以上播放音效、更新布局和得分
if len(deleteList) >= 3:
for pos in deleteList:
popSound.play()
row = pos[0]
column = pos[1]
bubbleArray[row][column] = BLANK
checkForFloaters(bubbleArray)
score.update(deleteList)
# 更新发射状态和新气泡为None
launchBubble = False
newBubble = None
return launchBubble, newBubble, score
def addBubbleToTop(bubbleArray, bubble):
# 获取气泡中心的x坐标并计算气泡左侧边界的x坐标
posx = bubble.rect.centerx
leftSidex = posx - BUBBLERADIUS
# 根据气泡左侧边界的位置计算其所在的列
columnDivision = math.modf(float(leftSidex) / float(BUBBLEWIDTH))
column = int(columnDivision[1])
# 判断气泡应该添加到当前列还是下一列
if columnDivision[0] < 0.5:
bubbleArray[0][column] = copy.copy(bubble)
else:
column += 1
bubbleArray[0][column] = copy.copy(bubble)
# 设置行索引为0因为气泡被添加到数组顶部
row = 0
return row, column
#这个函数递归地查找并消除连接的同色泡泡。
def popBubbles(bubbleArray, row, column, color, deleteList):
# 检查索引是否越界
if row < 0 or column < 0 or row > (len(bubbleArray) - 1) or column > (len(bubbleArray[0]) - 1):
return
# 检查当前位置是否为空或颜色不匹配
elif bubbleArray[row][column] == BLANK:
return
elif bubbleArray[row][column].color != color:
return
# 如果气泡颜色匹配,但已在删除列表中,则不处理
for bubble in deleteList:
if bubbleArray[bubble[0]][bubble[1]] == bubbleArray[row][column]:
return
# 将当前气泡加入删除列表
deleteList.append((row, column))
# 递归消除相邻的气泡
# 处理顶部行或底部行的逻辑
if row == 0:
popBubbles(bubbleArray, row, column - 1, color, deleteList)
popBubbles(bubbleArray, row, column + 1, color, deleteList)
popBubbles(bubbleArray, row + 1, column, color, deleteList)
popBubbles(bubbleArray, row + 1, column - 1, color, deleteList)
# 处理中间行的逻辑,奇数行和偶数行处理方式略有不同
elif row % 2 == 0:
popBubbles(bubbleArray, row + 1, column, color, deleteList)
popBubbles(bubbleArray, row + 1, column - 1, color, deleteList)
popBubbles(bubbleArray, row - 1, column, color, deleteList)
popBubbles(bubbleArray, row - 1, column - 1, color, deleteList)
popBubbles(bubbleArray, row, column + 1, color, deleteList)
popBubbles(bubbleArray, row, column - 1, color, deleteList)
else:
popBubbles(bubbleArray, row - 1, column, color, deleteList)
popBubbles(bubbleArray, row - 1, column + 1, color, deleteList)
popBubbles(bubbleArray, row + 1, column, color, deleteList)
popBubbles(bubbleArray, row + 1, column + 1, color, deleteList)
popBubbles(bubbleArray, row, column + 1, color, deleteList)
popBubbles(bubbleArray, row, column - 1, color, deleteList)
def drawBubbleArray(array):
for row in range(ARRAYHEIGHT):
for column in range(len(array[row])):
if array[row][column] != BLANK:
array[row][column].draw()
def makeDisplay():
# 创建显示表面并获取其矩形区域
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
DISPLAYRECT = DISPLAYSURF.get_rect()
# 填充显示表面的背景色
DISPLAYSURF.fill(BGCOLOR)
# 转换显示表面的格式以优化性能
DISPLAYSURF.convert()
# 更新显示内容
pygame.display.update()
return DISPLAYSURF, DISPLAYRECT
# 退出游戏的函数
def terminate():
pygame.quit()
sys.exit()
# 遮盖下一个泡泡的函数
def coverNextBubble():
# 初始化一个白色矩形,位置在窗口的右下角
whiteRect = pygame.Rect(0, 0, BUBBLEWIDTH, BUBBLEWIDTH)
whiteRect.bottom = WINDOWHEIGHT
whiteRect.right = WINDOWWIDTH
# 在显示表面绘制矩形
pygame.draw.rect(DISPLAYSURF, BGCOLOR, whiteRect)
# 游戏结束屏幕的函数
def endScreen(score, winorlose):
# 初始化游戏结束信息的字体和内容
endFont = pygame.font.SysFont('Helvetica', 20)
endMessage1 = endFont.render('You ' + winorlose + '! Your Score is ' + str(score) + '. Press Enter to Play Again.',
True, BLACK, BGCOLOR)
endMessage1Rect = endMessage1.get_rect()
endMessage1Rect.center = DISPLAYRECT.center # 将结束信息居中显示
# 清空显示屏幕并绘制结束信息
DISPLAYSURF.fill(BGCOLOR)
DISPLAYSURF.blit(endMessage1, endMessage1Rect)
pygame.display.update()
# 等待玩家按键选择重新开始或退出游戏
while True:
for event in pygame.event.get():
if event.type == QUIT: # 如果检测到退出事件,则终止游戏
terminate()
elif event.type == KEYUP: # 如果检测到按键事件
if event.key == K_RETURN: # 如果玩家按下回车键,则返回主游戏循环
return
elif event.key == K_ESCAPE: # 如果玩家按下Esc键则终止游戏
terminate()
if __name__ == '__main__':
main()