趣味python编程之经典俄罗斯方块 – lykyl的自留地

在国庆节陆续无所事事的,用python把经典俄罗斯方块达到预期的目的了一遍,找寻幼年的生趣。突然的的奇观,我打算用Python排少量地经典的、风趣的小顺序。。其余者的正统主义行为也给了你少量地生趣。,使改变职位角度排顺序。
新颖的的打算是写东西完成或完毕的视频博客来解说顺序ALGORIT,无论如何当我整顿顺序时,我被发现的人我添加了正文。,顺序外的很多单词。什么叫简通道,指示职位导向的顺序代码,每人都在密码电文上、脚注,缓慢地置信对顺序的拘押应该是轻易的。。

配置文件 ,东西职位的原始正垂直整队的结成被界说。,在GETCONF中反省假设的体式的正文。

;1,1,1,1;;
1,1,1,0;1,0,0,0;;
1,1,1,0;0,0,1,0;;
0,1,0,0;1,1,1,0;;
1,1,0,0;1,1,0,0;;
1,1,0,0;0,1,1,0;;
0,1,1,0;1,1,0,0;;

完成或完毕顺序代码:

# -*- 编码:UTF-8 -*-
''''''
经典俄罗斯方块
本游玩、排。

游玩诠释说话中肯术语解说:
驿站:全游玩分界线,包孕摞区、成就等显示区,下块预告区。
摞区:游玩方块和敏捷的垂直积云区,游玩说话中肯首要共同的区域。
块(基块):正垂直是卑鄙的的小正垂直。,每个正垂直都是正垂直。。
方块整队:以假设的方法结成的一组正垂直,这执意你常常说的下倾正直地的整队。,像,用带绑扎,垂直,L形等。
固实方块:在摞区域内不再革囊,可以驱散的一组根本块。

version:1.0
author:lykyl
createdate:2016.9.29
''''''

import random,copy
import 法术 as pg
from 法术.locals import *

''''''
持续的宣布
''''''
EMPTY_CELL=0        空区域编号,无正垂直
FALLING_BLOCK=1     沦陷的正垂直用垂饰安装,这是打手势要求块。。
STATIC_BLOCK=2      存在块鉴定

''''''
全程变量宣布
变量的值是SysNIT有或起作用设定初值的奏效。
''''''
defaultFont=None        #默许手迹
screen=None     放映出口情郎
反面=None        图像出口缓冲画板
score=0     球员得分记载
clearLineScore=0        由玩家重新放置的方行数
level=1     #审察员的职权分阶段
clock=None      #游玩打卡
nowBlock=None       趋势湍滩说话中肯正垂直
nextBlock=None      将呈现的下东西块
fallSpeed=10        电流阻断攻击:严厉批评或猛烈攻击
beginFallSpeed=fallSpeed        游玩开端时的攻击:严厉批评或猛烈攻击
speedBuff=0     下倾攻击:严厉批评或猛烈攻击缓冲变量
keyBuff=None        至死击键记载
maxBlockWidth=10        阶段STA中X轴的最大可赞成根本块数
maxBlockHeight=18       阶段STA中Y轴的最大可赞成根本块编号
blockWidth=30       像素说话中肯基块宽度
blockHeight=30      像素说话中肯基块高价地
blocks=[]       方阵矩阵四维表。第东西维度在正垂直的整队上是差别的。,次货个维度是每个正垂直整队的职位(从0开端)。,一共同体四个一组之物职位。,第三维是Y轴正垂直的整队占据期间。,四分之一维是X轴正垂直的整队。。矩阵中0无正垂直,1表现块。
stage=[]        阶段摞面积矩阵二维表,首先维是Y轴块的占据期间。,次货个维度是x轴块的占据期间。。矩阵中0无正垂直,1是真心实意的块,2是打手势要求块。
gameOver=False      游玩完毕签名
pause=False     游玩使镇静签名


def printTxt(content,x,y,font,screen,color=(255,255,255)):
    显示课文
    args:
        心甘情愿的:显示课文心甘情愿的
        x,显示搭配
        手迹:手迹
        放映放映:出口
        色:色
    ''''''
    imgTxt=(content,True,色)
    (imgTxt,(x,y))
    
    
class 点(情郎)
    立体搭配点类
    attributes:
        x,搭配值
    ''''''
    def __init__(self,x,y):
        =x
        =y
    
    def GETX(自尊心)
        return 
    
    def setx(self,x):
        =x
    
    x=property(getx,setx)
    
    def 艳丽的(自尊心)
        return 
    
    def 塞蒂(自尊心),y):
        =y
    
    y=property(gety,赛迪)    
    
    def __str__(self):
        return {x: {:.0f}.FATA() ,y: {:.0f}.FATA()) }


class blockSprite(object):
    ''''''
    垂直精灵
    下倾方块的界说安宁它。。
    attributes:
        整队:正垂直编号
        职位:方职位编号
        xy,方块搭配的左上角块整队
        方块矩阵
    ''''''
    def __init__(self,shape,direction,XY)
        =shape
        =direction
        self.xy=xy
    
    def chgDirection(self,职位)
        ''''''
        使改变职位正垂直的职位
        args:
            职位:1是向右转,0左转。
        ''''''
        DyNub= LeN(块[])- 1
        if direction==1:
            +=1
            if >dirNumb:
                =0
        else:
            -=1
            if <0:
                =dirNumb
    
    def clone(self):
        ''''''
        克隆本体
        return:
            返回自身的克隆
        ''''''
        return blockSprite(,,point())
        
    def _getBlock(self):
        return blocks[][]
        
    block = property(_getBlock)


def getConf(fileName):
    ''''''
    从配置文件中读取方块整队记录
    每个方块以4*4矩阵表现整队,配置文件每行代表东西方块,用分号分隔矩阵行,用逗号分隔矩阵列,0无正垂直,1表现块。
    由于此顺序只针对俄罗斯方块的经典版,所以方块矩阵大小以硬编码的形式写死为4*4。
    args:
        fileName:配置文件名
    ''''''
    global blocks   #blocks记载方块整队。
    with open(fileName,''rt'') as fp:
        for temp in fp.readlines():
            ([])
            blocksNumb=len(blocks)-1
            blocks[blocksNumb]=[]
            #每种方块整队有四个一组之物职位,以0~3表现。配置文件中只记载东西职位整队,另外三个职位的矩阵排列在sysInit中通过调用transform计算出来。
            blocks[blocksNumb].append([])
            row=(";")
            for r in range(len(row)):
                col=[]
                ct=row[r].split(",")
                #对矩阵列记录做规整,首先将非“1”的值全修正成“0”以过滤空字串或回车符。
                for c in range(len(ct)):
                    if ct[c]!="1":
                        (0)
                    else:
                        (1)
                #将不足4列的矩阵通过补“0”的方法,补足4列。
                for c in range(len(ct)-1,3):
                    (0)
                blocks[blocksNumb][0].append(col)
            #万一矩阵某行无方块,则配置文件中可以省略此行,顺序会在末尾补上空行记录。
            for r in range(len(row)-1,3):
                blocks[blocksNumb][0].append([0,0,0,0])
            blocks[blocksNumb][0]=formatBlock(blocks[blocksNumb][0])


def sysInit():
    ''''''
    系统设定初值
    包孕法术环境设定初值,全程变量赋值,生成每个方块整队的四个一组之物职位矩阵。
    ''''''
    global defaultFont,screen,反面,clock,blocks,stage,gameOver,fallSpeed,beginFallSpeed,nowBlock,nextBlock,score,level,clearLineScore,pause
    
    #法术运转环境设定初值
    ()
    screen=((500,550))
    反面=((().width,().height))
    ("block")
    clock=()
    (False)
    
    #游玩全程变量设定初值
    defaultFont=("res/font/",16)        #这样地手迹文件请自行上网搜索下载,万一找不到就随便用个ttf体式手迹文件替换一下。
    nowBlock=None
    nextBlock=None
    gameOver=False
    pause=False
    score=0
    level=1
    clearLineScore=0
    beginFallSpeed=20
    fallSpeed=beginFallSpeed-level*2
    
    #设定初值游玩驿站
    stage=[]
    for y in range(maxBlockHeight):
        ([])
        for x in range(maxBlockWidth):
            stage[y].append(EMPTY_CELL)
            
    #生成每个方块整队4个职位的矩阵记录
    for x in range(len(blocks)):
        #由于重新开端游玩时会调用sysinit对系统缠住参数重新设定初值,为了戒职位矩阵记录重新生成,需要在此判别能否已经生成,万一已经生成则加啤酒花于。
        if len(blocks[x])<2:
            t=blocks[x][0]
            for i in range(3):
                t=transform(t,1)
                blocks[x].append(formatBlock(t))
                

#transform,removeTopBlank,formatBlock这三个有或起作用只为生成方块整队4个职位矩阵运用,在游玩其他环节无作用,在阅读顺序时可以先加啤酒花于。
def transform(block,direction=0):  
    ''''''
    生成指定方块整队替换职位后的矩阵记录
    args:
        方块矩阵参数
        direction:替换的职位,0代表向左,1代表向右
    return:
        使多样化职位后的方块整队矩阵参数
    ''''''
    result=[]
    for y in range(4):
        ([])
        for x in range(4):
            if direction==0:
                result[y].append(block[x][3-y])
            else:
                result[y].append(block[3-x][y])
    return result 


def removeTopBlank(block):
    ''''''
    重新放置方块矩阵顶部空行记录
    args:
        block:方块开关矩阵
    return:
        整顿后的方块矩阵记录
    ''''''
    result=(block)
    blankNumb=0
    while sum(result[0])<1 and blankNumb<4:
        del result[0]
        ([0,0,0,0])
        blankNumb+=1
    return result
    

def formatBlock(block):
    ''''''
    整顿方块矩阵记录,使方块在矩阵中处于左上角的位置
    args:
        block:方块开关矩阵
    return:
        整顿后的方块矩阵记录
    ''''''
    result=removeTopBlank(block)
    #将矩阵右转,用于计算左侧X轴线空行,计算完成后再转回
    result=transform(result, 1)
    result=removeTopBlank(result)
    result=transform(result,0)
    return result


def checkDeany(sprite):
    ''''''
    反省下落方块能否与驿站摞区中固实方块发作倾轧
    args:
        sprite:下落方块
    return:
        万一发作倾轧则返回True
    ''''''
    topX=sprite.xy.x
    topY=sprite.xy.y
    for y in 射击场
        for x in 范畴(LeN([Y])
            if [y][x]==1:
                yInStage=topY+y
                xInStage=topX+x
                if yInStage>maxBlockHeight-1 or yInStage<0:
                    return True
                if xInStage>maxBlockWidth-1 or xInStage<0:
                    return True
                if stage[yInStage][xInStage]==STATIC_BLOCK:
                    return True                
    return False


def checkLine():
    ''''''
    检测摞区能否有可驱散的整行固实方块
    粉底检测奏效重新生成摞区矩阵记录,调用updateScore有或起作用使恢复玩家使结合成为整体等记录。
    return:
        本轮下落自行车驱散的固实方块行数
    ''''''
    global stage
    clearCount=0    #本轮下落自行车驱散的固实方块行数
    tmpStage=[]     #粉底驱散情况新生成的摞区矩阵,在有使恢复的情况下会替换全局的摞区矩阵。
    
    for y in stage:
        #由于固实方块在摞矩阵里以2表现,所以判别方块能否已经满一整行只要计算矩阵行数值合计能否等于摞区X轴最大方块数*2就可以。
        if sum(y)>=maxBlockWidth*2:
            (0,maxBlockWidth*[0])
            clearCount+=1
        else:
            (y)
    if clearCount>0:
        stage=tmpStage
        updateScore(clearCount)
    return clearCount
   

def updateStage(sprite,updateType=1):
    ''''''
    将下落三次幂搭配记录使恢复为堆栈区域记录。。下倾方格中所触及的搭配用数字来特性。,真心实意的块在摞区域中用垂饰安装为数字2。。
    args:
        雪碧的整队:下倾正直地
        使恢复花样:使恢复花样,0大特有的或特别的整理,1个代表静态参与,2代表固-固相加。
    ''''''
    
    global stage
    topX=sprite.xy.x
    topY=sprite.xy.y
    for y in 射击场
        for x in 范畴(LeN([Y])
            if [y][x]==1:
                if updateType==0:
                    if stage[topY+y][topX+x]==FALLING_BLOCK:
                        stage[topY+y][topX+x]=EMPTY_CELL
                elif updateType==1:
                    if stage[topY+y][topX+x]==EMPTY_CELL:
                        stage[topY+y][topX+x]=FALLING_BLOCK
                else:
                    stage[topY+y][topX+x]=STATIC_BLOCK


def updateScore(clearCount):
    ''''''
    使恢复玩家的游玩记载,牵制使结合成为整体、审察员的职权、驱散平方行数,粉底卡的量子使恢复块的下倾攻击:严厉批评或猛烈攻击。
    args:
        重新放置计数中重新放置的平方行数:下倾自行车。
    return:
        趋势游玩的最新使结合成为整体
    ''''''
    global score,fallSpeed,level,clearLineScore
    
    prizePoint=0    额定支持使结合成为整体,同时删去行数越多。,高昂的使结合成为整体越高。
    if clearCount>1:
        if clearCount<4:
            prizePoint=clearCount**clearCount
        else:
            prizePoint=clearCount*5
    score+=(clearCount+prizePoint)*level
    #玩得再牛又有何用? :)
    if score>99999999:
        score=0
    clearLineScore+=clearCount
    if clearLineScore>100:
        clearLineScore=0
        level+=1
        if level>(beginFallSpeed/2):
            level=1
            fallSpeed=beginFallSpeed
        fallSpeed=beginFallSpeed-level*2
    return score


def drawStage(drawScreen):
    ''''''
    在赠送的画布上排好队伍驿站
    args:
        DrawScreen:画画布
    ''''''
    staticColor=30,102,76       真心实意的块色
    activeColor=255,239,0       正垂直与色
    fontColor=200,10,120        #剧本、广播稿或者电影剧本色
    baseRect=0,0,blockWidth*maxBlockWidth+1,blockHeight*maxBlockHeight+1        叠块盒
    
    绘制堆栈区域的外框
    ((180,200,170))
    (drawScreen, staticColor, baseRect,1)
    
    绘制摞区域说话中肯缠住正垂直,包孕下落正直地的整队
    for y in 范畴(LeN(阶段))
        for x in 范畴(LeN)(阶段[Y])
            baseRect=x*blockWidth,y*blockHeight,blockWidth,blockHeight
            if stage[y][x]==2:
                (drawScreen, staticColor, baseRect)
            elif stage[y][x]==1:
                (drawScreen, activeColor, baseRect)
                
    绘制下东西着陆正直地的整队
    printTxt("Next:",320,350,defaultFont,反面,fontColor)
    if nextBlock!=None:
        for y in 射击场
            for x in 范畴(LeN([Y])
                baseRect=320+x*blockWidth,380+y*blockHeight,blockWidth,blockHeight
                if [y][x]==1:
                    (drawScreen, activeColor, baseRect)
                
    #绘制审察员的职权、使结合成为整体、全线数的电流电平驱散
    PrimtTxt(水平线:%d) % level,320,40,defaultFont,反面,fontColor)
    PrimtTxt(分:%D % score,320,70,defaultFont,反面,fontColor)
    PrimtTxt(重新放置:%d) % clearLineScore,320,100,defaultFont,反面,fontColor)
    
    特别游玩影响的出口
    if gameOver:
        printTxt("GAME OVER",230,200,defaultFont,反面,fontColor)   
        printTxt("",200,260,defaultFont,反面,fontColor)   
    if pause:
        printTxt("Game pausing",230,200,defaultFont,反面,fontColor)   
        printTxt("",200,260,defaultFont,反面,fontColor)   


def process():
    ''''''
    游玩把持与逻辑处置
    ''''''
    global gameOver,nowBlock,nextBlock,speedBuff,反面,keyBuff,pause
    
    if nextBlock is None:
        nextBlock=blockSprite((0,莱恩(块)- 1),(0,3),point(maxBlockWidth+4,maxBlockHeight))
    if nowBlock is None:
        nowBlock=()
        (maxBlockWidth//2,0)
        nextBlock=blockSprite((0,莱恩(块)- 1),(0,3),point(maxBlockWidth+4,maxBlockHeight))
        无论什么时候发作新的液滴整队时,就发作倾轧检测。,万一呈现新的垂直整队,就会发作倾轧。,很明显,球员无机遇。。
        gameOver=checkDeany(nowBlock)
        竞赛耽搁后,打手势要求块的整队应对待真心实意的块。
        if gameOver:
            updateStage(nowBlock,2)
            
    ''''''
    把持和革囊下倾正直地的整队,先期判别投阴影于的整队。万一无倾轧,则对下倾的团块整队停止使改变职位。,要不它不见得使改变职位。
    ''''''
    tmpBlock=()       投阴影于垂直
    ''''''
    处置用户输出
    用户输出分为两面积。
    首先面积,将抛弃、使镇静、重启和整队替换容易搬运来冷锻使成型事变。。
    摆布做的利益是只处置了东西指板。,在顺序倒转处置后戒用户从事单人表演关键的,显著地整队使多样化运算,冷锻使成型指板并使改变职位东西职位,玩家倾向把持。
    ''''''
    for event in pg.event.get():
        if event.type== pg.QUIT:
            sys.exit()
            ()
        elif event.type==pg.KEYDOWN:
            if event.key==pg.K_ESCAPE:
                sys.exit()
                ()
            elif event.key==pg.K_RETURN:
                if gameOver:
                    sysInit()
                    return
                elif pause:
                    pause=False
                else:
                    pause=True
                    return
            elif not gameOver and not pause:
                if event.key==pg.K_SPACE:
                    tmpBlock.chgDirection(1)
                elif event.key==pg.K_UP:
                    tmpBlock.chgDirection(0)
                    
    if not gameOver and not pause:
        ''''''
        用户输出处置次货面积,摆布革囊急速的投容易搬运事变PR。
        摆布做的利益是玩家不喜欢倒转点击指板。,确保了容易搬运的无变化。。
        由于陆续打手势要求的攻击:严厉批评或猛烈攻击太快,不顺职位。故,在顺序中运用复杂的输出加重。,也执意说,用指板键拿住至死东西容易搬运键。,万一这样地紧固件与至死东西紧固件恒等的,加啤酒花于这样地圆紧固件处置。
        ''''''
        keys=()
        if keys[K_DOWN]:
            ()
            keyBuff=None
        elif keys[K_LEFT]:
            if keyBuff!=pg.K_LEFT:
                ()
                keyBuff=pg.K_LEFT
            else:
                keyBuff=None
        elif keys[K_RIGHT]:
            if keyBuff!=pg.K_RIGHT:
                ()
                keyBuff=pg.K_RIGHT
            else:
                keyBuff=None
        if not checkDeany(tmpBlock):
            updateStage(nowBlock,0)
            nowBlock=()
        
        装卸必然发生的萎靡
        speedBuff+=1
        if speedBuff>=fallSpeed:
            speedBuff=0
            tmpBlock=()
            ()
            if not checkDeany(tmpBlock):
                updateStage(nowBlock,0)
                nowBlock=()
                updateStage(nowBlock,1)
            else:
                在必然发生的下倾的快跑中,有垂直整队的倾轧。,打手势要求块的整队是不易挥发的的。,反省能否有东西完成或完毕的块
                updateStage(nowBlock,2)
                checkLine()
                nowBlock=None
        else:
            updateStage(nowBlock,1)
    drawStage(反面)
    (反面,(0,0))
    ()
    (40)

    
def main():
    ''''''
    主顺序
    ''''''
    getConf("")
    sysInit()
    while True:
        process() 
  
    
if __name__ == "__main__":
    main()

顺序运转截图:

发表评论

电子邮件地址不会被公开。 必填项已用*标注