python语言入门必须要学习的模块化编程案例游戏---俄罗斯方块【源码大全】

部署运行你感兴趣的模型镜像

导入模块和定义颜色

import pygame
import random

# 定义颜色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

这段代码导入了pygame模块用于游戏开发,同时导入了random模块用于生成随机数。接着定义了几种颜色常量,分别代表黑色、白色、红色、绿色和蓝色,这些颜色将在游戏中用于绘制不同的元素。

定义方块形状

# 定义方块形状
SHAPES = [
    [[1, 1, 1, 1]],
    [[1, 1], [1, 1]],
    [[1, 1, 0], [0, 1, 1]],
    [[0, 1, 1], [1, 1, 0]],
    [[1, 1, 1], [0, 1, 0]],
    [[1, 1, 1], [1, 0, 0]],
    [[1, 1, 1], [0, 0, 1]]
]

这里定义了一个列表SHAPES,其中包含了七种不同的方块形状,每个形状用二维列表表示,其中1表示有方块,0表示为空。

定义方块类

# 定义方块类
class Shape:
    def __init__(self):
        self.shape = random.choice(SHAPES)
        self.color = random.choice([RED, GREEN, BLUE])
        self.x = 3
        self.y = 0

这部分定义了一个Shape类,用于表示游戏中的方块。在构造函数中,随机选择一种方块形状,并随机选择一种颜色(红、绿、蓝之一)。同时,初始化方块的横坐标x为 3,纵坐标y为 0,表示方块初始位置在游戏网格的中间偏左,高度为 0。

    def rotate(self):
        new_shape = [list(reversed(col)) for col in zip(*self.shape)]
        return Shape(new_shape, self.color)

这个方法实现了方块的旋转功能。通过对当前方块形状的矩阵进行转置和反转列操作,得到新的旋转后的形状,并返回一个新的Shape对象。

    def move_down(self):
        self.y -= 1

这个方法使方块向左移动一格,即减少横坐标x的值。

    def move_right(self):
        self.x += 1

这个方法使方块向右移动一格,即增加横坐标x的值。

初始化 Pygame 和设置屏幕尺寸

# 初始化 Pygame
pygame.init()

# 设置屏幕尺寸
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("俄罗斯方块")

# 游戏时钟
clock = pygame.time.Clock()

这部分代码首先初始化pygame库。然后设置游戏屏幕的宽度为 800 像素,高度为 600 像素,并创建一个窗口。设置窗口标题为 “俄罗斯方块”。接着创建一个游戏时钟对象,用于控制游戏的帧率。

游戏主循环

# 游戏主循环
def game_loop():
    shape = Shape()
    grid = [[BLACK for _ in range(10)] for _ in range(20)]
    score = 0
    game_over = False

定义了游戏主循环函数game_loop。在函数内部,首先创建一个初始方块对象shape,创建一个 20 行 10 列的二维列表grid表示游戏网格,初始颜色为黑色。初始化分数score为 0,设置游戏结束标志game_over为False。

    while not game_over:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game_over = True
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    shape.move_left()
                elif event.key == pygame.K_RIGHT:
                    shape.move_right()
                elif event.key == pygame.K_DOWN:
                    shape.move_down()
                elif event.key == pygame.K_UP:
                    new_shape = shape.rotate()
                    if is_valid_position(new_shape, grid):
                        shape = new_shape

这是游戏的主循环部分,当game_over为False时持续运行。循环中遍历pygame的事件队列,如果检测到窗口关闭事件(pygame.QUIT),则设置game_over为True,结束游戏。如果检测到键盘按下事件(pygame.KEYDOWN),根据不同的按键执行相应的方块移动或旋转操作。如果按下左方向键,调用方块的move_left方法向左移动方块;按下右方向键,调用move_right方法向右移动方块;按下下方向键,调用move_down方法向下移动方块;按下上方向键,先创建一个旋转后的新方块对象new_shape,如果新方块位置合法(通过调用is_valid_position函数判断),则将当前方块更新为新旋转后的方块。

        if not is_valid_position(shape, grid):
            if shape.y == 0:
                game_over = True
            else:
                place_shape(shape, grid)
                clear_lines(grid, score)
                shape = Shape()

如果当前方块位置不合法(通过调用is_valid_position函数判断),如果方块已经在最顶部(shape.y == 0),则设置游戏结束标志。否则,将方块放置在网格中(调用place_shape函数),检查并清除满行(调用clear_lines函数),然后创建一个新的方块对象。

        draw_grid(grid, shape)
        pygame.display.flip()
        clock.tick(10)

调用draw_grid函数绘制游戏画面,然后使用pygame.display.flip()更新屏幕显示。最后,通过clock.tick(10)控制游戏帧率,这里设置为每秒 10 帧。

    pygame.quit()
    quit()

当游戏结束时,退出pygame并退出程序。

检查方块位置是否合法

# 检查方块位置是否合法
def is_valid_position(shape, grid):
    for y, row in enumerate(shape.shape):
        for x, cell in enumerate(row):
            if cell and (shape.x + x >= 10 or shape.x + x < 0 or shape.y + y >= 20 or grid[shape.y + y][shape.x + x]!= BLACK):
                return False
    return True

这个函数用于检查给定方块在游戏网格中的位置是否合法。遍历方块的形状矩阵,如果方块中的某个格子为1(表示有方块),则检查该格子对应的在游戏网格中的位置是否超出边界(横坐标超出 0 到 9 的范围或纵坐标超出 0 到 19 的范围),或者该位置在游戏网格中已经被其他方块占据(不是黑色)。如果有任何不合法的情况,返回False;如果所有格子都合法,返回True。

将方块放置在网格中

# 将方块放置在网格中
def place_shape(shape, grid):
    for y, row in enumerate(shape.shape):
        for x, cell in enumerate(row):
            if cell:
                grid[shape.y + y][shape.x + x] = shape.color

这个函数将给定的方块放置在游戏网格中。遍历方块的形状矩阵,如果某个格子为1,则将该格子对应的游戏网格位置设置为方块的颜色。

清除满行并更新分数

# 清除满行并更新分数
def clear_lines(grid, score):
    lines_cleared = 0
    for y in range(len(grid)):
        if all(cell!= BLACK for cell in grid[y]):
            del grid[y]
            grid.insert(0, [BLACK for _ in range(10)])
            lines_cleared += 1

这个函数检查游戏网格中是否有满行,并清除满行同时更新分数。遍历游戏网格的每一行,如果一行中的所有格子都不是黑色(表示该行被方块填满),则删除该行,并在顶部插入一行黑色的空行。同时,记录清除的行数。

    if lines_cleared == 1:
        score += 100
    elif lines_cleared == 2:
        score += 300
    elif lines_cleared == 3:
        score += 500
    elif lines_cleared == 4:
        score += 800

根据清除的行数更新分数。如果清除了 1 行,分数增加 100;清除 2 行,分数增加 300;清除 3 行,分数增加 500;清除 4 行,分数增加 800。最后返回更新后的分数。

绘制游戏画面

# 绘制游戏画面
def draw_grid(grid, shape):
    screen.fill(BLACK)
    for y, row in enumerate(grid):
        for x, cell in enumerate(row):
            pygame.draw.rect(screen, cell, [x * 40, y * 40, 38, 38])

这个函数绘制游戏画面。首先用黑色填充整个屏幕。然后遍历游戏网格,对于每个非黑色的格子,在屏幕上绘制一个矩形,表示该格子中的方块。矩形的位置根据格子的坐标和每个格子的大小(40x40 像素)计算得出。

启动游戏

game_loop()

完整代码

import pygame
import random

# 定义颜色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

# 定义七种不同的方块形状,用二维列表表示
SHAPES = [
    [[1, 1, 1, 1]],  # 长条形状
    [[1, 1], [1, 1]],  # 正方形形状
    [[1, 1, 0], [0, 1, 1]],  # Z 字形(向左)
    [[0, 1, 1], [1, 1, 0]],  # Z 字形(向右)
    [[1, 1, 1], [0, 1, 0]],  # T 字形
    [[1, 1, 1], [1, 0, 0]],  # L 字形(向左)
    [[1, 1, 1], [0, 0, 1]]  # L 字形(向右)
]

# 定义方块类
class Shape:
    def __init__(self):
        # 随机选择一种形状并设置颜色,初始位置在网格中间偏左,高度为 0
        self.shape = random.choice(SHAPES)
        self.color = random.choice([RED, GREEN, BLUE])
        self.x = 3
        self.y = 0

    def rotate(self):
        # 实现方块的旋转,通过对形状矩阵进行转置和反转列得到新形状
        new_shape = [list(reversed(col)) for col in zip(*self.shape)]
        return Shape(new_shape, self.color)

    def move_down(self):
        # 向下移动一格
        self.y += 1

    def move_left(self):
        # 向左移动一格
        self.x -= 1

    def move_right(self):
        # 向右移动一格
        self.x += 1

# 初始化 Pygame
pygame.init()

# 设置屏幕尺寸
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("俄罗斯方块")

# 游戏时钟,用于控制游戏帧率
clock = pygame.time.Clock()

# 游戏主循环
def game_loop():
    shape = Shape()
    # 创建一个 20 行 10 列的二维列表表示游戏网格,初始颜色为黑色
    grid = [[BLACK for _ in range(10)] for _ in range(20)]
    score = 0
    game_over = False

    while not game_over:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                # 窗口关闭事件,设置游戏结束标志
                game_over = True
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    # 按下左方向键,向左移动方块
                    shape.move_left()
                elif event.key == pygame.K_RIGHT:
                    # 按下右方向键,向右移动方块
                    shape.move_right()
                elif event.key == pygame.K_DOWN:
                    # 按下下方向键,向下移动方块
                    shape.move_down()
                elif event.key == pygame.K_UP:
                    # 按下上方向键,旋转方块
                    new_shape = shape.rotate()
                    if is_valid_position(new_shape, grid):
                        shape = new_shape

        if not is_valid_position(shape, grid):
            if shape.y == 0:
                # 如果方块已经在最顶部且位置不合法,游戏结束
                game_over = True
            else:
                # 将方块放置在网格中
                place_shape(shape, grid)
                # 检查并清除满行,更新分数
                clear_lines(grid, score)
                # 创建新的方块
                shape = Shape()

        # 绘制游戏画面
        draw_grid(grid, shape)
        pygame.display.flip()
        # 控制游戏帧率
        clock.tick(10)

    pygame.quit()
    quit()

# 检查方块位置是否合法
def is_valid_position(shape, grid):
    for y, row in enumerate(shape.shape):
        for x, cell in enumerate(row):
            if cell and (shape.x + x >= 10 or shape.x + x < 0 or shape.y + y >= 20 or grid[shape.y + y][shape.x + x]!= BLACK):
                # 如果方块超出网格边界或者与已存在的方块重叠,则位置不合法
                return False
    return True

# 将方块放置在网格中
def place_shape(shape, grid):
    for y, row in enumerate(shape.shape):
        for x, cell in enumerate(row):
            if cell:
                # 将方块的颜色设置到对应的网格位置
                grid[shape.y + y][shape.x + x] = shape.color

# 清除满行并更新分数
def clear_lines(grid, score):
    lines_cleared = 0
    for y in range(len(grid)):
        if all(cell!= BLACK for cell in grid[y]):
            # 如果一行全是非黑色(即被方块占据),则为满行
            del grid[y]
            grid.insert(0, [BLACK for _ in range(10)])
            lines_cleared += 1

    if lines_cleared == 1:
        score += 100
    elif lines_cleared == 2:
        score += 300
    elif lines_cleared == 3:
        score += 500
    elif lines_cleared == 4:
        score += 800

    return score

# 绘制游戏画面
def draw_grid(grid, shape):
    screen.fill(BLACK)
    for y, row in enumerate(grid):
        for x, cell in enumerate(row):
            pygame.draw.rect(screen, cell, [x * 40, y * 40, 38, 38])
            # 绘制网格中的每个方块

    for y, row in enumerate(shape.shape):
        for x, cell in enumerate(row):
            if cell:
                pygame.draw.rect(screen, shape.color, [(shape.x + x) * 40, (shape.y + y) * 40, 38, 38])
                # 绘制当前正在下落的方块

game_loop()

您可能感兴趣的与本文相关的镜像

Python3.11

Python3.11

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值