爱学习的喵 发表于 2018-10-28 22:04:38

pygame俄罗斯方块

本帖最后由 爱学习的喵 于 2018-10-28 22:21 编辑

前言:
从零基础入门至今学习已经一个半月,谢谢小甲鱼的教学,我由刚开始的python小白到现在已经学会了爬虫,tkinter和pygame等模块,但随着课程的深入,我发现学习的效率不断下降,第87课开始就有点听不下去的,pygame模块真的好难记{:10_266:},所以为深化学习,我自己写了个俄罗斯方块,因为平时自己喜欢玩俄罗斯方块,拥有一款适合自己手感专属的游戏说不定会很有趣喔,就这样做了这个游戏。
代码有点乱,因为是练习和自用的,当中没优化的问题如下:
1.长方形竖立生成的方式(至今在起点只能横向生成,有点后悔生成的游戏太小了)
2.在下降到底部时会出现方块闪现
3.一部分多余的代码,特别是方块的旋转问题,这是个意外,我一开始版本不是2d建模的,所有耗费了大量的代码
综合而言,就是懒得改{:10_254:}
操作说明:
下、左右:移动
空格:翻转


import pygame
import sys
from pygame.locals import *
import random
#初始化Pygame

pygame.init()

WHITE = (255,255,255)
BLACK = (0,0,0)

all_blocks = []
def set_background(all_blocks):
    temp1 =[]
    for y in range(21):
      for x in range(12):
            temp1.append(-1)
      all_blocks.append(temp1)
      temp1 = []
    all_blocks = all_blocks[:][:]
      
    return all_blocks

def set_boarder(all_blocks):
    for x in range(12):
      all_blocks = 7

    for y in range(21):
      all_blocks = 7
      all_blocks = 7
    return all_blocks

all_blocks = set_background(all_blocks)

all_blocks = set_boarder(all_blocks)

def block(type_a,dir1,pos_x,pos_y):
    if type_a == 1:
      bottom,left,right,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3 = block_A(dir1,pos_x,pos_y)
    elif type_a == 2:
      bottom,left,right,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3 = block_B(dir1,pos_x,pos_y)
    elif type_a == 3:
      bottom,left,right,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3 = block_C(dir1,pos_x,pos_y)
    elif type_a == 4:
      bottom,left,right,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3 = block_D(dir1,pos_x,pos_y)
    elif type_a == 5:
      bottom,left,right,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3 = block_E(dir1,pos_x,pos_y)
    elif type_a == 6:
      bottom,left,right,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3 = block_F(dir1,pos_x,pos_y)

    return bottom,left,right,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3

def block_A(dir1,pos_x,pos_y):#长方形
    #1:North,2:east
    if dir1 == 2 or dir1==4:
      pos_x1,pos_y1 = pos_x,pos_y+20
      pos_x2,pos_y2 = pos_x,pos_y-20
      pos_x3,pos_y3 = pos_x,pos_y-40
      bottom = pos_y+20
      left = pos_x
      right = pos_x
      
    if dir1 == 1 or dir1 ==3:
      pos_x1,pos_y1 = pos_x-20,pos_y
      pos_x2,pos_y2 = pos_x+20,pos_y
      pos_x3,pos_y3 = pos_x+40,pos_y
      bottom = pos_y
      left = pos_x-20
      right = pos_x+40
      
    pygame.draw.rect(screen,color(1),(pos_x,pos_y,20,20),0)
    pygame.draw.rect(screen,color(1),(pos_x1,pos_y1,20,20),0)
    pygame.draw.rect(screen,color(1),(pos_x2,pos_y2,20,20),0)
    pygame.draw.rect(screen,color(1),(pos_x3,pos_y3,20,20),0)
    return bottom,left,right,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3

def block_C(dir1,pos_x,pos_y):#倒Z型
    #1:North,2:east
    if dir1 == 1 or dir1 == 3:
      pos_x1,pos_y1 = pos_x-20,pos_y
      pos_x2,pos_y2 = pos_x,pos_y-20
      pos_x3,pos_y3 = pos_x+20,pos_y-20
      bottom = pos_y
      left = pos_x-20
      right = pos_x+20
      
    if dir1 == 2 or dir1 == 4:
      pos_x1,pos_y1 = pos_x,pos_y+20
      pos_x2,pos_y2 = pos_x-20,pos_y
      pos_x3,pos_y3 = pos_x-20,pos_y-20
      bottom = pos_y+20
      left = pos_x-20
      right = pos_x
      
    pygame.draw.rect(screen,color(3),(pos_x,pos_y,20,20),0)
    pygame.draw.rect(screen,color(3),(pos_x1,pos_y1,20,20),0)
    pygame.draw.rect(screen,color(3),(pos_x2,pos_y2,20,20),0)
    pygame.draw.rect(screen,color(3),(pos_x3,pos_y3,20,20),0)
    return bottom,left,right,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3

def block_B(dir1,pos_x,pos_y):#Z型
    #1:North,2:east
    if dir1 == 1 or dir1 == 3:
      pos_x1,pos_y1 = pos_x-20,pos_y
      pos_x2,pos_y2 = pos_x,pos_y+20
      pos_x3,pos_y3 = pos_x+20,pos_y+20
      bottom=pos_y+20
      left = pos_x-20
      right = pos_x+20
      
    if dir1 == 2 or dir1 == 4:
      pos_x1,pos_y1 = pos_x,pos_y-20
      pos_x2,pos_y2 = pos_x-20,pos_y
      pos_x3,pos_y3 = pos_x-20,pos_y+20
      bottom = pos_y+20
      left = pos_x-20
      right = pos_x
      
    pygame.draw.rect(screen,color(2),(pos_x,pos_y,20,20),0)
    pygame.draw.rect(screen,color(2),(pos_x1,pos_y1,20,20),0)
    pygame.draw.rect(screen,color(2),(pos_x2,pos_y2,20,20),0)
    pygame.draw.rect(screen,color(2),(pos_x3,pos_y3,20,20),0)
    return bottom,left,right,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3

def block_D(dir1,pos_x,pos_y):#方型
    #1:North,2:east
    pos_x1,pos_y1 = pos_x-20,pos_y
    pos_x2,pos_y2 = pos_x,pos_y-20
    pos_x3,pos_y3 = pos_x-20,pos_y-20
    pygame.draw.rect(screen,color(4),(pos_x,pos_y,20,20),0)
    pygame.draw.rect(screen,color(4),(pos_x1,pos_y1,20,20),0)
    pygame.draw.rect(screen,color(4),(pos_x2,pos_y2,20,20),0)
    pygame.draw.rect(screen,color(4),(pos_x3,pos_y3,20,20),0)
    bottom = pos_y
    left = pos_x-20
    right = pos_x
    return bottom,left,right,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3


def block_E(dir1,pos_x,pos_y):#L型
    #1:North,2:east3:south4:west
    if dir1 == 1:
      pos_x1,pos_y1 = pos_x,pos_y-20
      pos_x2,pos_y2 = pos_x,pos_y+20
      pos_x3,pos_y3 = pos_x+20,pos_y+20
      bottom = pos_y+20
      left = pos_x
      right = pos_x+20
      
    if dir1 == 2:
      pos_x1,pos_y1 = pos_x+20,pos_y
      pos_x2,pos_y2 = pos_x-20,pos_y
      pos_x3,pos_y3 = pos_x-20,pos_y+20
      bottom = pos_y+20
      left = pos_x-20
      right = pos_x+20

    if dir1 == 3:
      pos_x1,pos_y1 = pos_x,pos_y+20
      pos_x2,pos_y2 = pos_x,pos_y-20
      pos_x3,pos_y3 = pos_x-20,pos_y-20
      bottom = pos_y+20
      left = pos_x-20
      right = pos_x+20

    if dir1 == 4:
      pos_x1,pos_y1 = pos_x-20,pos_y
      pos_x2,pos_y2 = pos_x+20,pos_y
      pos_x3,pos_y3 = pos_x+20,pos_y-20
      bottom = pos_y
      left = pos_x-20
      right = pos_x+20
      
    pygame.draw.rect(screen,color(5),(pos_x,pos_y,20,20),0)
    pygame.draw.rect(screen,color(5),(pos_x1,pos_y1,20,20),0)
    pygame.draw.rect(screen,color(5),(pos_x2,pos_y2,20,20),0)
    pygame.draw.rect(screen,color(5),(pos_x3,pos_y3,20,20),0)

    return bottom,left,right,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3

def block_F(dir1,pos_x,pos_y):#倒L型
    #1:North,2:east3:south4:west
    if dir1 == 1:
      pos_x1,pos_y1 = pos_x,pos_y-20
      pos_x2,pos_y2 = pos_x,pos_y+20
      pos_x3,pos_y3 = pos_x-20,pos_y+20
      bottom = pos_y+20
      left = pos_x-20
      right = pos_x
      
    if dir1 == 2:
      pos_x1,pos_y1 = pos_x+20,pos_y
      pos_x2,pos_y2 = pos_x-20,pos_y
      pos_x3,pos_y3 = pos_x-20,pos_y-20
      bottom = pos_y
      left = pos_x-20
      right = pos_x+20

    if dir1 == 3:
      pos_x1,pos_y1 = pos_x,pos_y+20
      pos_x2,pos_y2 = pos_x,pos_y-20
      pos_x3,pos_y3 = pos_x+20,pos_y-20
      bottom = pos_y+20
      left = pos_x
      right = pos_x+20

    if dir1 == 4:
      pos_x1,pos_y1 = pos_x-20,pos_y
      pos_x2,pos_y2 = pos_x+20,pos_y
      pos_x3,pos_y3 = pos_x+20,pos_y+20
      bottom = pos_y+20
      left = pos_x-20
      right = pos_x+20
      
    pygame.draw.rect(screen,color(6),(pos_x,pos_y,20,20),0)
    pygame.draw.rect(screen,color(6),(pos_x1,pos_y1,20,20),0)
    pygame.draw.rect(screen,color(6),(pos_x2,pos_y2,20,20),0)
    pygame.draw.rect(screen,color(6),(pos_x3,pos_y3,20,20),0)

    return bottom,left,right,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3

size = width , height = 400,420
screen = pygame.display.set_mode(size)
pygame.display.set_caption('Tetris')

#第一块方块值
dir1 = 1
pos_x = 120
pos_y = 0
#下降计时器
timer=0
#选择方块色彩
def color(num):
    if num ==1:
      return (0,0,255)
    if num ==2:
      return (0,255,0)
    if num ==3:
      return (255,0,0)
    if num ==4:
      return (127,127,0)
    if num ==5:
      return (127,0,127)
    if num ==6:
      return (0,127,127)
    if num == 7:
      return (0,0,0)
   

#能否移动左边
def moveleft(all_blocks,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3):
    pos_x//=20
    pos_y//=20
    pos_x1//=20
    pos_y1//=20
    pos_x2//=20
    pos_y2//=20
    pos_x3//=20
    pos_y3//=20
    #print(pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3)
    if all_blocks != -1 \
       or all_blocks != -1 \
       or all_blocks != -1 \
       or all_blocks!= -1:
      return False
    return True
#能否移到右边
def moveright(all_blocks,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3):
    pos_x//=20
    pos_y//=20
    pos_x1//=20
    pos_y1//=20
    pos_x2//=20
    pos_y2//=20
    pos_x3//=20
    pos_y3//=20
    #print(pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3)
    if all_blocks != -1 \
       or all_blocks != -1 \
       or all_blocks != -1 \
       or all_blocks!= -1:
      return False
    return True

def movedown(all_blocks,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3):
    pos_x//=20
    pos_y//=20
    pos_x1//=20
    pos_y1//=20
    pos_x2//=20
    pos_y2//=20
    pos_x3//=20
    pos_y3//=20
    #print(pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3)
    if pos_y>0 and pos_y1>0 and pos_y2>0 and pos_y3>0:
      if all_blocks != -1 \
         or all_blocks != -1 \
         or all_blocks != -1 \
         or all_blocks != -1:
            return False
    return True

def rotate(all_blocks,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3):
    temp = pos_y1
   
    pos_y1 = pos_y-(pos_x1 - pos_x)
    pos_x1 = pos_x-(temp-pos_y)
    temp = pos_y2
    pos_y2 = pos_y-(pos_x2 - pos_x)
    pos_x2 = pos_x-(temp-pos_y)
    temp = pos_y3
    pos_y3 = pos_y-(pos_x3 - pos_x)
    pos_x3 = pos_x-(temp-pos_y)

    if all_blocks== -1 and all_blocks== -1\
                                 and all_blocks== -1:
      #print('a')
      return True

def level_up(points):
    level = 1
    if points >20:
      level = 2
    if points >40:
      level = 3
    if points >60:
      level = 4
    if points >80:
      level = 5
    if points >100:
      level = 6
    if points >120:
      level = 7
    if points >140:
      level = 8
    if points >160:
      level = 9
    return level
   
def get_point(all_blocks,points):
    for y in range(20):
      if -1 not in all_blocks:
            points+=1
            for x in range(1,11,1):
                all_blocks=-1
            for i in range(y):
                for x in range(1,11,1):
                  if i!=y:
                        all_blocks= all_blocks
    return all_blocks,points

def game_over(all_blocks):
    for x in range(1,11,1):
      if all_blocks!=-1:
            return True
    return False
#设定等级
level = 1
levels = {1:500,2:450,3:400,4:350,5:300,6:250,7:200,8:150,9:100}
#
next_block_type = random.randint(1,6)
myfont = pygame.font.Font(None, 18)
block_timer = 0
points = 0
block_type = random.randint(1,6)
clock = pygame.time.Clock()
while not game_over(all_blocks):
    for event in pygame.event.get():
      if event.type == pygame.QUIT:
            sys.exit()

      if event.type == KEYDOWN:
            #if event.key == K_LEFT and moveleft(all_blocks,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3):
                #pos_x -= 20
            #if event.key == K_RIGHT and moveright(all_blocks,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3):
                #pos_x += 20
            if event.key == K_SPACE and rotate(all_blocks,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3):
                if 4>dir1>=1:
                  dir1 += 1
                else:
                  dir1 =1
   
    screen.fill(WHITE)

    #载入背景
    for y in range(21):
      for x in range(12):
            if all_blocks != -1:
                pygame.draw.rect(screen,color(all_blocks),(x*20,y*20,20,20),0)

    #载入方块
    bottom,left,right,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3 = block(block_type,dir1,pos_x,pos_y)
    block(next_block_type,1,300,40)

   
    if not movedown(all_blocks,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3):
      pos_y//=20
      pos_x//=20
      pos_y1//=20
      pos_x1//=20
      pos_y2//=20
      pos_x2//=20
      pos_y3//=20
      pos_x3//=20
      all_blocks=block_type
      all_blocks=block_type
      all_blocks=block_type
      all_blocks=block_type
      #print(block_type)
      pos_x = 120
      pos_y = 0
      block_type = next_block_type
      next_block_type = random.randint(1,6)
      dir1 =1
    textImage1 = myfont.render('Points', True,(0,0,0))   
    textImage2 = myfont.render(str(points), True,(0,0,0))
    screen.blit(textImage1, (280, 190))
    screen.blit(textImage2, (280, 210))
    textImage3 = myfont.render('Level', True,(0,0,0))   
    textImage4 = myfont.render(str(level), True,(0,0,0))
    screen.blit(textImage3, (280, 150))
    screen.blit(textImage4, (280, 170))
   
    if timer>levels:
      pos_y+=20
      timer=0
    all_blocks,points = get_point(all_blocks,points)
    pygame.display.flip()
    level = level_up(points)
    temp = clock.tick(60)
    key_pressed = pygame.key.get_pressed()
    if key_pressed and movedown(all_blocks,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3):
      pos_y += 20
    else:
      timer+=temp
    block_timer += 1
    if block_timer>2:#可改善手感
      if key_pressed and moveleft(all_blocks,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3):
            pos_x -= 20
      if key_pressed and moveright(all_blocks,pos_x,pos_y,pos_x1,pos_y1,pos_x2,pos_y2,pos_x3,pos_y3):
            pos_x += 20
      block_timer = 0



fiore 发表于 2018-10-28 22:20:19

66666

想跳的鱼 发表于 2019-1-21 21:44:32

666666666
页: [1]
查看完整版本: pygame俄罗斯方块