欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 社会 > Pygame第10课——俄罗斯方块

Pygame第10课——俄罗斯方块

2025/4/1 3:37:46 来源:https://blog.csdn.net/weixin_42636075/article/details/146106097  浏览:    关键词:Pygame第10课——俄罗斯方块

Pygame基础专栏目录

  • 专栏导读
  • 完整代码
  • 总结

在这里插入图片描述

专栏导读

  • 🌸 欢迎来到Pygame基础专栏—大家可以在这里学习pygame基础知识

  • 🏳️‍🌈 博客主页:请点击——> 一晌小贪欢的博客主页

  • 👍 该系列文章专栏:请点击——>Pygame基础专栏

  • 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏

  • ❤️ 欢迎各位佬关注! ❤️

完整代码

import pygame
import random
import time# 初始化pygame
pygame.init()# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
CYAN = (0, 255, 255)
BLUE = (0, 0, 255)
ORANGE = (255, 165, 0)
YELLOW = (255, 255, 0)
GREEN = (0, 255, 0)
PURPLE = (128, 0, 128)
RED = (255, 0, 0)# 游戏设置
BLOCK_SIZE = 30
GRID_WIDTH = 10
GRID_HEIGHT = 20
SCREEN_WIDTH = BLOCK_SIZE * (GRID_WIDTH + 8)
SCREEN_HEIGHT = BLOCK_SIZE * GRID_HEIGHT
GAME_AREA_LEFT = BLOCK_SIZE * 4
GAME_AREA_TOP = 0# 方块形状定义
SHAPES = [[[1, 1, 1, 1]],  # I[[1, 1], [1, 1]],  # O[[1, 1, 1], [0, 1, 0]],  # T[[1, 1, 1], [1, 0, 0]],  # L[[1, 1, 1], [0, 0, 1]],  # J[[0, 1, 1], [1, 1, 0]],  # S[[1, 1, 0], [0, 1, 1]]  # Z
]# 方块颜色
SHAPE_COLORS = [CYAN, YELLOW, PURPLE, ORANGE, BLUE, GREEN, RED]# 创建游戏窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("俄罗斯方块")# 游戏时钟
clock = pygame.time.Clock()class Tetromino:def __init__(self):self.shape_index = random.randint(0, len(SHAPES) - 1)self.shape = SHAPES[self.shape_index]self.color = SHAPE_COLORS[self.shape_index]self.x = GRID_WIDTH // 2 - len(self.shape[0]) // 2self.y = 0def rotate(self):# 旋转方块rows = len(self.shape)cols = len(self.shape[0])rotated = [[0 for _ in range(rows)] for _ in range(cols)]for r in range(rows):for c in range(cols):rotated[c][rows - 1 - r] = self.shape[r][c]return rotateddef draw(self, surface):for y, row in enumerate(self.shape):for x, cell in enumerate(row):if cell:rect = pygame.Rect(GAME_AREA_LEFT + (self.x + x) * BLOCK_SIZE,GAME_AREA_TOP + (self.y + y) * BLOCK_SIZE,BLOCK_SIZE, BLOCK_SIZE)pygame.draw.rect(surface, self.color, rect)pygame.draw.rect(surface, WHITE, rect, 1)class TetrisGame:def __init__(self):# 绘制下一个方块预览self.font = pygame.font.SysFont('simhei', 13)self.grid = [[0 for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]self.current_piece = Tetromino()self.next_piece = Tetromino()self.game_over = Falseself.score = 0self.level = 1self.lines_cleared = 0self.fall_time = 0self.fall_speed = 0.5  # 初始下落速度(秒)self.last_fall_time = time.time()def draw_grid(self, surface):# 绘制游戏区域背景pygame.draw.rect(surface, BLACK, (GAME_AREA_LEFT, GAME_AREA_TOP,GRID_WIDTH * BLOCK_SIZE,GRID_HEIGHT * BLOCK_SIZE))# 绘制网格线for x in range(GRID_WIDTH + 1):pygame.draw.line(surface, WHITE,(GAME_AREA_LEFT + x * BLOCK_SIZE, GAME_AREA_TOP),(GAME_AREA_LEFT + x * BLOCK_SIZE, GAME_AREA_TOP + GRID_HEIGHT * BLOCK_SIZE))for y in range(GRID_HEIGHT + 1):pygame.draw.line(surface, WHITE,(GAME_AREA_LEFT, GAME_AREA_TOP + y * BLOCK_SIZE),(GAME_AREA_LEFT + GRID_WIDTH * BLOCK_SIZE, GAME_AREA_TOP + y * BLOCK_SIZE))# 绘制已放置的方块for y in range(GRID_HEIGHT):for x in range(GRID_WIDTH):if self.grid[y][x]:color_idx = self.grid[y][x] - 1rect = pygame.Rect(GAME_AREA_LEFT + x * BLOCK_SIZE,GAME_AREA_TOP + y * BLOCK_SIZE,BLOCK_SIZE, BLOCK_SIZE)pygame.draw.rect(surface, SHAPE_COLORS[color_idx], rect)pygame.draw.rect(surface, WHITE, rect, 1)def draw_info(self, surface):# 绘制信息区域背景info_area = pygame.Rect(0, 0, GAME_AREA_LEFT, SCREEN_HEIGHT)pygame.draw.rect(surface, (50, 50, 50), info_area)next_text = self.font.render("下一个:", True, WHITE)surface.blit(next_text, (20, 20))# 绘制下一个方块next_piece_surface = pygame.Surface((len(self.next_piece.shape[0]) * BLOCK_SIZE,len(self.next_piece.shape) * BLOCK_SIZE))next_piece_surface.fill((50, 50, 50))for y, row in enumerate(self.next_piece.shape):for x, cell in enumerate(row):if cell:rect = pygame.Rect(x * BLOCK_SIZE,y * BLOCK_SIZE,BLOCK_SIZE, BLOCK_SIZE)pygame.draw.rect(next_piece_surface, self.next_piece.color, rect)pygame.draw.rect(next_piece_surface, WHITE, rect, 1)surface.blit(next_piece_surface, (20, 60))# 绘制分数score_text = self.font.render(f"分数: {self.score}", True, WHITE)surface.blit(score_text, (20, 180))# 绘制等级level_text = self.font.render(f"等级: {self.level}", True, WHITE)surface.blit(level_text, (20, 220))# 绘制已消除行数lines_text = self.font.render(f"消除行: {self.lines_cleared}", True, WHITE)surface.blit(lines_text, (20, 260))# 绘制操作说明controls_text = ["操作说明:","←→: 左右移动","↑: 旋转","↓: 加速下落","空格: 直接落下","P: 暂停游戏","R: 重新开始"]for i, text in enumerate(controls_text):ctrl_text = self.font.render(text, True, WHITE)surface.blit(ctrl_text, (20, 320 + i * 30))def draw_game_over(self, surface):overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))overlay.set_alpha(150)overlay.fill(BLACK)surface.blit(overlay, (0, 0))font = pygame.font.SysFont(None, 50)game_over_text = self.font.render("游戏结束!", True, WHITE)restart_text = self.font.render("按R键重新开始", True, WHITE)surface.blit(game_over_text,(SCREEN_WIDTH // 2 - game_over_text.get_width() // 2,SCREEN_HEIGHT // 2 - 50))surface.blit(restart_text,(SCREEN_WIDTH // 2 - restart_text.get_width() // 2,SCREEN_HEIGHT // 2 + 10))def is_collision(self, shape, x, y):for row_idx, row in enumerate(shape):for col_idx, cell in enumerate(row):if cell:# 检查是否超出边界if (x + col_idx < 0 or x + col_idx >= GRID_WIDTH ory + row_idx >= GRID_HEIGHT):return True# 检查是否与已放置的方块重叠if y + row_idx >= 0 and self.grid[y + row_idx][x + col_idx]:return Truereturn Falsedef merge_piece(self):# 将当前方块合并到网格中for y, row in enumerate(self.current_piece.shape):for x, cell in enumerate(row):if cell and 0 <= self.current_piece.y + y < GRID_HEIGHT:self.grid[self.current_piece.y + y][self.current_piece.x + x] = self.current_piece.shape_index + 1def clear_lines(self):lines_to_clear = []for y in range(GRID_HEIGHT):if all(self.grid[y]):lines_to_clear.append(y)for line in lines_to_clear:del self.grid[line]self.grid.insert(0, [0 for _ in range(GRID_WIDTH)])# 更新分数和等级if lines_to_clear:self.lines_cleared += len(lines_to_clear)self.score += [100, 300, 500, 800][min(len(lines_to_clear) - 1, 3)] * self.levelself.level = min(10, 1 + self.lines_cleared // 10)self.fall_speed = max(0.05, 0.5 - (self.level - 1) * 0.05)return len(lines_to_clear)def move(self, dx, dy):if not self.is_collision(self.current_piece.shape,self.current_piece.x + dx,self.current_piece.y + dy):self.current_piece.x += dxself.current_piece.y += dyreturn Truereturn Falsedef rotate_piece(self):rotated = self.current_piece.rotate()if not self.is_collision(rotated, self.current_piece.x, self.current_piece.y):self.current_piece.shape = rotatedreturn True# 尝试墙踢(wall kick)for dx in [-1, 1, -2, 2]:if not self.is_collision(rotated, self.current_piece.x + dx, self.current_piece.y):self.current_piece.x += dxself.current_piece.shape = rotatedreturn Truereturn Falsedef drop_piece(self):while self.move(0, 1):passdef new_piece(self):self.current_piece = self.next_pieceself.next_piece = Tetromino()# 检查游戏是否结束if self.is_collision(self.current_piece.shape,self.current_piece.x,self.current_piece.y):self.game_over = Truedef update(self):current_time = time.time()if current_time - self.last_fall_time > self.fall_speed:if not self.move(0, 1):self.merge_piece()self.clear_lines()self.new_piece()self.last_fall_time = current_timedef reset(self):self.__init__()def main():game = TetrisGame()paused = Falsewhile True:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()returnif event.type == pygame.KEYDOWN:if event.key == pygame.K_r:game.reset()paused = Falseif game.game_over:continueif event.key == pygame.K_p:paused = not pausedif paused:continueif event.key == pygame.K_LEFT:game.move(-1, 0)elif event.key == pygame.K_RIGHT:game.move(1, 0)elif event.key == pygame.K_DOWN:game.move(0, 1)elif event.key == pygame.K_UP:game.rotate_piece()elif event.key == pygame.K_SPACE:game.drop_piece()if not game.game_over and not paused:game.update()# 绘制游戏screen.fill((50, 50, 50))game.draw_grid(screen)game.draw_info(screen)if not game.game_over:game.current_piece.draw(screen)if game.game_over:game.draw_game_over(screen)pygame.display.flip()clock.tick(60)if __name__ == "__main__":main()

总结

  • 希望对初学者有帮助

  • 致力于办公自动化的小小程序员一枚

  • 希望能得到大家的【一个免费关注】!感谢

  • 求个 🤞 关注 🤞

  • 此外还有办公自动化专栏,欢迎大家订阅:Python办公自动化专栏

  • 求个 ❤️ 喜欢 ❤️

  • 此外还有爬虫专栏,欢迎大家订阅:Python爬虫基础专栏

  • 求个 👍 收藏 👍

  • 此外还有Python基础专栏,欢迎大家订阅:Python基础学习专栏

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com