欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

150行python代码制作一个简单的俄罗斯方块小游戏

程序员文章站 2024-03-18 19:50:58
...

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

这个主要是转动数据麻烦,虽说全部手动写上去也行,实际也比代码要短,只是不太好意思,强行转动(共7个图形,最后一个转动时中心会发生偏移,耍赖了一把)
150行python代码制作一个简单的俄罗斯方块小游戏
实际流程(三个状态):

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

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

  • 到底,图形数据记录到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()
相关标签: python pygame