Python课程设计之俄罗斯方块

这篇具有很好参考价值的文章主要介绍了Python课程设计之俄罗斯方块。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

演示效果

点击查看

下载地址

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

Python课程设计之俄罗斯方块

运行效果

Python课程设计之俄罗斯方块
Python课程设计之俄罗斯方块

基础页面

(1)、搭建基础窗体
使用tkinter实现基础窗体。

import tkinter as tk#实现tkinter基础窗体,导入tkinter包取别名tk  
win = tk.Tk()#tk库名,TK是tkinter库里面顶层窗体控件,用于表示用户主窗口  
win.mainloop()# 维持窗体 

运行代码生成窗口如下
Python课程设计之俄罗斯方块
接下来需要在窗体里面,添加一个画布容器用来“装”俄罗斯方块,就是让这个画布作为面板,俄罗斯方块的移动和绘制均在这个画板上实现。
这里我们设定一些俄罗斯方块游戏参数。行数为R(取20),列数为C(取12),俄罗斯方块的边长为cell_size(取30)
通过tkinger的画布类Canvas实现,Canvas是tkinter库里常用的画布对象,主要用于绘制一些东西

import tkinter as tk  #实现tkinter基础窗体,导入tkinter包取别名tk    
cell_size = 30 #每一个方格的边长  
C = 12 #列数  
R = 20 #行数  
height = R * cell_size #画布高度  
width = C * cell_size #画布宽度   
win = tk.Tk() #tk库名,TK是tkinter库里面顶层窗体控件,用于表示用户主窗口  
canvas = tk.Canvas(win, width=width, height=height)#参数为宽度与高度,win是父控件或者说母控件  
canvas.pack() #把所有的控件对象放置在指定位置,才能展示在界面窗体  
win.mainloop() # 维持窗体  
 此时界面的长宽就变成我们所需要的了

Python课程设计之俄罗斯方块

接下来在画板上绘制俄罗斯方块空白位,首先建立一个函数draw_cell_by_cr,用于在画板上绘制单个俄罗斯方块,然后建立一个函数draw_blank_board,用于在画板上绘制所有空白方块(也就是空白方块板,为了和背景区分,所以设置空白方块为轻灰色)

import tkinter as tk  #实现tkinter基础窗体,导入tkinter包取别名tk   
cell_size = 30 #每一个方格的边长  
C = 12 #列数  
R = 20 #行数  
height = R * cell_size #画布高度  
width = C * cell_size #画布宽度  
#在画板上绘制空白格子作为背景,先建立一个方法  
def draw_cell_by_cr(canvas, c, r, color="#CCCCCC"):  
    """ 
     canvas: 画板,用于绘制一个方块的Canvas对象 
     c: 方块所在列 
     r: 方块所在行 
     color: 方块颜色,默认为#CCCCCC,轻灰色 
    """  
    x0 = c * cell_size #列数*方块大小  
    y0 = r * cell_size#行数*方块大小  
    x1 = c * cell_size + cell_size#列数*方块大小+1  
    y1 = r * cell_size + cell_size#行数*方块大小+1  
    canvas.create_rectangle(x0, y0, x1, y1, fill=color, outline="white", width=2)  
  #用canvas画板对象在指定的行、列进行绘制矩形并填充,以及白色边框,宽度为2   
# 新建一个方法,绘制空白面板,也就是这些空白面板背景  
def draw_blank_board(canvas): #绘制空白面板  
    for ri in range(R): #遍历所有行  
       for ci in range(C): #遍历每一行的所有列  
                draw_cell_by_cr(canvas, ci, ri) #调用绘制函数    
win = tk.Tk() #tk库名,TK是tkinter库里面顶层窗体控件,用于表示用户主窗口  
canvas = tk.Canvas(win, width=width, height=height)#参数为宽度与高度,win是父控件或者说母控件  
canvas.pack() #把所有的控件对象放置在指定位置,才能展示在界面窗体  
draw_blank_board(canvas) #调用函数  
win.mainloop() # 维持窗体  

Python课程设计之俄罗斯方块

(2)、绘制O形俄罗斯方块
先从最简单的o型俄罗斯方块(即田字格)
Python课程设计之俄罗斯方块

先要记录每各形状所有格子的坐标,以格子所在行序号为纵坐标,所在列序号为横坐标,以田字格中点为原点,则o型俄罗斯方块的四个格子的坐标如下图所示
Python课程设计之俄罗斯方块

用列表和元组记录为

[  
    (-1, -1),  
    (0, -1),  
    (-1, 0),  
    (0, 0)  
]   

将俄罗斯方块形状字符串和坐标列表的映射关系存到字典SHAPES里(映射关系这里可以理解为一一对应的关系),同时建立一个字典SHAPESCOLOR,来记录俄罗斯方块形状字符串和颜色的一一对应关系。由于一个形状可以看成多个方格组成的,所以我们可以新建函数draw_cells用来绘制这个形状,最后选择一个地方来绘制这个形状。

1.# 定义形状  
2.SHAPES = {  
3.    "O": [(-1, -1), (0, -1), (-1, 0), (0, 0)],  
4.}  
5.# 定义形状的颜色  
6.SHAPESCOLOR = {  
7.    "O": "blue",  
8.}  
9.def draw_cells(canvas, c, r, cell_list, color="#CCCCCC"):  
10.    """ 
11.    绘制指定形状指定颜色的俄罗斯方块 
12.     canvas: 画板 
13.     r: 该形状设定的原点所在的行 
14.     c: 该形状设定的原点所在的列 
15.     cell_list: 该形状各个方格相对自身所处位置 
16.     color: 该形状颜色 
17.    """  
18.    for cell in cell_list:  # 遍历这个形状的所有方格  
19.        cell_c, cell_r = cell  # 它的实际位置坐标为相对的这个位置加上原点的行列  
20.        ci = cell_c + c  
21.        ri = cell_r + r  
22.        # 判断该位置方格在画板内部(画板外部的方格不再绘制)  
23.        if 0 <= c < C and 0 <= r < R:  # 判断该方格在画板内部,再绘制  
24.            draw_cell_by_cr(canvas, ci, ri, color)  # 调用绘制函数  
25.# 下面这行代码放在draw_blank_board(canvas) 下面  
26.# 任取一个位置,如(3,3)绘制一个o型俄罗斯方块,用于展示  
27.draw_cells(canvas, 3, 3, SHAPES['O'], SHAPESCOLOR['O'])  
28.# 上面这行代码放在win.mainloop()上面  

Python课程设计之俄罗斯方块

(3)、绘制其他俄罗斯方块
俄罗斯方块主流分七种,除去上面的O型,其他六俄罗斯方块如图所示
Python课程设计之俄罗斯方块
对应的,要在SHAPES和SHAPESCOLOR中添加其他方块的坐标和颜色,添加后如下

1.# 定义各种形状,用列表与元组记录  
2.#用常量记录  
3.SHAPES = {  
4.    "Z": [(-1, -1), (0, -1), (0, 0), (1, 0)],  
5.    "O": [(-1, -1), (0, -1), (-1, 0), (0, 0)],  
6.    "S": [(-1, 0), (0, 0), (0, -1), (1, -1)],  
7.    "T": [(-1, 0), (0, 0), (0, -1), (1, 0)],  
8.    "I": [(0, 1), (0, 0), (0, -1), (0, -2)],  
9.    "L": [(-1, 0), (0, 0), (-1, -1), (-1, -2)],  
10.    "J": [(-1, 0), (0, 0), (0, -1), (0, -2)]  
11.}  
12.# 定义各种形状的颜色  
13.SHAPESCOLOR = {  
14.    "O": "blue",  
15.    "Z": "Cyan",  
16.    "S": "red",  
17.    "T": "yellow",  
18.    "I": "green",  
19.    "L": "purple",  
20.    "J": "orange",  
21.}  

将原来绘制O型俄罗斯方块处的代码改成如下代码,将这七种俄罗斯方块绘制出来

1.draw_cells(canvas, 3, 3, SHAPES['O'], SHAPESCOLOR['O'])  
2.draw_cells(canvas, 3, 8, SHAPES['S'], SHAPESCOLOR['S'])  
3.draw_cells(canvas, 3, 13, SHAPES['T'], SHAPESCOLOR['T'])  
4.draw_cells(canvas, 8, 3, SHAPES['I'], SHAPESCOLOR['I'])  
5.draw_cells(canvas, 8, 8, SHAPES['L'], SHAPESCOLOR['L'])  
6.draw_cells(canvas, 8, 13, SHAPES['J'], SHAPESCOLOR['J'])  
7.draw_cells(canvas, 5, 18, SHAPES['Z'], SHAPESCOLOR['Z'])  

Python课程设计之俄罗斯方块

界面动起来

要让游戏界面动起来,需要实现两点:1、定时刷新页面 2、移动页面内部的俄罗斯方块。光实现1的话理论上页面也算动起来了,但是如果界面内容不变,每次新的页面和旧的界面看起来是一样的,给人的观看感觉跟没有动没有区别,所以必须要实现2,来更改界面内容,给人“动”起来的感觉

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

1.FPS = 500  # 刷新页面的毫秒间隔  
2.def game_loop():  
3.    win.update()  
4.   
5.    # ===用于展示刷新,后续会删掉===  
6.    import time  
7.    print(time.ctime())  
8.    # ===========================  
9.   
10.    win.after(FPS, game_loop)  
11.   
12.win.update()  
13.win.after(FPS, game_loop) # 在FPS 毫秒后调用 game_loop方法 

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

Python课程设计之俄罗斯方块

但是每次刷新后页面的内容是没有变化的,给人的感觉还是更没动一样,所以需要配合每次刷新,移动俄罗斯方块的位置
(2)、移动俄罗斯方块
对于某个俄罗斯方块,要绘制出来需要知道它的位置和类型,以及内部的各个方格。
这三个数据可以用字典存起来,这里规定格式如下

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

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

1.# 在draw_blank_board(canvas)语句下面添加如下语句  
2.def draw_block_move(canvas, block, direction=[0, 0]):  
3.    """ 
4.    绘制向指定方向移动后的俄罗斯方块 
5.    canvas: 画板 
6.    block: 俄罗斯方块对象 
7.    direction: 俄罗斯方块移动方向 
8.    ""#把方块里面所有信息取出来
9.    shape_type = block['kind']  
10.    c, r = block['cr']  
11.    cell_list = block['cell_list']  
12.   
13.    # 移动前,先清除原有位置绘制的俄罗斯方块,也就是用背景色绘制原有的俄罗斯方块  
14.    draw_cells(canvas, c, r, cell_list)  
15.     #移动,按照指定方向移动 
16.    dc, dr = direction
17.    new_c, new_r = c+dc, r+dr  
18.    block['cr'] = [new_c, new_r]  #把更新后的信息存在方块对象里面
19.    # 在新位置绘制新的俄罗斯方块就好  
20.    draw_cells(canvas, new_c, new_r, cell_list, SHAPESCOLOR[shape_type])  
21.   
22.   
23.a_block = {  
24.    'kind': 'O',  # 对应俄罗斯方块的类型  
25.    'cell_list': SHAPES['O'],  # 对应俄罗斯方块的各个方格  
26.    'cr': [3, 3]  # 对应横纵坐标,以左上角为原点,水平向右为横坐标轴正方向,竖直向下为纵坐标轴正方向  
27.}  
28.   
29.draw_block_move(canvas, a_block)  
30.   
31.   
32.# 修改原来的game_loop方法如下  
33.def game_loop():  
34.    win.update()  
35.   
36.    down = [0, 1]  
37.    draw_block_move(canvas, a_block, down)  
38.   
39.    win.after(FPS, game_loop)  

Python课程设计之俄罗斯方块
Python课程设计之俄罗斯方块

生成、移动、固定、变形

(1)、随机生成俄罗斯方块
这里需要导入python自带的随机库random,使用其中的choice方法,从俄罗斯方块形状列表中随机选出一个。
首先需要删除原来的位于game_loop方法上面的a_block = … 和draw_block_move(canvas, a_block)这2段代码(这两端代码俄罗斯方块是在固定位置,按照指定形状生成的,需要删掉这部分代码),然后再在原来的这2段代码所在位置,添加一个随机生成俄罗斯方块的方法generate_new_block

1.def generate_new_block():  
2.    # 随机生成新的俄罗斯方块  
3.   #使用choice方法在方块形状列表中随机选取一个
4.    kind = random.choice(list(SHAPES.keys()))  
5.    # 对应横纵坐标,以左上角为原点,水平向右为x轴正方向,  
6.    # 竖直向下为y轴正方向,x对应横坐标,y对应纵坐标  
7.    cr = [C // 2, 0]  #设置初始的行列,在第一行的正中间
8.    new_block = {  
9.        'kind': kind,  # 对应俄罗斯方块的类型  
10.        'cell_list': SHAPES[kind],  
11.        'cr': cr  
12.    }  
13.   
14.    return new_block  

再将游戏运行方法game_loop修改成如下,其中,将当前的俄罗斯方块对象通过全局变量来存储,并在game_loop方法下面设置初始的俄罗斯方块为空(None),此时每次运行代码都会发现生成了随机的俄罗斯方块。

1.def game_loop():  
2.    win.update()  
3.    global current_block  #获取全局变量
4.    if current_block is None:  #如果它不存在,就生成,并原地绘制
5.        new_block = generate_new_block()  
6.        # 新生成的俄罗斯方块需要先在生成位置绘制出来  
7.        draw_block_move(canvas, new_block)  
8.        current_block = new_block  
9.    else:  #否则向下移动这个方块对象
10.        draw_block_move(canvas, current_block, [0, 1])  
11.   
12.    win.after(FPS, game_loop)  
13.   
14.current_block = None  

Python课程设计之俄罗斯方块

Python课程设计之俄罗斯方块

当然,此时还有问题没有解决,就是俄罗斯方块生成后,会一直往下移动,就算出了可视范围还是会往下移动(只是这时再也看不到了)。所以接下来要实现的是:当俄罗斯方块落地的时候,将它固定住,然后再去生成新的。
(2)、固定已经失效的俄罗斯方块
判断俄罗斯方块落地的原则是,该方块是否可以继续向下移动:这里首先需要的是一个方法check_move需要判断俄罗斯方块是否可以向指定位置移动,该generate_new_block方法的下面,添加check_move方法代码如下

1.def check_move(block, direction=[0, 0]):#当方块落地时进行固定,然后生成新的方块
2.    """ 
3.        判断俄罗斯方块是否可以朝制定方向移动 
4.        block: 俄罗斯方块对象 
5.        direction: 俄罗斯方块移动方向 
6.        boolean 是否可以朝制定方向移动 
7.        """  
8.    cc, cr = block['cr']  #先取出方块行列坐标
9.    cell_list = block['cell_list']  #内部各个格子相对自身的坐标行列
10.   
11.    for cell in cell_list:  
12.        cell_c, cell_r = cell  
13.        c = cell_c + cc + direction[0]  
14.        r = cell_r + cr + direction[1]  
15.        # 判断该位置是否超出左右边界,以及下边界  
16.        # 一般不判断上边界,因为俄罗斯方块生成的时候,可能有一部分在上边界之上还没有出来  
17.        if c < 0 or c >= C or r >= R:  
18.            return False  
19.   
20.    return True  

再将游戏运行方法game_loop修改成如下,便可以每次俄罗斯方块落地后都会生成新的

1.def game_loop():  
2.    win.update()  
3.    global current_block  #获取全局变量
4.   
5.    if current_block is None:  #如果它不存在,就生成,并原地绘制
6.        new_block = generate_new_block()  
7.        # 新生成的俄罗斯方块需要先在生成位置绘制出来  
8.        draw_block_move(canvas, new_block)  
9.        current_block = new_block  #并且设置当前的方块为新生成的对象
10.    else:  #否则向下移动这个方块对象
11.        if check_move(current_block, [0, 1]):#添加这个方法可以判断是否可以向下移动
12.            draw_block_move(canvas, current_block, [0, 1])  
13.        else:  
14.            current_block = None  
15.   
16.    win.after(FPS, game_loop)  

Python课程设计之俄罗斯方块

此时仍然有个问题就是老的俄罗斯方块会被新的落地的俄罗斯方块重合。

Python课程设计之俄罗斯方块

这个需要处理,当俄罗斯方块发现下面有已固定的俄罗斯方块时,也不能移动。首先,我们需要添加一个变量block_list来记录已固定的俄罗斯方块。在原代码draw_blank_board(canvas)的位置的下面,添加如下代码

1.block_list = []  #建立一个变量,计入已经固定的方块,使其不会重叠,先生成初始的
2.for i in range(R):  #由空字符串,由R行C列组成的一个二维列表
3.    i_row = ['' for j in range(C)]  
4.    block_list.append(i_row)  
然后再在固定俄罗斯方块的时候记录进去,所以一要添加一个save_block_to_list方法,将无法移动的俄罗斯方块记录进去。二要修改game_loop
1.def save_block_to_list(block):  #计入无法移动的方块
2.    shape_type = block['kind']  
3.    cc, cr = block['cr']  
4.    cell_list = block['cell_list']  
5.   
6.    for cell in cell_list: #在对应的行对应的列记录方块类型
7.        cell_c, cell_r = cell  
8.        c = cell_c + cc  
9.        r = cell_r + cr  
10.        # block_list 在对应位置记下其类型,也就是对应的字符串
11.        block_list[r][c] = shape_type  
12.   
13.   #定义一个方法不断去刷新这个页面
14.def game_loop():  
15.    win.update()  
16.    global current_block  #获取全局变量
17.    if current_block is None:  #如果它不存在,就生成,并原地绘制
18.        new_block = generate_new_block()  
19.        # 新生成的俄罗斯方块需要先在生成位置绘制出来  
20.        draw_block_move(canvas, new_block)  
21.        current_block = new_block  #并且设置当前的方块为新生成的对象
22.    else:  #否则向下移动这个方块对象
23.        if check_move(current_block, [0, 1]): #添加这个方法判断是否可以向下移动 
24.            draw_block_move(canvas, current_block, [0, 1])  
25.        else:  
26.            # 无法移动,记入 block_list 中  
27.            save_block_to_list(current_block)  
28.            current_block = None  #就让当前方块为None
29.   
30.    win.after(FPS, game_loop)  

然后还要再修改原来的check_move方法,就是发现下面有已固定的俄罗斯方块时,也不能移动。

1.def check_move(block, direction=[0, 0]):  
2.    """ 
3.        判断俄罗斯方块是否可以朝制定方向移动 
4.        block: 俄罗斯方块对象 
5.        direction: 俄罗斯方块移动方向 
6.        boolean 是否可以朝制定方向移动 
7.        """  
8.    cc, cr = block['cr']  
9.    cell_list = block['cell_list']  
10.   
11.    for cell in cell_list:  
12.        cell_c, cell_r = cell  
13.        c = cell_c + cc + direction[0]  
14.        r = cell_r + cr + direction[1]  
15.        # 判断该位置是否超出左右边界,以及下边界  
16.        # 一般不判断上边界,因为俄罗斯方块生成的时候,可能有一部分在上边界之上还没有出来  
17.        if c < 0 or c >= C or r >= R:  
18.            return False  
19.   
20.        # 必须要判断r不小于0才行,具体原因你可以不加这个判断,试试会出现什么效果  
21.        if r >= 0 and block_list[r][c]:  
22.            return False  
23.   
24.    return True  

Python课程设计之俄罗斯方块

(3)、左右移动俄罗斯方块
首先,需要新建一个左右移动俄罗斯方块的方法horizontal_move_block,其中的参数event对应键鼠事件,在save_block_to_list方法下面添加horizontal_move_block方法的代码如下

1.def horizontal_move_block(event):  #新建一个方法,左右移动方块
2.    """ 
3.    左右水平移动俄罗斯方块 
4.    """  
5.    direction = [0, 0]  #默认方向为0
6.    if event.keysym == 'Left':  #如果按键为left,方向向左移动一个
7.        direction = [-1, 0]  
8.    elif event.keysym == 'Right':  #如果按键为right,方向向右移动一个
9.        direction = [1, 0]  
10.    else:  
11.        return  
12.   
13.    global current_block  #获取当前方块对象,如果不为空,且可以向这个方向移动
14.    if current_block is not None and check_move(current_block, direction):  
15.        draw_block_move(canvas, current_block, direction)  #移动绘制它

然后把键盘上的左右键绑定(bind)这个方法,代码如下

1.# 在game_loop方法(之外)下面添加  
2.canvas.focus_set() # 聚焦到canvas画板对象上  
3.canvas.bind("<KeyPress-Left>", horizontal_move_block)  
4.canvas.bind("<KeyPress-Right>", horizontal_move_block)  

此时运行,就可以按左右方向键来移动俄罗斯方块了

Python课程设计之俄罗斯方块

Python课程设计之俄罗斯方块
Python课程设计之俄罗斯方块

(4)、变换俄罗斯方块
左右键是移动俄罗斯方块,上下键我们则实现变换俄罗斯方块。按上键俄罗斯方块会进行顺时针九十度旋转。按下键俄罗斯方块会进行顺时针九十度旋转,这里需要添加旋转俄罗斯方块的方法rotate_block,以及让俄罗斯方块着陆的方法land,在horizontal_move_block方法下面添加rotate_block方法的代码如下

1.def rotate_block(event):  #新建一个方法旋转方块,并且响应键鼠事件
2.    global current_block  #获取当前方块对象
3.    if current_block is None:  #作非空判断
4.        return  
5.   #在方块里面的所有方格做一个旋转变换
6.    cell_list = current_block['cell_list']  
7.    rotate_list = []  
8.    for cell in cell_list:  
9.        cell_c, cell_r = cell  
10.        rotate_cell = [cell_r, -cell_c]  
11.        rotate_list.append(rotate_cell)  
12.   #然后新建一个旋转之后的方块对象
13.    block_after_rotate = {  
14.        'kind': current_block['kind'],  # 对应俄罗斯方块的类型  
15.        'cell_list': rotate_list,  #对应方块的各个方格坐标
16.        'cr': current_block['cr']  #对应的列与横,水平向右为列坐标,竖直向下为行坐标正方向
17.    }  #这个字典可看作方块对象
18.   
19.    if check_move(block_after_rotate):  #判断是否可以进行旋转
20.        cc, cr= current_block['cr']  
21.        draw_cells(canvas, cc, cr, current_block['cell_list'])  #清除原有的方块,用默认颜色替换
22.        draw_cells(canvas, cc, cr, rotate_list,SHAPESCOLOR[current_block['kind']])  #绘制旋转之后的方块
23.        current_block = block_after_rotate  #更改当前方块对象为旋转之后的
24.   
25. 新建一个方法用于方块着路
26.def land(event):  
27.    global current_block  #获取当前方块对象
28.    if current_block is None:  #做个非空判断
29.        return  
30.   #获取当前方块里面所有方格向下移动的最大行数,取其中最小的
31.    cell_list = current_block['cell_list']  
32.    cc, cr = current_block['cr']  
33.    min_height = R  
34.    for cell in cell_list:  
35.        cell_c, cell_r = cell  
36.        c, r = cell_c + cc, cell_r + cr  
37.        if block_list[r][c]:  
38.            return  
39.        h = 0  
40.        for ri in range(r+1, R):  #对应的方格从上到下遍历它
41.            if block_list[ri][c]: #如果下面已经有固定的则退出 
42.                break  
43.            else:  
44.                h += 1  #否则可向下移动的行数+1
45.        if h < min_height:  #如果这个方格比之前可移动的行数小,则更新这个最小值
46.            min_height = h  
47.   
48.    down = [0, min_height]  
49.    if check_move(current_block, down):  #移动判断
50.        draw_block_move(canvas, current_block, down)  

然后再在上一步绑定左右方向键的地方添加下面这行代码,让上键绑定(bind)这个方法

1.canvas.bind("<KeyPress-Up>", rotate_block)  
2.canvas.bind("<KeyPress-Down>", land)  

Python课程设计之俄罗斯方块

Python课程设计之俄罗斯方块

消除与得分

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

1.# 绘制面板,也就是空白画板背景
2.def draw_board(canvas, block_list):  
3.    for ri in range(R):  #遍历所有行
4.        for ci in range(C):  #遍历每一行的所有列
5.            cell_type = block_list[ri][ci]  #取出当前位置对应的值
6.            if cell_type:  #如果有方块,则按照对应的颜色绘制它
7.                draw_cell_by_cr(canvas, ci, ri, SHAPESCOLOR[cell_type])  
8.            else:  #否则,使用默认的青灰色绘制
9.                draw_cell_by_cr(canvas, ci, ri)  #调用绘制函数
10.   
11.   
12.# 新建一个方法,判断指定行是否已经可以清除
13.def check_row_complete(row):  
14.    for cell in row:  
15.        if cell=='':  
16.            return False  
17.   
18.    return True  
19.   
20.   
21.score = 0  
22.win.title("SCORES: %s" % score) # 窗口标题中展示分数  
23.   
24.   #新建一个方法,去检查并且清除
25.def check_and_clear():  
26.    has_complete_row =False  
27.    for ri in range(len(block_list)):  
28.        if check_row_complete(block_list[ri]):  
29.            has_complete_row = True  
30.            # 当前行可消除  
31.            if ri > 0:  #如果不是第一行,就让当前行等于上一行
32.                for cur_ri in range(ri, 0, -1):  #从上往下遍历
33.                    block_list[cur_ri] = block_list[cur_ri-1][:]  
34.        block_list[0] = ['' for j in range(C)]  
35.            else:  #如果为第一行,就使用空行绘制
36.                block_list[ri] = ['' for j in range(C)]  
37.            global score  #每删除一行增加10分
38.            score += 10  
39.   
40.    if has_complete_row:  #如果检查发现所有行被删除,则需要重新绘制画板
41.        draw_board(canvas, block_list)  
42.   
43.        win.title("SCORES: %s" % score)  #并修改标题得分

同时将原有的这两行代码

1.draw_blank_board(canvas)  
2.   
3.block_list = []  
4.for i in range(R):  
5.    i_row = ['' for j in range(C)]  
6.    block_list.append(i_row) 

修改成

1.block_list = []  
2.for i in range(R):  
3.    i_row = ['' for j in range(C)]  
4.    block_list.append(i_row)  
5.   
6.draw_board(canvas, block_list)  

再在game_loop方法内部的current_block = None语句后添加下面语句

1.check_and_clear()  

Python课程设计之俄罗斯方块

Python课程设计之俄罗斯方块

一般来说,当新的俄罗斯方块无法移动时,游戏就算游戏结束了。这里的判断机制是,新生成的俄罗斯方块已经无法在出生点放置了,也就是出生点都已经被之前的固定的方块占用了,就算游戏结束。在代码文件开头添加

1.from tkinter import messagebox  #用于弹窗提醒

再修改game_loop方法如下

1.def game_loop():  
2.    win.update()  
3.    global current_block  
4.    if current_block is None:  
5.        new_block = generate_new_block()  
6.        # 新生成的俄罗斯方块需要先在生成位置绘制出来  
7.        draw_block_move(canvas, new_block)  
8.        current_block = new_block  
9.        if not check_move(current_block, [0, 0]):#如果新生成的方块无法在出生点放置,也就是出身点被占有
10.            messagebox.showinfo("Game Over!", "Your Score is %s" % score)  
11.              #第一个字符串是弹窗提醒,第二个字符串是弹窗内容
12.            win.destroy()  #弹窗关闭后,销毁游戏界面
13.            return  #并退出游戏循环
14.    else:  #否则直接向下移动这个方块对象
15.        if check_move(current_block, [0, 1]):#添加这个方法判断是否可以向下移动
16.            draw_block_move(canvas, current_block, [0, 1])  
17.        else:  
18.            # 无法移动,记入 block_list 中  
19.            save_block_to_list(current_block)  
20.            current_block = None  #就让当前的方块为None
21.            check_and_clear()  #调用清除与得分函数
22.   
23.    win.after(FPS, game_loop)  

Python课程设计之俄罗斯方块文章来源地址https://www.toymoban.com/news/detail-490115.html

到了这里,关于Python课程设计之俄罗斯方块的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 免费分享一套Python俄罗斯方块源码 PyQt5俄罗斯方块源码,太好玩了~

    大家好,我是java1234_小锋老师,看到一个不错的Python俄罗斯方块源码 PyQt5俄罗斯方块源码,分享下哈。 【免费】Python俄罗斯方块源码 PyQt5俄罗斯方块源码 Python小游戏源码_哔哩哔哩_bilibili 【免费】Python俄罗斯方块源码 PyQt5俄罗斯方块源码 Python小游戏源码项目来自互联网,免

    2024年01月25日
    浏览(47)
  • python制作俄罗斯方块

    作者简介 :一名后端开发人员,每天分享后端开发以及人工智能相关技术,行业前沿信息,面试宝典。 座右铭 :未来是不可确定的,慢慢来是最快的。 个人主页 :极客李华-CSDN博客 合作方式 :私聊+ 这个专栏内容 :BAT等大厂常见后端java开发面试题详细讲解,更新数目10

    2024年02月12日
    浏览(51)
  • 用python制作俄罗斯方块

    代码如下,可以直接运行:

    2024年02月11日
    浏览(53)
  • python基础项目实战-俄罗斯方块

    一、俄罗斯方块游戏设计分析: 俄罗斯方块是一款风靡全球,从一开始到现在都一直经久不衰的电脑、手机、掌上游戏机产品,是一款游戏规则简单,但又不缺乏乐趣的简单经典小游戏,上手容易,适用范围广泛,人所共知。俄罗斯方块游戏基本规则是油4个小方块组成的7种不

    2024年02月12日
    浏览(44)
  • 用python写一个俄罗斯方块程序

    2024年04月23日
    浏览(41)
  • python实现俄罗斯方块【含代码和讲解】

    Python实现俄罗斯方块:打造经典游戏的代码实现教程 俄罗斯方块是世界上最受欢迎的电子游戏之一,源自俄罗斯。这是一个简单却富有挑战和乐趣的游戏,让玩家必须思考如何将各种形状的积木放入底部的平面上,以便完整地填满一行或多行,每填满一行就会消失并获得分数

    2024年02月11日
    浏览(53)
  • 软件设计实战:基于Java的俄罗斯方块游戏【完整版】

     个人简介 👨🏻‍💻个人主页:陈橘又青 🏃🏻‍♂️博客记录心情,代码编写人生。 🌟如果文章对你有用,麻烦关注点赞收藏走一波,感谢支持! 🌱强力推荐我平时学习编程和准备面试的刷题网站:点这里! 前言 大家好,今天用Java编程实现一个GUI界面的经典俄罗斯方

    2024年02月02日
    浏览(43)
  • Python小项目俄罗斯方块代码基于pygame编写

    python实习作业或者期末作业,俄罗斯方块,基于pygame编写 有很多小伙伴想要找一些小项目练练手,下面是我在闲暇时写的一个俄罗斯方块的一个小游戏,它是基于pygame板块来实现的 这是它的首页界面 然后这里是它的运行界面 总共有四个速度等级,分别对应四种不同的速度,

    2023年04月08日
    浏览(39)
  • Python 竟能开发如此精美的俄罗斯方块【附源码】

    1、案例介绍 俄罗斯方块是由 4 个小方块组成不同形状的板块,随机从屏幕上方落下,按方向键调整板块的位置和方向,在底部拼出完整的一行或几行。这些完整的横条会消失,给新落下来的板块腾出空间,并获得分数奖励。没有被消除掉的方块不断堆积,一旦堆到顶端,便

    2024年02月12日
    浏览(43)
  • 基于STM32F407的俄罗斯方块小游戏的设计

        本文讲述的是基于STM32F407的俄罗斯方块小游戏的设计思路和测试结果,具体的代码分析见文章 基于STM32F407的俄罗斯方块游戏代码分析_钻仰弥坚的博客-CSDN博客 1.1 可行性分析 可行性分析能够对新系统进行各方面的分析与研究,确定新系统是否具有开发的可行性和必要性

    2024年02月11日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包