• 俄罗斯方块游戏


    1.python代码实现

    import sys
    import random,copy
    import pygame as pg
    from pygame.locals import *

    EMPTY_CELL=0       
    FALLING_BLOCK=1    
    STATIC_BLOCK=2     
    defaultFont=None      
    screen=None    
    backSurface=None        
    score=0    
    clearLineScore=0       
    level=1   
    clock=None 
    nowBlock=None 
    nextBlock=None
    fallSpeed=10
    beginFallSpeed=fallSpeed
    speedBuff=0 
    keyBuff=None 
    maxBlockWidth=10 
    maxBlockHeight=18  
    blockWidth=30 
    blockHeight=30    
    blocks=[]      
    stage=[]       
    gameOver=False   
    pause=False   

    def printTxt(content,x,y,font,screen,color=(255,255,255)):
        imgTxt=font.render(content,True,color)
        screen.blit(imgTxt,(x,y))
        
        
    class point(object):
        def __init__(self,x,y):
            self.__x=x
            self.__y=y
        
        def getx(self):
            return self.__x
        
        def setx(self,x):
            self.__x=x
        
        x=property(getx,setx)
        
        def gety(self):
            return self.__y
        
        def sety(self,y):
            self.__y=y
        
        y=property(gety,sety)    
        
        def __str__(self):
            return "{x:"+"{:.0f}".format(self.__x)+",y:"+"{:.0f}".format(self.__y)+"}"


    class blockSprite(object):
        def __init__(self,shape,direction,xy):
            self.shape=shape
            self.direction=direction
            self.xy=xy
        
        def chgDirection(self,direction):
            dirNumb=len(blocks[self.shape])-1
            if direction==1:
                self.direction+=1
                if self.direction>dirNumb:
                    self.direction=0
            else:
                self.direction-=1
                if self.direction<0:
                    self.direction=dirNumb
        
        def clone(self):
            return blockSprite(self.shape,self.direction,point(self.xy.x,self.xy.y))
            
        def _getBlock(self):
            return blocks[self.shape][self.direction]
            
        block = property(_getBlock)


    def getConf(fileName):
        global blocks
        with open(fileName,'rt') as fp:
            for temp in fp.readlines():
                blocks.append([])
                blocksNumb=len(blocks)-1
                blocks[blocksNumb]=[]
                blocks[blocksNumb].append([])
                row=temp.split(";")
                for r in range(len(row)):
                    col=[]
                    ct=row[r].split(",")
                    for c in range(len(ct)):
                        if ct[c]!="1":
                            col.append(0)
                        else:
                            col.append(1)
                    for c in range(len(ct)-1,3):
                        col.append(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,backSurface,clock,blocks,stage,gameOver,fallSpeed,beginFallSpeed,nowBlock,nextBlock,score,level,clearLineScore,pause
      
        pg.init()
        screen=pg.display.set_mode((500,550))
        backSurface=pg.Surface((screen.get_rect().width,screen.get_rect().height))
        pg.display.set_caption("block")
        clock=pg.time.Clock()
        pg.mouse.set_visible(False)
        
        defaultFont=pg.font.Font("res/font/yh.ttf",16) 
        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):
            stage.append([])
            for x in range(maxBlockWidth):
                stage[y].append(EMPTY_CELL)
                
        for x in range(len(blocks)):
            if len(blocks[x])<2:
                t=blocks[x][0]
                for i in range(3):
                    t=transform(t,1)
                    blocks[x].append(formatBlock(t))
                    

    def transform(block,direction=0):  
        result=[]
        for y in range(4):
            result.append([])
            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):
        result=copy.deepcopy(block)
        blankNumb=0
        while sum(result[0])<1 and blankNumb<4:
            del result[0]
            result.append([0,0,0,0])
            blankNumb+=1
        return result
        

    def formatBlock(block):
        result=removeTopBlank(block)
        result=transform(result, 1)
        result=removeTopBlank(result)
        result=transform(result,0)
        return result


    def checkDeany(sprite):
        topX=sprite.xy.x
        topY=sprite.xy.y
        for y in range(len(sprite.block)):
            for x in range(len(sprite.block[y])):
                if sprite.block[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():
        global stage
        clearCount=0   
        tmpStage=[]    
        
        for y in stage:
            if sum(y)>=maxBlockWidth*2:
                tmpStage.insert(0,maxBlockWidth*[0])
                clearCount+=1
            else:
                tmpStage.append(y)
        if clearCount>0:
            stage=tmpStage
            updateScore(clearCount)
        return clearCount
       

    def updateStage(sprite,updateType=1): 
        global stage
        topX=sprite.xy.x
        topY=sprite.xy.y
        for y in range(len(sprite.block)):
            for x in range(len(sprite.block[y])):
                if sprite.block[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):
        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):
        staticColor=30,102,76     
        activeColor=255,239,0
        fontColor=200,10,120
        baseRect=0,0,blockWidth*maxBlockWidth+1,blockHeight*maxBlockHeight+1
        
        drawScreen.fill((180,200,170))
        pg.draw.rect(drawScreen, staticColor, baseRect,1)
        
        for y in range(len(stage)):
            for x in range(len(stage[y])):
                baseRect=x*blockWidth,y*blockHeight,blockWidth,blockHeight
                if stage[y][x]==2:
                    pg.draw.rect(drawScreen, staticColor, baseRect)
                elif stage[y][x]==1:
                    pg.draw.rect(drawScreen, activeColor, baseRect)
                    
        printTxt("Next:",320,350,defaultFont,backSurface,fontColor)
        if nextBlock!=None:
            for y in range(len(nextBlock.block)):
                for x in range(len(nextBlock.block[y])):
                    baseRect=320+x*blockWidth,380+y*blockHeight,blockWidth,blockHeight
                    if nextBlock.block[y][x]==1:
                        pg.draw.rect(drawScreen, activeColor, baseRect)
                    
        printTxt("Level:%d" % level,320,40,defaultFont,backSurface,fontColor)
        printTxt("Score:%d" % score,320,70,defaultFont,backSurface,fontColor)
        printTxt("Clear:%d" % clearLineScore,320,100,defaultFont,backSurface,fontColor)
        
        if gameOver:
            printTxt("GAME OVER",230,200,defaultFont,backSurface,fontColor)   
            printTxt("<PRESS RETURN TO REPLAY>",200,260,defaultFont,backSurface,fontColor)   
        if pause:
            printTxt("Game pausing",230,200,defaultFont,backSurface,fontColor)   
            printTxt("<PRESS RETURN TO CONTINUE>",200,260,defaultFont,backSurface,fontColor)   


    def process():
        global gameOver,nowBlock,nextBlock,speedBuff,backSurface,keyBuff,pause
        
        if nextBlock is None:
            nextBlock=blockSprite(random.randint(0,len(blocks)-1),random.randint(0,3),point(maxBlockWidth+4,maxBlockHeight))
        if nowBlock is None:
            nowBlock=nextBlock.clone()
            nowBlock.xy=point(maxBlockWidth//2,0)
            nextBlock=blockSprite(random.randint(0,len(blocks)-1),random.randint(0,3),point(maxBlockWidth+4,maxBlockHeight))
            gameOver=checkDeany(nowBlock)
            if gameOver:
                updateStage(nowBlock,2)
      
        tmpBlock=nowBlock.clone()    
        for event in pg.event.get():
            if event.type== pg.QUIT:
                sys.exit()
                pg.quit()
            elif event.type==pg.KEYDOWN:
                if event.key==pg.K_ESCAPE:
                    sys.exit()
                    pg.quit()
                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:
            keys=pg.key.get_pressed()
            if keys[K_DOWN]:
                tmpBlock.xy=point(tmpBlock.xy.x,tmpBlock.xy.y+1)
                keyBuff=None
            elif keys[K_LEFT]:
                if keyBuff!=pg.K_LEFT:
                    tmpBlock.xy=point(tmpBlock.xy.x-1,tmpBlock.xy.y)
                    keyBuff=pg.K_LEFT
                else:
                    keyBuff=None
            elif keys[K_RIGHT]:
                if keyBuff!=pg.K_RIGHT:
                    tmpBlock.xy=point(tmpBlock.xy.x+1,tmpBlock.xy.y)
                    keyBuff=pg.K_RIGHT
                else:
                    keyBuff=None
            if not checkDeany(tmpBlock):
                updateStage(nowBlock,0)
                nowBlock=tmpBlock.clone()

            speedBuff+=1
            if speedBuff>=fallSpeed:
                speedBuff=0
                tmpBlock=nowBlock.clone()
                tmpBlock.xy=point(nowBlock.xy.x,nowBlock.xy.y+1)
                if not checkDeany(tmpBlock):
                    updateStage(nowBlock,0)
                    nowBlock=tmpBlock.clone()
                    updateStage(nowBlock,1)
                else:
                    updateStage(nowBlock,2)
                    checkLine()
                    nowBlock=None
            else:
                updateStage(nowBlock,1)
        drawStage(backSurface)
        screen.blit(backSurface,(0,0))
        pg.display.update()
        clock.tick(40)

        
    def main():
        sysInit()
        while True:
            process() 
      
        
    if __name__ == "__main__":
        main()
    源代码出自https://www.cnblogs.com/lykyl/p/5946102.html
    在此基础上进行了一些细节上的小优化,让游戏体验感更好一点。
    2.
     
  • 相关阅读:
    2018年NGINX最新版高级视频教程
    PHP 高级工程面试题汇总
    2018年最全Go语言教程零基础入门到进阶实战视频
    Mac和window生成ssh和查看ssh key
    33款可用来抓数据的开源爬虫软件工具
    什么是CMS系统
    对于做需求分析时的一些心得
    WPF和Silverlight的关系
    My97日期控件 My97 DatePicker Ver 3.0 正式版(转)
    HTML教程HTML技巧层的高级应用
  • 原文地址:https://www.cnblogs.com/wxMing/p/14052898.html
Copyright © 2020-2023  润新知