俄罗斯方块小游戏(附源码)

游戏展示

一.导包

python 复制代码
import turtle
import random

二.定义一个Block类

  1. 定义一个Block类,用于表示游戏中的方块,包含颜色和形状。
python 复制代码
class Block:
    def __init__(self, color, tiles):
        self.color = color
        self.tiles = tiles

三.定义了7个不同的Block对象

  1. 定义了7个不同的Block对象,分别代表游戏中的7种不同的方块,每种方块都有其特定的颜色和形状。
python 复制代码
I = Block("cyan", [[[1, 0, 0, 0],
                    [1, 0, 0, 0],
                    [1, 0, 0, 0],
                    [1, 0, 0, 0]],

                   [[0, 0, 0, 0],
                    [0, 0, 0, 0],
                    [0, 0, 0, 0],
                    [1, 1, 1, 1]]])

J = Block("blue", [[[0, 1, 0],
                    [0, 1, 0],
                    [1, 1, 0]],

                   [[0, 0, 0],
                    [1, 1, 1],
                    [0, 0, 1]],

                   [[1, 1, 0],
                    [1, 0, 0],
                    [1, 0, 0]],

                   [[0, 0, 0],
                    [1, 0, 0],
                    [1, 1, 1]]])

L = Block("orange", [[[1, 0, 0],
                      [1, 0, 0],
                      [1, 1, 0]],

                     [[0, 0, 0],
                      [0, 0, 1],
                      [1, 1, 1]],

                     [[0, 1, 1],
                      [0, 0, 1],
                      [0, 0, 1]],

                     [[0, 0, 0],
                      [1, 1, 1],
                      [1, 0, 0]]])

S = Block("lime", [[[0, 0, 0],
                    [0, 1, 1],
                    [1, 1, 0]],

                   [[1, 0, 0],
                    [1, 1, 0],
                    [0, 1, 0]]])

Z = Block("red", [[[0, 0, 0],
                   [1, 1, 0],
                   [0, 1, 1]],

                  [[0, 1, 0],
                   [1, 1, 0],
                   [1, 0, 0]]])

O = Block("yellow", [[[1, 1],
                      [1, 1]]])

T = Block("magenta", [[[0, 0, 0],
                       [0, 1, 0],
                       [1, 1, 1]],

                      [[0, 1, 0],
                       [1, 1, 0],
                       [0, 1, 0]],

                      [[0, 0, 0],
                       [1, 1, 1],
                       [0, 1, 0]],

                      [[1, 0, 0],
                       [1, 1, 0],
                       [1, 0, 0]]])

四.定义了一些游戏相关的全局变量

定义了一些游戏相关的全局变量,如方块大小、地图大小、地图起始坐标、分数等

python 复制代码
tile_size = 25
map_rows = 20
map_cols = 10
map_x = -125
map_y = 250

五.创建了几个Turtle对象

用于在屏幕上绘制地图、方块、分数和游戏结束信息

python 复制代码
map_turtle = turtle.Turtle()
map_turtle.hideturtle()
map_turtle.up()

game_map = [["" for _ in range(map_cols)] for _ in range(map_rows)]

active_block = None
active_block_row = 0
active_block_col = 0
active_block_index = 0

block_turtle = turtle.Turtle()
block_turtle.hideturtle()
block_turtle.up()

game_update_interval = 250

score = 0
score_turtle = turtle.Turtle()
score_turtle.hideturtle()
score_turtle.up()
score_turtle.goto(170, 210)
score_turtle.write("Score: " + str(score), font=("Calibri", 20, "bold"))

game_over_turtle = turtle.Turtle()
game_over_turtle.hideturtle()
game_over_turtle.color("red")

六.定义函数

(1)draw_box函数

用于绘制方块

python 复制代码
def draw_box(t, width, height, pencolor, fillcolor):
    t.color(pencolor, fillcolor)
    t.down()
    t.begin_fill()
    for _ in range(2):
        t.forward(width)
        t.right(90)
        t.forward(height)
        t.right(90)
    t.end_fill()
    t.up()

(2)draw_map函数

用于绘制地图

python 复制代码
def draw_map():
    map_turtle.clear()
    for row in range(map_rows):
        for col in range(map_cols):
            map_turtle.goto(map_x + tile_size * col, map_y - tile_size * row)
            draw_box(map_turtle, tile_size, tile_size, "black",
                     game_map[row][col].color if game_map[row][col] else "mintcream")

(3)make_new_block函数

用于生成新的方块

python 复制代码
def make_new_block():
    global active_block
    global active_block_row, active_block_col
    global active_block_index

    active_block = random.choice((I, J, L, S, Z, O, T))
    active_block_row = 0
    active_block_col = 4
    active_block_index = 0

(4)draw_block函数

用于绘制当前方块

python 复制代码
def draw_block():
    block_turtle.clear()

    # Find the x and y position of the block
    x = map_x + active_block_col * tile_size
    y = map_y - active_block_row * tile_size

    block_tiles = active_block.tiles[active_block_index]
    block_color = active_block.color
    for row in range(len(block_tiles)):
        for col in range(len(block_tiles[row])):
            if block_tiles[row][col] == 1:
                block_turtle.goto(x + col * tile_size, y - row * tile_size)
                draw_box(block_turtle, tile_size, tile_size, "black", block_color)

(5)is_valid_block函数

用于检查方块是否可以在当前位置放置

python 复制代码
def is_valid_block(block_type, block_row, block_col, block_index):
    block_tiles = block_type.tiles[block_index]
    for row in range(len(block_tiles)):
        for col in range(len(block_tiles[row])):
            if block_tiles[row][col] == 1:
                if block_row + row not in range(0, map_rows):
                    return False
                if block_col + col not in range(0, map_cols):
                    return False
                if game_map[block_row + row][block_col + col] != "":
                    return False

    return True

(6)set_block_on_map函数

用于将方块固定到地图上

python 复制代码
def set_block_on_map():
    block_tiles = active_block.tiles[active_block_index]
    for row in range(len(block_tiles)):
        for col in range(len(block_tiles[row])):
            if block_tiles[row][col] == 1:
                game_map[active_block_row + row][active_block_col + col] = active_block
    draw_map()


r = 0

(7)remove_completed_rows函数

用于移除完成的行,并更新分数和游戏难度

python 复制代码
def remove_completed_rows():
    global game_map
    global score
    global game_update_interval
    global r

    new_map = []
    for row in range(len(game_map)):
        game_row = game_map[row]
        if "" in game_row:
            new_map.append(game_row)
        else:
            score += 10
            score_turtle.clear()
            score_turtle.write("Score: " + str(score), font=("Calibri", 20, "bold"))
            r += 1
            if r == 5:
                game_update_interval = int(game_update_interval / 1.1)
                r = 0

    for row in range(0, map_rows - len(new_map)):
        game_row = ["" for _ in range(map_cols)]
        new_map.insert(0, game_row)

    game_map = new_map
    draw_map()

    # Task: increase the score and difficulty when a row is completed


pause = False

七.定义了一个游戏循环

用于控制游戏的主要逻辑,如方块的移动、旋转、下落
设置了键盘事件监听,用于处理玩家的输入,如旋转、移动、加速下落和暂停游戏

python 复制代码
def game_loop():
    global active_block, active_block_row

    if active_block is None:
        make_new_block()
        if not is_valid_block(active_block, active_block_row, active_block_col, active_block_index):
            active_block = None
            game_over_turtle.write("Game over!", align="center", font=("Calibri", 60, "bold"))
            return
        draw_block()

    else:
        if is_valid_block(active_block, active_block_row + 1, active_block_col, active_block_index):
            if not pause:
                active_block_row += 1
                draw_block()
        else:
            set_block_on_map()
            active_block = None
            remove_completed_rows()

    turtle.update()

    # Set the next update

    turtle.ontimer(game_loop, game_update_interval)


# Set up the turtle window
turtle.setup(800, 600)
turtle.title("Tetris")
turtle.bgcolor("navajowhite")
turtle.up()
turtle.hideturtle()
turtle.tracer(False)

# Draw the background border around the map
turtle.goto(map_x - 10, map_y + 10)
draw_box(turtle, tile_size * map_cols + 20, tile_size * map_rows + 20, \
         "", "lightslategray")

# Draw the empty map in the window
draw_map()
turtle.update()

# Set up the game loop
turtle.ontimer(game_loop, game_update_interval)


def rotate():
    global active_block_index

    if active_block is None:
        return
    new_block_index = (active_block_index + 1) % len(active_block.tiles)
    if is_valid_block(active_block, active_block_row, active_block_col, new_block_index):
        active_block_index = new_block_index
        draw_block()


turtle.onkeypress(rotate, "Up")


def move_left():
    global active_block_col

    if active_block is None:
        return
    if is_valid_block(active_block, active_block_row, active_block_col - 1, active_block_index):
        active_block_col -= 1
        draw_block()


turtle.onkeypress(move_left, "Left")


def move_right():
    global active_block_col

    if active_block is None:
        return
    if is_valid_block(active_block, active_block_row, active_block_col + 1, active_block_index):
        active_block_col += 1
        draw_block()


turtle.onkeypress(move_right, "Right")


def drop():
    global active_block_row

    if active_block is None:
        return
    while is_valid_block(active_block, active_block_row + 1, active_block_col, active_block_index):
        active_block_row += 1
    draw_block()


turtle.onkeypress(drop, "Down")


def pause_game():
    global pause
    pause = not pause


turtle.onkeypress(pause_game, "space")


def change_block_type():
    global active_block
    global active_block_index

    new_block = random.choice((I, J, L, S, Z, O, T))
    new_block_index = 0
    if is_valid_block(new_block, active_block_row, active_block_col, new_block_index):
        active_block = new_block
        active_block_index = new_block_index
        draw_block()


turtle.onkeypress(change_block_type, "c")

turtle. Listen()

八.启动游戏

python 复制代码
turtle.done()

全部代码

代码来自微信公众号python顾木子吖 感兴趣的小伙伴可以关注一下

python 复制代码
import turtle
import random


class Block:
    def __init__(self, color, tiles):
        self.color = color
        self.tiles = tiles


I = Block("cyan", [[[1, 0, 0, 0],
                    [1, 0, 0, 0],
                    [1, 0, 0, 0],
                    [1, 0, 0, 0]],

                   [[0, 0, 0, 0],
                    [0, 0, 0, 0],
                    [0, 0, 0, 0],
                    [1, 1, 1, 1]]])

J = Block("blue", [[[0, 1, 0],
                    [0, 1, 0],
                    [1, 1, 0]],

                   [[0, 0, 0],
                    [1, 1, 1],
                    [0, 0, 1]],

                   [[1, 1, 0],
                    [1, 0, 0],
                    [1, 0, 0]],

                   [[0, 0, 0],
                    [1, 0, 0],
                    [1, 1, 1]]])

L = Block("orange", [[[1, 0, 0],
                      [1, 0, 0],
                      [1, 1, 0]],

                     [[0, 0, 0],
                      [0, 0, 1],
                      [1, 1, 1]],

                     [[0, 1, 1],
                      [0, 0, 1],
                      [0, 0, 1]],

                     [[0, 0, 0],
                      [1, 1, 1],
                      [1, 0, 0]]])

S = Block("lime", [[[0, 0, 0],
                    [0, 1, 1],
                    [1, 1, 0]],

                   [[1, 0, 0],
                    [1, 1, 0],
                    [0, 1, 0]]])

Z = Block("red", [[[0, 0, 0],
                   [1, 1, 0],
                   [0, 1, 1]],

                  [[0, 1, 0],
                   [1, 1, 0],
                   [1, 0, 0]]])

O = Block("yellow", [[[1, 1],
                      [1, 1]]])

T = Block("magenta", [[[0, 0, 0],
                       [0, 1, 0],
                       [1, 1, 1]],

                      [[0, 1, 0],
                       [1, 1, 0],
                       [0, 1, 0]],

                      [[0, 0, 0],
                       [1, 1, 1],
                       [0, 1, 0]],

                      [[1, 0, 0],
                       [1, 1, 0],
                       [1, 0, 0]]])

tile_size = 25
map_rows = 20
map_cols = 10
map_x = -125
map_y = 250

map_turtle = turtle.Turtle()
map_turtle.hideturtle()
map_turtle.up()

game_map = [["" for _ in range(map_cols)] for _ in range(map_rows)]

active_block = None
active_block_row = 0
active_block_col = 0
active_block_index = 0

block_turtle = turtle.Turtle()
block_turtle.hideturtle()
block_turtle.up()

game_update_interval = 250

score = 0
score_turtle = turtle.Turtle()
score_turtle.hideturtle()
score_turtle.up()
score_turtle.goto(170, 210)
score_turtle.write("Score: " + str(score), font=("Calibri", 20, "bold"))

game_over_turtle = turtle.Turtle()
game_over_turtle.hideturtle()
game_over_turtle.color("red")


def draw_box(t, width, height, pencolor, fillcolor):
    t.color(pencolor, fillcolor)
    t.down()
    t.begin_fill()
    for _ in range(2):
        t.forward(width)
        t.right(90)
        t.forward(height)
        t.right(90)
    t.end_fill()
    t.up()


def draw_map():
    map_turtle.clear()
    for row in range(map_rows):
        for col in range(map_cols):
            map_turtle.goto(map_x + tile_size * col, map_y - tile_size * row)
            draw_box(map_turtle, tile_size, tile_size, "black",
                     game_map[row][col].color if game_map[row][col] else "mintcream")


def make_new_block():
    global active_block
    global active_block_row, active_block_col
    global active_block_index

    active_block = random.choice((I, J, L, S, Z, O, T))
    active_block_row = 0
    active_block_col = 4
    active_block_index = 0


def draw_block():
    block_turtle.clear()

    # Find the x and y position of the block
    x = map_x + active_block_col * tile_size
    y = map_y - active_block_row * tile_size

    block_tiles = active_block.tiles[active_block_index]
    block_color = active_block.color
    for row in range(len(block_tiles)):
        for col in range(len(block_tiles[row])):
            if block_tiles[row][col] == 1:
                block_turtle.goto(x + col * tile_size, y - row * tile_size)
                draw_box(block_turtle, tile_size, tile_size, "black", block_color)


def is_valid_block(block_type, block_row, block_col, block_index):
    block_tiles = block_type.tiles[block_index]
    for row in range(len(block_tiles)):
        for col in range(len(block_tiles[row])):
            if block_tiles[row][col] == 1:
                if block_row + row not in range(0, map_rows):
                    return False
                if block_col + col not in range(0, map_cols):
                    return False
                if game_map[block_row + row][block_col + col] != "":
                    return False

    return True


def set_block_on_map():
    block_tiles = active_block.tiles[active_block_index]
    for row in range(len(block_tiles)):
        for col in range(len(block_tiles[row])):
            if block_tiles[row][col] == 1:
                game_map[active_block_row + row][active_block_col + col] = active_block
    draw_map()


r = 0


def remove_completed_rows():
    global game_map
    global score
    global game_update_interval
    global r

    new_map = []
    for row in range(len(game_map)):
        game_row = game_map[row]
        if "" in game_row:
            new_map.append(game_row)
        else:
            score += 10
            score_turtle.clear()
            score_turtle.write("Score: " + str(score), font=("Calibri", 20, "bold"))
            r += 1
            if r == 5:
                game_update_interval = int(game_update_interval / 1.1)
                r = 0

    for row in range(0, map_rows - len(new_map)):
        game_row = ["" for _ in range(map_cols)]
        new_map.insert(0, game_row)

    game_map = new_map
    draw_map()

    # Task: increase the score and difficulty when a row is completed


pause = False


def game_loop():
    global active_block, active_block_row

    if active_block is None:
        make_new_block()
        if not is_valid_block(active_block, active_block_row, active_block_col, active_block_index):
            active_block = None
            game_over_turtle.write("Game over!", align="center", font=("Calibri", 60, "bold"))
            return
        draw_block()

    else:
        if is_valid_block(active_block, active_block_row + 1, active_block_col, active_block_index):
            if not pause:
                active_block_row += 1
                draw_block()
        else:
            set_block_on_map()
            active_block = None
            remove_completed_rows()

    turtle.update()

    # Set the next update

    turtle.ontimer(game_loop, game_update_interval)


# Set up the turtle window
turtle.setup(800, 600)
turtle.title("Tetris")
turtle.bgcolor("navajowhite")
turtle.up()
turtle.hideturtle()
turtle.tracer(False)

# Draw the background border around the map
turtle.goto(map_x - 10, map_y + 10)
draw_box(turtle, tile_size * map_cols + 20, tile_size * map_rows + 20, \
         "", "lightslategray")

# Draw the empty map in the window
draw_map()
turtle.update()

# Set up the game loop
turtle.ontimer(game_loop, game_update_interval)


def rotate():
    global active_block_index

    if active_block is None:
        return
    new_block_index = (active_block_index + 1) % len(active_block.tiles)
    if is_valid_block(active_block, active_block_row, active_block_col, new_block_index):
        active_block_index = new_block_index
        draw_block()


turtle.onkeypress(rotate, "Up")


def move_left():
    global active_block_col

    if active_block is None:
        return
    if is_valid_block(active_block, active_block_row, active_block_col - 1, active_block_index):
        active_block_col -= 1
        draw_block()


turtle.onkeypress(move_left, "Left")


def move_right():
    global active_block_col

    if active_block is None:
        return
    if is_valid_block(active_block, active_block_row, active_block_col + 1, active_block_index):
        active_block_col += 1
        draw_block()


turtle.onkeypress(move_right, "Right")


def drop():
    global active_block_row

    if active_block is None:
        return
    while is_valid_block(active_block, active_block_row + 1, active_block_col, active_block_index):
        active_block_row += 1
    draw_block()


turtle.onkeypress(drop, "Down")


def pause_game():
    global pause
    pause = not pause


turtle.onkeypress(pause_game, "space")


def change_block_type():
    global active_block
    global active_block_index

    new_block = random.choice((I, J, L, S, Z, O, T))
    new_block_index = 0
    if is_valid_block(new_block, active_block_row, active_block_col, new_block_index):
        active_block = new_block
        active_block_index = new_block_index
        draw_block()


turtle.onkeypress(change_block_type, "c")

turtle.listen()

turtle.done()
相关推荐
牧羊人_myr几秒前
Ajax 技术详解
前端
浩男孩10 分钟前
🍀封装个 Button 组件,使用 vitest 来测试一下
前端
蓝银草同学14 分钟前
阿里 Iconfont 项目丢失?手把手教你将已引用的 SVG 图标下载到本地
前端·icon
布列瑟农的星空24 分钟前
重学React —— React事件机制 vs 浏览器事件机制
前端
程序员小远39 分钟前
常用的测试用例
自动化测试·软件测试·python·功能测试·测试工具·职场和发展·测试用例
IT学长编程41 分钟前
计算机毕业设计 基于EChants的海洋气象数据可视化平台设计与实现 Python 大数据毕业设计 Hadoop毕业设计选题【附源码+文档报告+安装调试】
大数据·hadoop·python·毕业设计·课程设计·毕业论文·海洋气象数据可视化平台
辣椒http_出海辣椒1 小时前
Python 数据抓取实战:从基础到反爬策略的完整指南
python
一小池勺1 小时前
CommonJS
前端·面试
孙牛牛1 小时前
实战分享:一招解决嵌套依赖版本失控问题,以 undici 为例
前端