zoukankan      html  css  js  c++  java
  • 俄罗斯方块游戏

    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.
     
  • 相关阅读:
    383. Ransom Note
    598. Range Addition II
    453. Minimum Moves to Equal Array Elements
    492. Construct the Rectangle
    171. Excel Sheet Column Number
    697. Degree of an Array
    665. Nondecreasing Array
    视频网站使用H265编码能提高视频清晰度吗?
    现阶段的语音视频通话SDK需要解决哪些问题?
    企业远程高清会议平台视频会议系统在手机端使用的必备要求有哪些?
  • 原文地址:https://www.cnblogs.com/wxMing/p/14052898.html
Copyright © 2011-2022 走看看