只是实现了最简单功能。。。

这个主要是转动数据麻烦,虽说全部手动写上去也行,实际也比代码要短,只是不太好意思,强行转动(共7个图形,最后一个转动时中心会发生偏移,耍赖了一把)
在这里插入图片描述
实际流程(三个状态):

  • 新生成图形块,如果从下往上已经堆到这里了(图形块出现位置出现不为空白的背景)游戏结束

  • 下落(途中可以键盘操作块的移动,转动)

  • 到底,图形数据记录到map,检查是否消去一行

所有的检查,就用check_action(位置x,位置y,图形块号,图形转动角度):检查是否出界或遇到原先的块,

  • 游戏是否结束判断:新生成图形块位置是否check_action == False

  • 下落是否到底:y+1位置是否check_action == False

  • 操作动作(x-1,x+1,y+1,角度+1):是否check_action == False

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
import sys
import pygame
from pygame.locals import *
import random

class Block:
    blk_color = [(255, 255, 255),(255, 255, 0),(255, 0, 255),(0, 255, 255),(255, 0, 0),(0, 255, 0),(0, 0, 255),(32,32,32)]
    BLANK = 7
    type_coord=[[[-1,0],[0,0],[1,0],[2,0]]\
        ,[[-1,0],[0,0],[1,0],[0,1]]\
        ,[[-1,0],[0,0],[-1,1],[0,1]]\
        ,[[-1,0],[0,0],[0,1],[1,1]]\
        ,[[0,0],[1,0],[-1,1],[0,1]]\
        ,[[-1,0],[0,0],[1,0],[1,1]]\
        ,[[-1,0],[0,0],[1,0],[-1,1]]]
    type_rotate = []
    
    def __init__(self,x,y,blk,angle):
        self.x = x
        self.y = y
        self.blk = blk
        self.angle = angle
        
    @staticmethod
    def rotate(no):
        rt_all = []
        rt = Block.type_coord[no][:]
        cx,cy=0,0
        for b in range(4):
            rt[b][0],rt[b][1] = rt[b][0]*4,rt[b][1]*4
            cx += rt[b][0]
            cy += rt[b][1]
        cx = (cx)//8*2 if no !=6 else (cx+4)//8*2
        cy = (cy)//8*2 if no !=6 else (cy-4)//8*2
        rt_all.append(rt)
        for r in range(3):
            rt_new = []
            for b in range(4):
                rt_new.append([cx + (cy-rt[b][1]),cy-(cx-rt[b][0])])
            rt_all.append(rt_new)
            rt = rt_new
        for r in range(4):
            for b in range(4):
                rt_all[r][b][0] //= 4
                rt_all[r][b][1] //= 4
        return rt_all
    @staticmethod
    def init_rotate():
        for r in range(7):
            Block.type_rotate.append(Block.rotate(r))

class TRS:
    screen = None
    map = [[Block.BLANK]*10 for i in range(20)]
    STATUS = 0
    cbk = None

    def __init__(self,screen):
        TRS.screen = screen

    @staticmethod
    def action(key_pressed):
        if(key_pressed[K_LEFT] and TRS.check_action(TRS.cbk.x-1,TRS.cbk.y,TRS.cbk.blk,TRS.cbk.angle)):
            TRS.cbk.x -= 1
        elif (key_pressed[K_RIGHT] and TRS.check_action(TRS.cbk.x+1,TRS.cbk.y,TRS.cbk.blk,TRS.cbk.angle)):
            TRS.cbk.x += 1
        elif (key_pressed[K_UP] and TRS.check_action(TRS.cbk.x,TRS.cbk.y,TRS.cbk.blk,TRS.cbk.angle+1)):
            TRS.cbk.angle += 1
        elif (key_pressed[K_DOWN] and TRS.check_action(TRS.cbk.x,TRS.cbk.y+1,TRS.cbk.blk,TRS.cbk.angle)):
            TRS.cbk.y += 1
            
    @staticmethod
    def new_blk():
        TRS.cbk = Block(5,0,random.randint(0,6),0)
    @staticmethod
    def check_action(x,y,blk,angle):
        tr = Block.type_rotate[blk][angle%4]
        for b in range(4):
            bx,by = x + tr[b][0],y + tr[b][1]
            if(bx<0 or bx>9 or by <0 or by>19 or TRS.map[by][bx]!=Block.BLANK):
                return False
        return True
    @staticmethod
    def check_drop():
        if TRS.check_action(TRS.cbk.x,TRS.cbk.y+1,TRS.cbk.blk,TRS.cbk.angle):
            TRS.cbk.y += 1
        else:
            TRS.STATUS = 2
            
    @staticmethod
    def check_clear():
        blk = Block.type_rotate[TRS.cbk.blk][TRS.cbk.angle%4]
        row = list({TRS.cbk.y + blk[i][1] for i in range(4)})
        row.sort()
        row.reverse()
        for b in range(4):
            TRS.map[TRS.cbk.y + blk[b][1]][TRS.cbk.x + blk[b][0]] = TRS.cbk.blk
        del_rows = 0
        for r in row:
            if not (Block.BLANK in TRS.map[r]):
                TRS.map.pop(r)
                del_rows += 1
        for d in range(del_rows):
            TRS.map.insert(0,[Block.BLANK for i in range(10)])
            
    @staticmethod
    def print_game():
        TRS.screen.fill((0, 0, 0))
        for row in range(20):
            for col in range(10):
                pygame.draw.rect(TRS.screen, Block.blk_color[TRS.map[row][col]], ((col*21,row*21), (20, 20)), 0)
        blk = Block.type_rotate[TRS.cbk.blk][TRS.cbk.angle%4]
        for b in range(4):
            pygame.draw.rect(TRS.screen, Block.blk_color[TRS.cbk.blk], (((TRS.cbk.x+blk[b][0])*21,(TRS.cbk.y+blk[b][1])*21), (20, 20)), 0)
class App:
    def __init__(self):
        pygame.init()
        screen = pygame.display.set_mode((300,430))
        Block.init_rotate()
        TRS(screen)
        
    def main(self):
        clock = pygame.time.Clock()   # 创建游戏时钟
        count = 1
        # 进入游戏循环
        while True:
            # 设置刷新帧率
            clock.tick(15)
         
            # 事件检测
            for event in pygame.event.get():
                if event.type == pygame.QUIT:   # 退出事件
                    sys.exit()
                    
            if TRS.STATUS == 0:
                TRS.new_blk()
                if TRS.check_action(TRS.cbk.x,TRS.cbk.y,TRS.cbk.blk,TRS.cbk.angle):
                    TRS.STATUS = 1
                else:
                    TRS.STATUS = 3
                    print("GAME OVER")
            elif TRS.STATUS == 1:
                TRS.action(pygame.key.get_pressed())
                if count % 10 == 0:
                    TRS.check_drop()
            elif TRS.STATUS == 2:
                TRS.check_clear()
                TRS.STATUS = 0

            TRS.print_game()
            pygame.display.update()   #刷新屏幕
            count += 1
 
App().main()
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐