一个由tk按钮指令控制的封装成函数的pygame俄罗斯方块小游戏
时间: 2023-06-24 11:04:09 浏览: 95
下面是一个简单的由tk按钮指令控制的封装成函数的pygame俄罗斯方块小游戏:
```python
import pygame
import random
# 初始化pygame
pygame.init()
# 定义游戏窗口大小
WINDOW_WIDTH = 320
WINDOW_HEIGHT = 480
# 定义游戏区域大小
GAME_WIDTH = 10
GAME_HEIGHT = 20
# 定义每个方块的大小
BLOCK_SIZE = 20
# 定义游戏区域左上角坐标
GAME_X = (WINDOW_WIDTH - GAME_WIDTH * BLOCK_SIZE) // 2
GAME_Y = (WINDOW_HEIGHT - GAME_HEIGHT * BLOCK_SIZE) // 2
# 定义方块的颜色
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
CYAN = (0, 255, 255)
MAGENTA = (255, 0, 255)
# 定义方块的形状
BLOCKS = [
[[1, 1], [1, 1]], # 方块
[[1, 0], [1, 0], [1, 1]], # L形块
[[0, 1], [0, 1], [1, 1]], # 反L形块
[[1, 1, 0], [0, 1, 1]], # Z形块
[[0, 1, 1], [1, 1, 0]], # 反Z形块
[[1, 1, 1], [0, 1, 0]], # T形块
[[0, 1, 0], [1, 1, 1]] # I形块
]
# 定义游戏区域
game_area = [[0] * GAME_WIDTH for i in range(GAME_HEIGHT)]
# 定义当前方块
cur_block = None
# 定义下一个方块
next_block = None
# 定义下落速度
speed = 1
# 定义分数
score = 0
# 定义字体
font = pygame.font.SysFont('SimHei', 20)
# 定义游戏窗口
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
# 定义游戏区域的矩形
game_rect = pygame.Rect(GAME_X, GAME_Y, GAME_WIDTH * BLOCK_SIZE, GAME_HEIGHT * BLOCK_SIZE)
# 定义游戏区域的背景色
game_bg_color = (0, 0, 0)
# 定义方块的边框宽度
block_border_width = 2
def get_block():
"""
随机获取一个方块
"""
return random.choice(BLOCKS)
def draw_block(block, x, y, color):
"""
在指定位置绘制一个方块
"""
for i in range(len(block)):
for j in range(len(block[i])):
if block[i][j] == 1:
rect = pygame.Rect(x + j * BLOCK_SIZE, y + i * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE)
pygame.draw.rect(screen, color, rect, 0)
pygame.draw.rect(screen, WHITE, rect, block_border_width)
def draw_game_area():
"""
绘制游戏区域
"""
pygame.draw.rect(screen, game_bg_color, game_rect, 0)
for i in range(GAME_HEIGHT):
for j in range(GAME_WIDTH):
if game_area[i][j] != 0:
color = get_color_by_index(game_area[i][j])
rect = pygame.Rect(GAME_X + j * BLOCK_SIZE, GAME_Y + i * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE)
pygame.draw.rect(screen, color, rect, 0)
pygame.draw.rect(screen, WHITE, rect, block_border_width)
def get_color_by_index(index):
"""
根据方块的索引获取颜色
"""
if index == 1:
return RED
elif index == 2:
return GREEN
elif index == 3:
return BLUE
elif index == 4:
return YELLOW
elif index == 5:
return CYAN
elif index == 6:
return MAGENTA
def can_move_left(block, x, y):
"""
判断方块是否可以向左移动
"""
for i in range(len(block)):
for j in range(len(block[i])):
if block[i][j] == 1:
if x + j <= 0 or game_area[y + i][x + j - 1] != 0:
return False
return True
def can_move_right(block, x, y):
"""
判断方块是否可以向右移动
"""
for i in range(len(block)):
for j in range(len(block[i])):
if block[i][j] == 1:
if x + j >= GAME_WIDTH - 1 or game_area[y + i][x + j + 1] != 0:
return False
return True
def can_move_down(block, x, y):
"""
判断方块是否可以向下移动
"""
for i in range(len(block)):
for j in range(len(block[i])):
if block[i][j] == 1:
if y + i >= GAME_HEIGHT - 1 or game_area[y + i + 1][x + j] != 0:
return False
return True
def add_block_to_game_area(block, x, y):
"""
将方块加入到游戏区域
"""
for i in range(len(block)):
for j in range(len(block[i])):
if block[i][j] == 1:
game_area[y + i][x + j] = cur_block_index
def remove_full_lines():
"""
消除满行
"""
global score
lines = []
for i in range(GAME_HEIGHT):
if 0 not in game_area[i]:
lines.append(i)
for line in lines:
game_area.pop(line)
game_area.insert(0, [0] * GAME_WIDTH)
score += 10 * speed
def game_over():
"""
游戏结束
"""
text = font.render('GAME OVER!', True, (255, 255, 255))
x = (WINDOW_WIDTH - text.get_width()) // 2
y = (WINDOW_HEIGHT - text.get_height()) // 2
screen.blit(text, (x, y))
pygame.display.update()
pygame.time.delay(2000)
def game_loop():
"""
游戏循环
"""
global cur_block, next_block, cur_block_index, speed, score
# 随机获取一个方块作为当前方块
cur_block = next_block or get_block()
cur_block_index = BLOCKS.index(cur_block) + 1
# 随机获取一个方块作为下一个方块
next_block = get_block()
# 初始化方块的位置
x = (GAME_WIDTH - len(cur_block[0])) // 2
y = 0
# 设置游戏循环标志
running = True
# 游戏循环
while running:
# 处理事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT and can_move_left(cur_block, x, y):
x -= 1
elif event.key == pygame.K_RIGHT and can_move_right(cur_block, x, y):
x += 1
elif event.key == pygame.K_DOWN and can_move_down(cur_block, x, y):
y += 1
elif event.key == pygame.K_SPACE:
while can_move_down(cur_block, x, y):
y += 1
# 判断方块是否可以向下移动
if can_move_down(cur_block, x, y):
y += 1
else:
# 将方块加入到游戏区域
add_block_to_game_area(cur_block, x, y)
# 消除满行
remove_full_lines()
# 判断游戏是否结束
if game_area[0][GAME_WIDTH // 2] != 0:
game_over()
running = False
break
# 随机获取一个方块作为当前方块
cur_block = next_block
cur_block_index = BLOCKS.index(cur_block) + 1
# 随机获取一个方块作为下一个方块
next_block = get_block()
# 初始化方块的位置
x = (GAME_WIDTH - len(cur_block[0])) // 2
y = 0
# 绘制游戏区域
draw_game_area()
# 绘制当前方块
draw_block(cur_block, GAME_X + x * BLOCK_SIZE, GAME_Y + y * BLOCK_SIZE, get_color_by_index(cur_block_index))
# 绘制下一个方块
draw_block(next_block, GAME_X + GAME_WIDTH * BLOCK_SIZE + BLOCK_SIZE, GAME_Y + BLOCK_SIZE, get_color_by_index(BLOCKS.index(next_block) + 1))
# 绘制分数
score_text = font.render('Score: ' + str(score), True, (255, 255, 255))
screen.blit(score_text, (20, 20))
# 刷新屏幕
pygame.display.update()
# 设置游戏帧率
pygame.time.Clock().tick(30 * speed)
def start_game():
"""
开始游戏
"""
global game_area, score
game_area = [[0] * GAME_WIDTH for i in range(GAME_HEIGHT)]
score = 0
game_loop()
# 定义开始游戏按钮的回调函数
def start_game_callback():
start_game()
# 创建开始游戏按钮
start_button = tkinter.Button(text='开始游戏', command=start_game_callback)
start_button.pack()
# 进入主循环
pygame.display.set_caption('俄罗斯方块')
pygame.display.set_icon(pygame.image.load('icon.png'))
pygame.display.flip()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
pygame.display.update()
```
在上面的代码中,我们使用了一个`tkinter`按钮来控制游戏的开始和结束。当点击开始游戏按钮时,调用`start_game_callback`函数开始游戏。在游戏循环中,我们使用了`pygame.time.Clock().tick()`函数来控制游戏的帧率,从而控制游戏的速度。同时,我们还定义了一些函数来处理游戏逻辑,如获取方块、绘制方块、判断方块是否可以移动、将方块加入到游戏区域、消除满行、判断游戏是否结束等。最后,在游戏结束时,我们使用了`pygame.time.delay()`函数来延迟2秒,以便玩家能够看到游戏结束的提示。
阅读全文