Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用pygame的python俄罗斯方块游戏_Python - Fatal编程技术网

使用pygame的python俄罗斯方块游戏

使用pygame的python俄罗斯方块游戏,python,Python,我刚刚用pygame用python实现了一个非常初级的俄罗斯方块游戏,希望任何人都能对我提出建设性的批评 这是我的第一个相当长的程序,所以肯定会有bug。我也无法完全理解pygame事件处理,所以键盘控制可能会有问题,但请尝试一下 任何建设性的批评或建议都将受到高度重视 ############################################################################### ## an implementation of a ***very*

我刚刚用pygame用python实现了一个非常初级的俄罗斯方块游戏,希望任何人都能对我提出建设性的批评

这是我的第一个相当长的程序,所以肯定会有bug。我也无法完全理解pygame事件处理,所以键盘控制可能会有问题,但请尝试一下

任何建设性的批评或建议都将受到高度重视

###############################################################################
## an implementation of a ***very*** basic tetris game in python using pygame
###############################################################################
'''rotate --- r
   pause ---- p
   direction buttons for movement'''


import sys
import pygame
import random

size = width, height = 200, 400
color = {'black': (0, 0, 0), 'white':(255, 255, 255)}
sqrsize = 20
occupied_squares = []
top_of_screen = (0, 0)
top_x, top_y = top_of_screen[0], top_of_screen[1]
num_block = 4
pen_size = 1
mov_delay, r_delay = 300, 50
board_centre = 80
no_move = 0
events = {276: 'left', 275: 'right', 112: 'pause'}


pygame.init()
screen = pygame.display.set_mode(size)
background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((color['white']))
screen.blit(background, top_of_screen)
pygame.display.flip()


def tetris():
    ''' this is the controller of the whole game for now, maybe changed
    later on as game architecture changes.'''
    global mov_delay
while True:
    curr_shape = create_newshape(board_centre)
    l_of_blcks_ind = blck_x_axis = 0
    shape_name_ind = blck_y_axis = 1

    move_dir = 'down' #default move direction
    game = 'playing'  #default game state play:- is game paused or playing

    shape_blcks = [pygame.Rect(block[blck_x_axis], block[blck_y_axis],
        sqrsize, sqrsize) for block in curr_shape[l_of_blcks_ind]]
    if legal(shape_blcks):
        draw_shape(shape_blcks)
    else:
        break  #game over
    while True:
        if game == 'paused':
            for event in pygame.event.get(pygame.KEYDOWN):
                if event.key == pygame.K_p:
                    game = 'playing'            
        else:
            for event in pygame.event.get((pygame.KEYDOWN, pygame.KEYUP,
                                           pygame.QUIT)):
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_DOWN:
                        mov_delay = 50
                        continue
                    elif event.key == pygame.K_r:
                        shape_blcks = rotate(shape_blcks, curr_shape[shape_name_ind])
                        draw_shape(shape_blcks)
                        pygame.time.delay(r_delay)
                        continue

                    elif event.key == pygame.K_p:
                        game = 'paused'
                        move_dir = events[event.key]
                        break

                    else:
                        if event.key in events.keys():
                            mov_delay = 50
                            move_dir = events[event.key]
                            move (shape_blcks, move_dir)   
                            draw_shape(shape_blcks)
                            pygame.time.delay(mov_delay) 
                            continue  
                elif event.type == pygame.KEYUP:
                    if mov_delay != 300:
                        mov_delay = 300
                    move_dir  = 'down'        
            moved = move(shape_blcks, move_dir)
            draw_shape(shape_blcks)
            pygame.time.delay(mov_delay)

            '''if block did not move and the direction for movement is down
            then shape has come to rest so we can exit loop and then a new
            shape is generated. if direction for movement is sideways and
            block did not move it should be moved down rather'''
            if not moved and move_dir == 'down':
                for block in shape_blcks:
                    occupied_squares.append((block[blck_x_axis],
                                             block[blck_y_axis]))
                break
            else:
                draw_shape(shape_blcks)
                pygame.time.delay(mov_delay)
            for row_no in range (height - sqrsize, 0, -sqrsize):
                if row_filled(row_no):
                    delete_row(row_no)


def draw_shape(shp_blcks):
'''this draws list of blocks or a block to the background and blits
background to screen'''
if isinstance(shp_blcks, list):
    for blck in shp_blcks:
        pygame.draw.rect(background, color['black'], blck, pen_size)
else:
    pygame.draw.rect(background, color['black'], shp_blcks, pen_size)
screen.blit(background, top_of_screen)
pygame.display.update()


def row_filled(row_no):
'''check if a row is fully occupied by a shape block'''
for x_coord in range(0, width, sqrsize):
    if (x_coord, row_no) in occupied_squares:
        continue
    else:
        return False
return True


def delete_row(row_no):
'''removes all squares on a row from the occupied_squares list and then
moves all square positions which have y-axis coord less than row_no down
board'''
global occupied_squares
new_buffer = []
x_coord, y_coord = 0, 1
background.fill(color['white'])
for sqr in occupied_squares:
    if sqr[y_coord] != row_no:
        new_buffer.append(sqr)
occupied_squares = new_buffer
for index in range(len(occupied_squares)):
    if occupied_squares[index][y_coord] < row_no:
        occupied_squares[index] = (occupied_squares[index][x_coord],
                                occupied_squares[index][y_coord] + sqrsize)
for sqr in occupied_squares:
    rect = pygame.Rect(sqr[x_coord], sqr[y_coord], sqrsize, sqrsize)
    draw_shape(rect)


def move(shape_blcks, direction):
'''input:- list of blocks making up a tetris shape
output:- list of blocks making up a tetris shape
function moves the input list of blocks that make up shape and then checks
that the  list of blocks are all in positions that are valide. position is
valid if it has not been occupied previously and is within the tetris board.
If move is successful, function returns the moved shape and if move is not
possible, function returns a false'''
directs = {'down':(no_move, sqrsize), 'left':(-sqrsize, no_move),
    'right':(sqrsize, no_move), 'pause': (no_move, no_move)}
delta_x, delta_y = directs[direction]
for index in range(num_block):
    shape_blcks[index] = shape_blcks[index].move(delta_x, delta_y)

if legal(shape_blcks):
    for index in range(num_block):
        background.fill((color['white']), shape_blcks[index].move(-delta_x,
                                                                  -delta_y))
    return True
else:
    for index in range(num_block):
        shape_blcks[index] = shape_blcks[index].move(-delta_x, -delta_y)
    return False


def legal(shape_blcks):
'''input: list of shape blocks
checks whether a shape is in a legal portion of the board as defined in the
doc of 'move' function'''
blck_x_axis, blck_y_axis = 0, 1
for index in range(num_block):
    new_x, new_y = (shape_blcks[index][blck_x_axis],
                    shape_blcks[index][blck_y_axis])

    if (((new_x, new_y) in occupied_squares or new_y >= height) or
        (new_x >= width or new_x < top_x)): #probly introduced a bug by removing the check for shape being less that y-axis origin 
        return False
return True


def create_newshape(start_x=0, start_y=0):
'''A shape is a list of four rectangular blocks.
Input:- coordinates of board at which shape is to be created
Output:- a list of the list of the coordinates of constituent blocks of each
shape relative to a reference block and shape name. Reference block  has
starting coordinates of start_x and start_y. '''
shape_names = ['S', 'O', 'I', 'L', 'T']
shapes = {'S':[(start_x + 1*sqrsize, start_y + 2*sqrsize),
    (start_x, start_y), (start_x, start_y + 1*sqrsize),(start_x + 1*sqrsize,
                                                start_y + 1*sqrsize)],

    'O':[(start_x + 1*sqrsize, start_y + 1*sqrsize), (start_x, start_y),
        (start_x, start_y + 1*sqrsize), (start_x + 1*sqrsize, start_y)],

    'I':[(start_x, start_y + 3*sqrsize), (start_x, start_y),
        (start_x, start_y + 2*sqrsize), (start_x, start_y + 1*sqrsize)],

    'L':[(start_x + 1*sqrsize, start_y + 2*sqrsize), (start_x, start_y),
        (start_x, start_y + 2*sqrsize), (start_x, start_y + 1*sqrsize)],

    'T':[(start_x + 1*sqrsize, start_y + 1*sqrsize),(start_x, start_y),
        (start_x - 1*sqrsize, start_y + 1*sqrsize),(start_x,
                                                    start_y + 1*sqrsize)]
    }
a_shape = random.randint(0, 4)
return shapes[shape_names[a_shape]], shape_names[a_shape]
#return shapes['O'], 'O' #for testing 


def rotate(shape_blcks, shape):
'''input:- list of shape blocks
ouput:- list of shape blocks
function tries to rotate ie change orientation of blocks in the shape
and this applied depending on the shape for example if a 'O' shape is passed
to this function, the same shape is returned because the orientation of such
shape cannot be changed according to tetris rules'''
if shape == 'O':
    return shape_blcks
else:
    #global no_move, occupied_squares, background
    blck_x_axis, blck_y_axis = 0, 1

    shape_coords = [(block[blck_x_axis], block[blck_y_axis]) for
        block in shape_blcks]

    ref_shape_ind = 3 # index of block along which shape is rotated
    start_x, start_y = (shape_coords[ref_shape_ind][blck_x_axis],
                        shape_coords[ref_shape_ind][blck_y_axis])  
    new_shape_blcks = [(start_x + start_y-shape_coords[0][1],
                        start_y - (start_x - shape_coords[0][0])),
        (start_x + start_y-shape_coords[1][1],
         start_y - (start_x - shape_coords[1][0])),
        (start_x + start_y-shape_coords[2][1],
         start_y - (start_x - shape_coords[2][0])),
        (shape_coords[3][0], shape_coords[3][1])]
    if legal(new_shape_blcks):
        for index in range(num_block): # paint over the previous shape
            background.fill(color['white'], shape_blcks[index])
        return [pygame.Rect(block[blck_x_axis], block[blck_y_axis],
                                                 sqrsize, sqrsize) for
                                           block in new_shape_blcks] 
    else:
        return shape_blcks

if __name__ == '__main__':
    tetris()
###############################################################################
##使用pygame在python中实现一个***非常***的基本俄罗斯方块游戏
###############################################################################
''旋转--r
停顿——p
移动“”的方向按钮
导入系统
导入pygame
随机输入
尺寸=宽度,高度=200400
颜色={'black':(0,0,0),'white':(255,255,255)}
sqrsize=20
占用的面积=[]
屏幕的顶部=(0,0)
top_x,top_y=_屏幕的top_[0],_屏幕的top_[1]
num_block=4
钢笔尺寸=1
mov_延迟,r_延迟=300,50
董事会会议中心=80
不移动=0
事件={276:'左',275:'右',112:'暂停'}
pygame.init()
screen=pygame.display.set_模式(大小)
background=pygame.Surface(screen.get_size())
background=background.convert()
背景填充((颜色['white']))
屏幕。blit(背景,屏幕顶部)
pygame.display.flip()
def俄罗斯方块():
''现在这是整个游戏的控制者,可能会改变
后来随着游戏架构的改变。”
全局移动延迟
尽管如此:
curr\u shape=创建新闻形状(board\u Center)
l_of_blcks_ind=blck_x_轴=0
形状\u名称\u ind=blck\u y\u轴=1
move_dir=‘down’#默认移动方向
游戏='playing'#默认游戏状态play:-游戏暂停还是正在玩
shape_blcks=[pygame.Rect(块[blck_x_轴]、块[blck_y_轴],
sqrsize,sqrsize)用于当前形状的块[l_of_blcks_ind]]
如果合法(shape_blcks):
绘制图形(图形块)
其他:
休息,比赛结束
尽管如此:
如果游戏==“暂停”:
对于pygame.event.get(pygame.KEYDOWN)中的事件:
如果event.key==pygame.K\p:
游戏=‘玩’
其他:
对于pygame.event.get中的事件((pygame.KEYDOWN,pygame.keydup,
pygame.退出):
如果event.type==pygame.QUIT:
sys.exit()
elif event.type==pygame.KEYDOWN:
如果event.key==pygame.K_向下:
mov_延迟=50
持续
elif event.key==pygame.K\u r:
shape\u blcks=旋转(shape\u blcks,curr\u shape[shape\u name\u ind])
绘制图形(图形块)
pygame.time.delay(r_delay)
持续
elif event.key==pygame.K\p:
游戏='暂停'
move_dir=events[event.key]
打破
其他:
如果event.key插入events.keys():
mov_延迟=50
move_dir=events[event.key]
移动(形块,移动方向)
绘制图形(图形块)
pygame.time.delay(移动延迟)
继续
elif event.type==pygame.KEYUP:
如果移动延迟!=300:
mov_延迟=300
move_dir='向下'
移动=移动(形状、移动方向)
绘制图形(图形块)
pygame.time.delay(移动延迟)
''如果块未移动且移动方向为向下
然后形状停止了,所以我们可以退出循环,然后是一个新的循环
形状被生成。如果移动方向为侧向和
块未移动它应向下移动,而不是“”移动
如果未移动,则移动_dir==“向下”:
对于形状为黑色的块:
占用的方格。追加((块[blck_x_轴],
块[blck_y_轴])
打破
其他:
绘制图形(图形块)
pygame.time.delay(移动延迟)
对于范围内的行号(高度-sqrsize,0,-sqrsize):
如果填写了行(行号):
删除行(行号)
def绘图形状(shp块):
''这会将块列表或块绘制到背景和光点
屏幕“”的背景
如果存在(上海浦东新区,列表):
对于上海浦东新区的地块:
pygame.draw.rect(背景,颜色['black',黑色,钢笔大小)
其他:
pygame.draw.rect(背景、颜色['black']、黑色、钢笔大小)
屏幕。blit(背景,屏幕顶部)
pygame.display.update()
def行已填充(行编号):
''检查一行是否完全被形状块占用''
对于范围内的x_坐标(0,宽度,sqrsize):
如果(x_坐标,行号)位于占用的方格中:
持续
其他:
返回错误
返回真值
def delete_行(行号):
''从“已占用方格”列表中删除一行上的所有方格,然后
向下移动y轴坐标小于行号的所有方形位置
董事会''
全局占位符方格
新的缓冲区=[]
x_坐标,y_坐标=0,1
背景填充(颜色['白色])
对于占用的广场中的sqr:
如果sqr[y_coord]!=行号:
新的缓冲区追加(sqr)
占用的方=新的缓冲区
对于范围内的索引(len(占用的平方):
如果占用方格[索引][y坐标]<行号:
占用方格[索引]=(占用方格[索引][x_坐标],
占用方格[索引][y_坐标]+sqrsize)
对于占用的广场中的sqr:
rect=pygame.rect(sqr[x_-coord],sqr[y_-coord],sqrsize,sqrsize)
绘制形状(矩形)
def移动(形状、方向):
''输入:-组成俄罗斯方块形状的块列表
输出:-bl列表
    gameboard.colors = ['black','red','brown','cyan','orange','magenta','yellow','green'];
    gameboard.tetrominoes = {
      O: [[[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]],
          [[0,1,1,0], [0,1,1,0], [0,1,1,0], [0,1,1,0]],
          [[0,1,1,0], [0,1,1,0], [0,1,1,0], [0,1,1,0]],
          [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]]],

      I: [[[0,0,0,0], [0,0,2,0], [0,0,0,0], [0,0,2,0]],
          [[2,2,2,2], [0,0,2,0], [2,2,2,2], [0,0,2,0]],
          [[0,0,0,0], [0,0,2,0], [0,0,0,0], [0,0,2,0]],
          [[0,0,0,0], [0,0,2,0], [0,0,0,0], [0,0,2,0]]],

      S: [[[0,0,0,0], [0,0,3,0], [0,0,0,0], [0,0,3,0]],
          [[0,0,3,3], [0,0,3,3], [0,0,3,3], [0,0,3,3]],
          [[0,3,3,0], [0,0,0,3], [0,3,3,0], [0,0,0,3]],
          [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]]],

      Z: [[[0,0,0,0], [0,0,0,4], [0,0,0,0], [0,0,0,4]],
          [[0,4,4,0], [0,0,4,4], [0,4,4,0], [0,0,4,4]],
          [[0,0,4,4], [0,0,4,0], [0,0,4,4], [0,0,4,0]],
          [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]]],

      L: [[[0,0,0,0], [0,0,5,0], [0,0,0,5], [0,5,5,0]],
          [[0,5,5,5], [0,0,5,0], [0,5,5,5], [0,0,5,0]],
          [[0,5,0,0], [0,0,5,5], [0,0,0,0], [0,0,5,0]],
          [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]]],

      J: [[[0,0,0,0], [0,0,6,6], [0,6,0,0], [0,0,6,0]],
          [[0,6,6,6], [0,0,6,0], [0,6,6,6], [0,0,6,0]],
          [[0,0,0,6], [0,0,6,0], [0,0,0,0], [0,6,6,0]],
          [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]]],

      T: [[[0,0,0,0], [0,0,7,0], [0,0,7,0], [0,0,7,0]],
          [[0,7,7,7], [0,0,7,7], [0,7,7,7], [0,7,7,0]],
          [[0,0,7,0], [0,0,7,0], [0,0,0,0], [0,0,7,0]],
          [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]]]
    };