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

总目录

一、基础界面

二、界面动起来

三、生成、移动、固定、消除

四、消除与得分

======================= 大爽歌作,made by big shuang =======================

0、思路

要让游戏界面动起来,需要实现两点

  • 1-定时刷新页面
  • 2-移动页面内部的俄罗斯方块

这块说一下,光实现一的话理论上页面也算动起来了,但是如果界面内容不变,每次新的页面和旧的界面看起来是一样的,给人的观看感觉跟没有动没有区别

所以必须要实现2,来更改界面内容,给人“动”起来的感觉

1、定时刷新页面

实现定时刷新页面,很简单
写一个方法用于循环刷新,再定时调用
此部分代码写在原来代码最后的win.mainloop之前就好

FPS = 500  # 刷新页面的毫秒间隔
def game_loop():
    win.update()
 
    # ===用于展示刷新,后续会删掉===
    import time
    print(time.ctime())
    # ===========================
 
    win.after(FPS, game_loop)
 
win.update()
win.after(FPS, game_loop) # 在FPS 毫秒后调用 game_loop方法

此时运行发现命令行中会有如下输出,说明这个页面确实是每隔500ms刷新了一次

Thu Nov 28 23:32:50 2019
Thu Nov 28 23:32:51 2019
Thu Nov 28 23:32:51 2019
Thu Nov 28 23:32:52 2019
Thu Nov 28 23:32:52 2019
Thu Nov 28 23:32:53 2019
Thu Nov 28 23:32:53 2019

但是由于我之前说的,每次刷新后页面的内容是没有变化的,给观众的感觉还是更没动一样
所以需要配合每次刷新,移动俄罗斯方块的位置

2、移动俄罗斯方块

对于某个俄罗斯方块,要绘制出来需要知道它的位置和类型,以及内部的各个方格。
这三个数据可以用字典存起来,这里我们规定格式如下

a_block = {
    'kind': 'O',  # 对应俄罗斯方块的类型
    'cell_list': SHAPES['O'],  # 对应俄罗斯方块的各个方格
    'cr': [3, 3]  # 对应横纵坐标,以左上角为原点,水平向右为横坐标轴正方向,竖直向下为纵坐标轴正方向
}

此时一个这样的字典其实就可以看做一个俄罗斯方块对象
然后我们再建一个专门的方法draw_block_move,来绘制俄罗斯方块的移动
其实移动也比较简单,就是清掉旧位置已经绘制的俄罗斯方块,再在新位置绘制新的俄罗斯方块就好
然后修改下game_loop方法
更新修改部分如下

# 在draw_blank_board(canvas)语句下面添加如下语句
def draw_block_move(canvas, block, direction=[0, 0]):
    """
    绘制向指定方向移动后的俄罗斯方块
    :param canvas: 画板
    :param block: 俄罗斯方块对象
    :param direction: 俄罗斯方块移动方向
    :return:
    """
    shape_type = block['kind']
    c, r = block['cr']
    cell_list = block['cell_list']
 
    # 移动前,先清除原有位置绘制的俄罗斯方块,也就是用背景色绘制原有的俄罗斯方块
    draw_cells(canvas, c, r, cell_list)
 
    dc, dr = direction
    new_c, new_r = c+dc, r+dr
    block['cr'] = [new_c, new_r]
    # 在新位置绘制新的俄罗斯方块就好
    draw_cells(canvas, new_c, new_r, cell_list, SHAPESCOLOR[shape_type])
 
 
a_block = {
    'kind': 'O',  # 对应俄罗斯方块的类型
    'cell_list': SHAPES['O'],  # 对应俄罗斯方块的各个方格
    'cr': [3, 3]  # 对应横纵坐标,以左上角为原点,水平向右为横坐标轴正方向,竖直向下为纵坐标轴正方向
}
 
draw_block_move(canvas, a_block)
 
 
# 修改原来的game_loop方法如下
def game_loop():
    win.update()
 
    down = [0, 1]
    draw_block_move(canvas, a_block, down)
 
    win.after(FPS, game_loop)

此时的完整代码已上传github,点击查看,运行代码就发现界面中的俄罗斯方块动起来了,动画如下
在这里插入图片描述

<think>好的,用户想在Tkinter实现俄罗斯方块游戏的动态刷新和动画效果。我之前看过一些相关的引用,比如引用[1]中提到了使用`win.after(FPS, game_loop)`来实现循环更新。这应该是利用Tkinter的`after`方法定时调用游戏循环函数,从而不断刷新界面。 首先,动态刷新需要定期更新画布上的方块位置。引用[3]提到需要删除原来的固定位置生成的代码,改为动态生成。这可能涉及到在游戏循环中生成新方块,并在每次循环时移动当前方块。当方块无法继续下落时,生成新的方块,如引用[1]中的`generate_new_block()`函数。 然后是动画效果,比如方块的下落和移动。每次移动时,应该先清除旧的方块位置,再在新的位置绘制。这可能需要在`draw_block_move`函数中处理,传入移动的方向,比如[0,1]表示向下移动。引用[2]中的`block.move()`方法可能负责更新位置,但具体在Tkinter中可能需要重新绘制方块。 另外,碰撞检测也很重要。引用[1]中的`check_move(current_block, [0, 1])`函数应该用于检测当前方块是否可以继续下落。如果不能,就将当前方块固定,并生成新的方块。这确保了游戏逻辑的正确性。 还需要考虑界面刷新频率,FPS的设置会影响动画的流畅度。使用`win.after(FPS, game_loop)`可以控制刷新间隔,避免占用过多资源。 可能还需要处理用户输入,比如左右移动和旋转方块。这部分需要绑定键盘事件,并在事件处理函数中调用移动或旋转的方法,同时更新画布上的显示。 总结一下,关键点在于定时器的使用、方块的位置更新与重绘、碰撞检测以及用户输入的响应。需要将这些部分结合起来,才能实现动态刷新和流畅的动画效果。</think>在Tkinter实现俄罗斯方块动态效果主要依靠定时刷新和画布对象操作。以下是实现动态刷新的具体步骤: 1. **定时器驱动框架** 使用`after()`方法建立游戏主循环: ```python FPS = 500 # 控制下落速度 def game_loop(): update_game() # 游戏状态更新 draw_frame() # 画面重绘 win.after(FPS, game_loop) # 递归调用[^1] ``` 2. **动态绘制模块** ```python def draw_block_move(canvas, block, offset=[0,0]): canvas.delete("current") # 清除上一帧图形 new_pos = [[x+offset[0], y+offset[1]] for (x,y) in block['pos']] for x,y in new_pos: canvas.create_rectangle( x*BLOCK_SIZE, y*BLOCK_SIZE, (x+1)*BLOCK_SIZE, (y+1)*BLOCK_SIZE, fill=COLORS[block['type']], tags="current" ) ``` 3. **运动检测逻辑** ```python def check_move(block, offset): new_pos = [[x+offset[0], y+offset[1]] for (x,y) in block['pos']] return all(0 <= x < COLUMNS and y < ROWS and not matrix[y][x] for (x,y) in new_pos) ``` 4. **键盘事件响应** ```python def on_key_press(event): if event.keysym == 'Left': if check_move(current_block, [-1,0]): draw_block_move(canvas, current_block, [-1,0]) elif event.keysym == 'Right': if check_move(current_block, [1,0]): draw_block_move(canvas, current_block, [1,0]) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值