Python开发俄罗斯方块游戏(自学记录)

参考:(https://gitbook.cn/gitchat/column/5b1a31bc862a01660e35955c/topic/5b1a86c33d723c686c3101ed)
2019-06-18

任务:绘制方块(1.定义各种方块的表示方法(类属性);2.绘制每个方块)

1.定义方块的表示方法

俄罗斯方块游戏中有七种方块,我们可以用七个大写字母表示它们:J、L、S、Z、I、T、O.
我们定义一个Piece类来表示方块,这个Piece类带有两个属性:shape表示是七种方块的哪一个方块;screen表示屏幕对象。(新建piece.py文件)

class Piece():
    def __init__(self, shape, screen):
        self.x = 3
        self.y = 0
        self.shape = shape
        self.screen = screen

类名称的第一个字母最好大写,否则与文件名piece重复。知识点: Python 语言的类定义内部,赋值给属性 t 或者访问属性 t 的值,都要写作 self.t。调用方法 m,要写作 self.m。
接下来有三个问题:
1.如何记住方块的类型?
2.如何根据方块类型得出方块形状?
3.如何在游戏区域定位方块?

1.如何记住方块的类型?

我们已经创建了piece.py的文件,定义了Piece类属性,则在main.py中加入

from piece import Piece

表示引入了Piece类,并将要画方块的类型赋给piece变量:

piece = Piece('S', screen)

'S' 代表的是方块的类型;screen 是绘制方块时会用到的屏幕对象。这里'S'可以换为TLJ等其它类型。以下用'S'类型作为例子。

2.如何根据方块类型得出方块形状?

首先定义每个类型的形状矩阵,例如'S'可以这样定义:

S_SHAPE_TEMPLETE = ['.OO.',
                    'OO..',
                    '....']

大写字母O表示此处有小方块,'.'表示此处为空。
参照下图想象以下:


图1.jpg

故定义七种方块类型的形状矩阵:

S_SHAPE_TEMPLETE = ['.OO.',
                    'OO..',
                    '....']
I_SHAPE_TEMPLETE = ['.O..',
                    '.O..,'
                    '.O..',
                    '.O..']
Z_SHAPE_TEMPLETE = ['OO..',
                    '.OO.',
                    '....']
T_SHAPE_TEMPLETE = ['.O..',
                    'OOO.',
                    '....']
L_SHAPE_TEMPLETE = ['.O..',
                    '.O..',
                    '.OO.',]
J_SHAPE_TEMPLETE = ['..O.',
                    '..O.',
                    '.OO.']
O_SHAPE_TEMPLETE = ['.OO',
                    '.OO',
                    '...']

定义字典PIECES: 键为表示每个形状的字母,值为上边定义的形状矩阵。

PIECES = {'S':S_SHAPE_TEMPLETE,
                  'I':  I_SHAPE_TEMPLETE,
                  'Z':Z_SHAPE_TEMPLETE,
                  'T':T_SHAPE_TEMPLETE,
                  'L':L_SHAPE_TEMPLETE,
                  'J':J_SHAPE_TEMPLETE,
                  'O':O_SHAPE_TEMPLETE}

形状矩阵和字典都可以写在settings.py中,这里放的都是常量,调用时开头加一句:

from settings import *

3.如何在游戏区域定位方块?

想让'S'方块处于图中这样的位置

图2.jpg

需让x=3,y=0。(下面解释为什么)x的范围是09,y的范围是019.这样'S'方块的定位点是第一行第四列,由于'S'的形状矩阵为:

['.OO.',
 'OO..',
 '....']

且'O'画 '.'不画,所以画出的'S'的四个小方块分别在一行五列、一行六列、二行四列、二行五列,如图2。

Piece类完整代码:

from settings import *
import pygame
class Piece():
    def __init__(self, shape, screen):
        self.x = 3
        self.y = 0
        self.shape = shape
        self.screen = screen
    def paint(self):
        shape_templete = PIECES[self.shape]
        for r in range(len(shape_templete)):
            for c in range(len(shape_templete[0])):
                if shape_templete[r][c] == 'O':
                    self.draw_cell(self.x+c,self.y+r)
    def draw_cell(self, x, y):
        cell_position = (x * CELL_WIDTH + GAME_AREA_LEFT + 1, 
                                 y * CELL_WIDTH + GAME_AREA_TOP + 1)
        cell_width_height = (CELL_WIDTH - 2, CELL_WIDTH - 2)
        cell_rect = pygame.Rect(cell_position, cell_width_height)
        pygame.draw.rect(self.screen, CELL_COLOR, cell_rect)

paint()用作方块绘制,首先self.shape存储的是

piece = Piece('S', screen) #回看“1.如何记住方块的类型?”

中Piece类所带有的shape属性,也就是'S',故

shape_templete = PIECES[self.shape]

中 shape_templete表示的是PIECES字典中的键'S'对应的值S_SHAPE_TEMPLETE,对照形状矩阵可得:

S_SHAPE_TEMPLETE = ['.OO.',
                    'OO..',
                    '....']

是一个列表。
而这两句:

        for r in range(len(shape_templete)):
            for c in range(len(shape_templete[0])):

表示先按行(raw),再按列(column)依次遍历列表 S_SHAPE_TEMPLETE,遍历顺序为:0行0列、0行1列、0行2列、0行3列、1行0列、1行1列......。这样更易理解:

#                    行           0           1         2
#                    列        0123   0123   0123
S_SHAPE_TEMPLETE = ['.OO.', 'OO..', '. . . .']

之后进行判断,如果某行某列为'O',则这个位置要画小方块,调用draw_cell()画。
定义draw_cell():有两个属性x,y,实际上和上次绘制小方块函数差不多,都要定左上角点,定宽度高度,再画方块。
解释需让x=3,y=0:对于形状'S',paint()中遍历'O'所在行列,遍历到的第一个行列值为r=0,c=1,所以paint()中调用draw_cell(4, 0).
带入draw_cell()中,可以绘制这样一个小方块:
1.左上角坐标(4CELL_WIDTH + GAME_AREA_LEFT + 1, 0CELL_WIDTH + GAME_AREA_TOP + 1).至于每个都加1像素,可以试试去掉后什么效果。
2.该方块长宽都为CELL_WIDTH - 2.至于减2,也可以去掉试试。
绘制出这样的效果:(我把加1、减2去掉了)

Python开发俄罗斯方块游戏(自学记录)_第1张图片
图3.jpg

对比图2看看。
最后两句显然是1.构建矩形对象2.填充矩形对象。
main()中

 while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
        screen.fill(bg_color)
        draw_game_area(screen)
       # draw_cell(screen, GAME_AREA_LEFT + CELL_WIDTH * 4, GAME_AREA_TOP)
        piece.paint() #加入此句绘制“piece = Piece('S', screen)”中规定的方块
        pygame.display.flip()

修改为:

piece = Piece('T', screen)

则有


Python开发俄罗斯方块游戏(自学记录)_第2张图片
图4.jpg

明天继续!

你可能感兴趣的:(Python开发俄罗斯方块游戏(自学记录))