python tkinter实现俄罗斯方块拓展——四种游戏模式

【Python】用Python实现一个俄罗斯方块游戏  俄罗斯方块游戏,使用Python实现,总共有350+行代码,实现了俄罗斯方块游戏的基本功能,同时会记录所花费时间,消去的总行数,所得的总分,还包括一个排行榜,可以查看最高记录。排行榜中包含一系列的统计功能,如单位时间消去的行数,单位时间得分等。 附源码:from Tkinter import *from tkMessageBox import *import rand 阅读详情

本文代码基于python
tkinter实现俄罗斯方块基础版——四、消除与得分

的最终代码,
建议先读懂基础版的代码。
对应的实现效果已投稿b站:BV1jt41157uR
对于基础很好的,可以简单阅读这里的核心代码梳理

本文第0部分是1,2,3,4部分的基础,强烈建议观看
本文第1,2,3,4部分相互独立,可跳跃观看

0、核心代码梳理

俄罗斯方块中的核心方法如下,该方法实现界面的刷新,可以认为是整个代码的核心(粗略比喻为控制中心)。后面的四种模式基本上或多或少是与该方法关联的。

def game_loop():
    win.update()
    global current_block
    if current_block is None:
        new_block = generate_new_block()
        # 新生成的俄罗斯方块需要先在生成位置绘制出来
        draw_block_move(canvas, new_block)
        current_block = new_block
        if not check_move(current_block, [0, 0]):
            messagebox.showinfo("Game Over!", "Your Score is %s" % score)
            win.destroy()
            return
    else:
        if check_move(current_block, [0, 1]):
            draw_block_move(canvas, current_block, [0, 1])
        else:
            # 无法移动,记入 block_list 中
            save_block_to_list(current_block)
            current_block = None

    check_and_clear()

    win.after(FPS, game_loop)

由于这个方法很重要,它是不断重复运行的(直到游戏退出),每一次(轮)运行的结果对应的就是一个帧,所以这里来逐行分析下:

  • 初步分析:
    第1行申明函数方法及名称,无需传参(实际是通过全局变量在获取参数,见第三行)
    第2行刷新win窗口
    第3行获取全局变量current_block,也就是当前下落中的俄罗斯方块
    第4行判断当前下落中的俄罗斯方块current_block是否为空None
    为空则执行第5-12行,主要是生成新的俄罗斯方块,并判断当前游戏是否已结束
    否则执行第14-19行,让当前的俄罗斯方块向下移动,无法下落就是落地,落地则设置current_block为None
    第21行检查是否有行可清除,有则清除并计算得分
    第23行设置刷新间隔,在FPS毫秒后刷新页面(重新调用方法本身)
  • 进一步分析
  • 第5-12行
    第5行生成一个新的俄罗斯方块
    第6行在原地绘制这个俄罗斯方块
    第7行将这个俄罗斯方块设置为current_block
    第8行判断当前位置能否放置当前的俄罗斯方块,即当前的俄罗斯方块是否会和已落地的相冲突,如果不能放置,就是冲突了,说明游戏结束,执行第10-12行弹框提示并退出游戏
  • 第14-19行:
    第14行判断当前俄罗斯方块是否能往下落,能则执行第15行,向下移动并绘制;不能则执行第18-19行
    第18行保存当前的俄罗斯方块,
    第19行current_block不再记录已经落地的俄罗斯方块,设置为None

1、残局模式

TODO

2、流动模式

TODO

3、上浮模式

TODO

4、隐藏模式

隐藏模式就是俄罗斯方块落地之后,展示一瞬间再隐藏
那么我们首先要弄明白,
落地后的俄罗斯方块是怎么展示的?
在game_loop方法中落地部分对应18-19行,而save_block_to_list方法中并没有绘制相关的代码,
也就是落地时并没有进行俄罗斯方块的再次的绘制,那么落地后的俄罗斯方块是怎么展示的呢?
本轮落地的俄罗斯方块是通过上一轮的第15行draw_block_move(canvas, current_block, [0, 1])绘制的,而本轮没有进行清除,所以上一轮的绘制留了下来。
进一步的,不考虑行满了被清除的情况。所有落地的俄罗斯方块都是通过第15行的绘制而展示出来的。
那么我们接下来应该怎么实现隐藏模式呢?
这里一步一步来个大家展示下这个摸索的过程,如果嫌啰嗦建议直接跳到本部分末尾,看最终代码

1,隐藏落地后的俄罗斯方块

既然落地后的俄罗斯方块已经展示了,这里就先直接实现落地后的俄罗斯方块的隐藏,
在game_loop方法代码之前,新增如下方法代码,实现落地后的俄罗斯方块的隐藏。

def hide_block_list():
    for ri in range(R):
        for ci in range(C):
            if block_list[ri][ci]:
                draw_cell_by_cr(canvas, ci, ri) # 默认状态下,绘制空白格的颜色

在game_loop方法中的第18-19行之间添加代码hide_block_list()调用该方法。
此时隐藏已实现,但是有了新的问题:
那就是当前俄罗斯方块落地时,只展示了当前的俄罗斯方块,之前落地的俄罗斯方块没有展示。
这是因为新增的hide_block_list()清除了之前的第15行的绘制的结果(实际上使用新的绘制覆盖掉了)
那么我们下面要进一步的解决这个问题,就是要去实现先展示一瞬,再隐藏掉。

2,隐藏前先展示已落地的俄罗斯方块

展示要能被看到,那么就不能和隐藏在同一帧里实现,要先展示,再在下一帧隐藏。
这里用一个全局变量has_hiden来判断,默认为True,已隐藏,
在game_loop方法代码之前,新增如下代码,实现落地后的俄罗斯方块的隐藏。

has_hiden = True
def show_block_list():
    for ri in range(R):
        for ci in range(C):
            if block_list[ri][ci]:
                draw_cell_by_cr(canvas, ci, ri, SHAPESCOLOR[block_list[ri][ci]])

再修改game_loop方法
将其中第3行改为

    global current_block, has_hiden

第18,19行改为

            if has_hiden: # has_hiden默认为True,所以先展示,展示后设置has_hiden为False
                save_block_to_list(current_block)
                show_block_list()
                has_hiden = False
            else: # 隐藏,隐藏后设置has_hiden为True
                hide_block_list()
                current_block = None
                has_hiden = True

到这里,隐藏模式是不是就算实现了呢?
可以算作实现了。
但是还有一个微小的问题,那就是关于行满清除的情况这里没有做处理。
目前的效果是,先展示俄罗斯方块落地后的效果。
展示之后,执行了check_and_clear(),进行了检查与清除,而这个清除的过程和结果并没有展示。
到下一轮game_loop里仍然看到的是俄罗斯方块落地后的效果,然后下一轮隐藏了落地后的效果。
也就是清除的过程和结果是没有展示的。

我们这里还是把这个解决一下

3,如果有清除行的情况,清除后展示下清除的结果再隐藏

这个时候俄罗斯方块落地后,有三件事要做

  • 1,先展示
  • 2,清除已满的行并展示
  • 3,隐藏
    而具体到每一帧的,进一步梳理如下
    俄罗斯方块落地后,
  • 第一帧,先展示落地的俄罗斯方块
  • 第二帧,判断是否有已满的行可清除
    如果有,在本帧(第二帧)展示清除的结果,在下一帧(第三帧)隐藏落地的俄罗斯方块
    否则,在本帧(第二帧)展示隐藏落地的俄罗斯方块

先修改check_and_clear()方法
在该方法中的末尾添加返回值,代码如下,用于判断是否有已满的行可清除(实际清除过程在该方法里已完成)

	return has_complete_row

修改game_loop方法如下

def game_loop():
    win.update()
    global current_block, has_hiden
    if current_block is None:
        new_block = generate_new_block()
        # 新生成的俄罗斯方块需要先在生成位置绘制出来
        draw_block_move(canvas, new_block)
        current_block = new_block
        if not check_move(current_block, [0, 0]):
            messagebox.showinfo("Game Over!", "Your Score is %s" % score)
            win.destroy()
            return
    else:
        if check_move(current_block, [0, 1]):
            draw_block_move(canvas, current_block, [0, 1])
        else:
            # 无法移动,记入 block_list 中
            if has_hiden:
                save_block_to_list(current_block)
                show_block_list()
                has_hiden = False
            else:
                if check_and_clear():
                    show_block_list()
                    has_hiden = False
                else:
                    hide_block_list()
                    current_block = None
                    has_hiden = True

    win.after(FPS, game_loop)

最后由于check_and_clear方法里已实现了清除后展示
所以上面的第24,25行其实是没必要的,上面的第22-29行课进一步优化为

			elif not check_and_clear():
                hide_block_list()
                current_block = None
                has_hiden = True

此时隐藏模式就算完全完成了
然后由于隐藏模式中如果展示时间太短,游戏体验会比较差,所以这里把展示时间搞长一些
第31代码修改如下

	if not has_hiden:
        win.after(2 * FPS, game_loop) # 展示的那一帧,设置时长为普通帧的两倍,也可自己进一步调整
    else:
        win.after(FPS, game_loop)

最终代码完整版本已上传到github:
https://github.com/BigShuang/Tetris/blob/master/2_MODE/04.py

python俄罗斯方块教程-100行代码 使用tkinter库实现基础窗体,不加入任何功能只需如下三行代码运行代码生成的窗口如下接下来我们需要在窗体里面,添加一个画布容器用来“装”俄罗斯方块,就是让这个画布作为面板,俄罗斯方块的移动和绘制均在这个画板上实现。这里我们设定一些俄罗斯方块游戏参数行数为R(取20)列数为C(取12)俄罗斯方块的边长为cell_size(取30)通过tkinger的画布类Canvas实现的代码如下运行代码生成的窗口如下,此时界面的长宽就变成我们所需要的了接下来在画板上绘制俄罗斯方块空白位。 阅读详情

相关推荐

python简易俄罗斯方块

python简易俄罗斯方块前言开始献上代码代码剖析项目github作者 前言 开始 献上代码 from tkinter.messagebox import showinfo as msg from pygame.locals import * import tkinter as tk import pygame import random import time win = tk.Tk() win.withdraw() pygame.init() def render(surf,blocks): for

weixin_42954615的博客 1656

Python课程设计之俄罗斯方块

Python课程设计之俄罗斯方块 软件需求:Python环境 压缩包内含:源代码、打包好的可执行文件、文档报告

满天星的博客 1万+

python之俄罗斯方块游戏

在游戏运行过程中,我们需要让方块不断地向下移动并检测其与游戏界面的碰撞,当方块无法再下降时,需要把方块的位置和颜色信息存储到游戏界面中,并生成一个新的方块。我们将从游戏的各个组成部分开始,逐步深入到游戏的实现细节,最后通过一些代码示例来演示如何实现一个完整的俄罗斯方块游戏。在开始构建游戏之前,我们需要先设计游戏的用户界面。现在,俄罗斯方块已经成为了一个全球流行的游戏,它的简单易懂的游戏机制和无尽的游戏乐趣吸引了无数的玩家。游戏初始化主要是设置游戏的各项参数,包括方块的类型、方块的位置、游戏的速度等。

吃不胖. 364

Python+tkinter实现俄罗斯方块游戏

一个方块区域(游戏板),显示当前分数和最高分的标签,以及控制按钮(重启、暂停、显示排行榜)。玩家可以通过点击“Restart”按钮重启游戏,点击“Pause”按钮暂停游戏,点击“Show Leaderboard”按钮查看排行榜(最高的十个分数)。

weixin_73004416的博客 1102

Tetris:俄罗斯方块教程,基于python tkinter实现

俄罗斯方块 俄罗斯方块教程,基于python tkinter实现 1基础版 对应文件夹:1_BASIC本项目基础版最终效果见本人b站投稿部分 本文已录制的视频教程上传b站: ://www.bilibili.com/video/av81480858。视频部分讲解的比较详细,觉得文字版不够详细的可以去看视频。 3 AI自动玩俄罗斯方块 对应文件夹:3_AI运行效果见本人b站投稿 其中multi_tetris.py对应宽屏多个 tetris_by_class.py对应分开竖屏

基于egret开发的俄罗斯方块(拓展篇)

基于egret开发,在基础的玩法上添加了闯关玩法,(目前有7个关卡),而且还加入了隐身模式增加游戏难度,提供开挂功能,代码里面注释很多,初学者页很容易理解。

python tkinter实现俄罗斯方块基础版——一、基础界面

本教程为我在b站投稿的视频教程av81480858 对应的文字版,项目最终效果见投稿简介部分,视频部分讲解的比较详细,觉得文字版不够详细的可以去看视频。 本项目最终代码已上传github: https://github.com/BigShuang/Tetris 的1_BASIC文件夹 。其中1234分别对应本项目教程每一部分的最终代码,所以想看完整代码直接看004.py就好。 本项目通过pyt...

大爽老师的博客 1万+

python实现俄罗斯方块游戏(改进版)

本文为大家分享了python实现俄罗斯方块游戏,继上一篇的改进版,供大家参考,具体内容如下 1.加了方块预览部分 2.加了开始按钮 在公司实习抽空写的,呵呵。觉得Python还不错,以前觉得像个玩具语言。希望能够用它做更多大事吧!!!加油。 截图如下: 代码如下: #coding=utf-8 from Tkinter import *; from random import *; import thread; from tkMessageBox import showinfo; import threading; from time import sleep; class BrickGam

用python写的俄罗斯方块游戏

python,俄罗斯方块,游戏,基础,漂亮

hongccsdn的博客 1万+

python实现俄罗斯方块

网上搜到一个Pygame写的俄罗斯方块(tetris),大部分看懂的前提下增加了注释,Fedora19下运行OK的 主程序: #coding:utf8 #! /usr/bin/env python # 注释说明:shape表示一个俄罗斯方块形状 cell表示一个小方块 import sys from random import choice import pygame from pygame.locals import * from block import O, I, S, Z, L, J, T COLS = 16 ROWS = 20 CELLS = COLS * ROWS CELLPX

ArcGIS小白必看:5分钟搞定面要素转点要素+自动计算经纬度坐标(附常见报错解决方案)

本文为ArcGIS新手详细解析了面要素转点要素并自动计算经纬度坐标的完整流程。核心在于正确理解和使用坐标系,并掌握ArcToolbox中的“要素转点”等工具。文章深入剖析了常见报错(如坐标系未定义、字段计算失败)的根源,提供了从基础操作到Python脚本自动化的实战解决方案,确保数据转换的准确与高效。

weixin_29284885的博客 575

python制作俄罗斯方块

python制作俄罗斯方块

jakelihua 1万+

FANUC机器人电弧跟踪功能深度解析:从电流采样原理到ROBOGUIDE仿真避坑指南

本文深度解析FANUC机器人电弧跟踪技术,从电流采样原理到ROBOGUIDE仿真避坑指南,详细介绍了电流波形分析、实时补偿机制及现场调试技巧。针对工业焊接中的常见问题,提供从底层原理到高阶应用的解决方案,帮助工程师优化自动化焊接质量。

weixin_31785177的博客 552

用python自带的tkinter做游戏(二)—— 俄罗斯方块 篇

俄罗斯方块相信大家都玩过

znix1116的博客 6496

第1章:认识OpenClaw

OpenClaw是一个开源的 AI 智能体 Gateway 网关项目名称演变:OpenClaw 原名 Clawdbot,因 Anthropic 商标顾虑在 2026年1月27日更名为 Moltbot(过渡名),最终在1月30日确定为 OpenClaw。三个名字本质是同一个项目,功能完全一致。🏠在你的电脑上运行:完全本地部署,数据隐私有保障📁访问本地文件:可以搜索、读取、编辑你电脑上的文件🔌扩展能力:通过Skills(技能)系统无限扩展功能💬多平台使用。

Maynor的博客 2834

基于Simulink的电力电子系统电磁兼容性(EMC)仿真

在电力电子系统中,由于高频开关器件的存在,会产生大量的电磁干扰(EMI),这对系统的稳定性和可靠性提出了挑战。Simulink 提供了一个强大的仿真环境,可以用来设计、分析和验证电力电子系统的电磁兼容性。本教程将详细介绍如何使用 Simulink 进行电力电子系统的电磁兼容性仿真。通过本教程,我们详细介绍了如何使用 Simulink 进行电力电子系统的电磁兼容性仿真。为了模拟电力电子系统中的电磁干扰(EMI),我们需要添加噪声源模块。为了更好地分析系统的电磁兼容性特性,可以在模型中添加频谱分析工具。

amy_mhd的博客 1126

python tkinter实现俄罗斯方块基础版——四、消除与得分

1、消除与得分 最后,要实现俄罗斯方块的消除,就是当一行满了的时候,需要消除这行,同时在通过窗口标题展示得分情况 这里需要添加check_row_completed方法判断指定行是否可以消除 同时添加check_and_clear方法检查所有行并消除 而消除之后,我们需要在画板上重新绘制一遍消除后剩余的俄罗斯方块 这里最好将之前的draw_blank_board方法修改为,可以绘制面板上残留的俄罗...

大爽老师的博客 4675

【异常】claude : 无法将“claude”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径

如果claude方式1(临时):使用完整路径运行,比如:# Windows 批处理脚本示例 C:\你的脚本目录\claude . bat # PowerShell 脚本示例 C:\你的脚本目录\claude . ps1方式2(永久):将脚本所在文件夹添加到系统 PATH 环境变量(参考场景1的环境变量配置步骤),之后即可直接输入claude运行。错误核心原因:系统 PATH 环境变量中找不到claude对应的可执行文件/脚本。

奶爸的编程之路,也就一周冷个三天 3671

【Python游戏】用Python制作一个俄罗斯方块游戏

本项目基于python3版本开发(如果你的是python2.x,运行可能会有问题)

GLB_0627的博客 3101

汽车UDS诊断详解及Vector相关工具链使用说明——1.1 应用层协议整体介绍

本文我们先从整体的维度来介绍一下应用层协议,每个UDS服务都遵循本文中的协议。 一、SI(Service ID) SI是UDS指令的第一个字节,我们第一篇文章中提到的10等服务就是指这个服务的SI=0x10,它是服务的标识,每个服务的SI都是唯一的。 ...

weixin_42967006的博客 5475

【大语言模型 21】语言模型训练目标:MLM vs CLM vs GLM对比分析

本文深入对比分析三种主流语言模型训练目标:掩码语言模型(MLM)、因果语言模型(CLM)和双空白填充(GLM)。通过数学推导、代码实现和实验对比,揭示不同训练目标的工作机制、适用场景和性能差异,为选择合适的预训练策略提供科学指导。

熵数实验室 1176

python tkinter实现俄罗斯方块基础版——二、界面动起来

总目录 一、基础界面 二、界面动起来 三、生成、移动、固定、消除 四、消除与得分 ======================= 大爽歌作,made by big shuang ======================= 0、思路 要让游戏界面动起来,需要实现两点 1-定时刷新页面 2-移动页面内部的俄罗斯方块 这块说一下,光实现一的话理论上页面也算动起来了,但是如果界面内容不变,每次新的...

大爽老师的博客 4885

YOLOv8改进:全网原创首发 | 新颖的多尺度卷积注意力(MSCA),即插即用,助力小目标检测 | NeurIPS2022

多尺度卷积注意力(MSCA),有效地提取上下文信息;1)作为注意力MSCA使用;

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 3844

用100行python代码制作俄罗斯方块游戏,俄罗斯方块游戏教程-附完整代码

本项目通过python自带库tkinter实现,无需安装第三方库本项目基于python3版本开发(如果你的是python2.x,运行可能会有问题)

2401_85737382的博客 1641

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

用100行Python代码,制作游戏《俄罗斯方块》!

用100行Python代码,制作游戏《俄罗斯方块》!

m0_75067840的博客 1868

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

上一篇: Django自学笔记 1-6* 各种问题(Bug)
下一篇: 【BUG】Sourcetree已设置ssh仍然弹窗要求Github账号密码登录or提交代码失败
大爽歌
博客等级 码龄9年 422粉丝 92原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值