Python写的俄罗斯方块

发布时间:2019-09-05 07:07:48编辑:auto阅读(1335)

    在公司实习。公司推崇Python和Django框架,所以也得跟着学点。

    简单瞅了下Tkinter,和Canvas配合在一起,还算是简洁的界面开发API。threading.Thread创建新的线程,其多线程机制也算是方便。

    只是canvas.create_rectangle居然不是绘制矩形,而是新建了矩形控件这点让人大跌眼镜。先开始,在线程里每次都重绘多个矩形(随数组变化),其实是每次都新建了N个矩形,结果内存暴增。原来,对矩形进行变更时,只需用canvas.itemconfig即可。

    下面就是截图(时间太晚,明日还得上班,做得非常粗糙...没事时再慢慢修正)。


    而代码如下:

    #coding=utf-8
    from Tkinter import *;
    from random import *;
    import thread;   
    from tkMessageBox import showinfo;
    import threading;
    from time import sleep;
    class BrickGame(object):
      
      #是否开始
      start = True;
      #是否到达底部
      isDown = True;
      
      #窗体
      window = None;
      #frame
      frame1 = None;
      
      #绘图类
      canvas = None;
      
      #标题
      title = "BrickGame";
      #宽和高
      width = 350;
      height = 670;
      
      #行和列
      rows = 20;
      cols = 10;
      
      #几种方块
      brick = [
        
        [
             [
                 [1,1,1],
                 [0,0,1],
                 [0,0,0]
             ],
             [
                  [0,0,1],
                  [0,0,1],
                  [0,1,1]
             ],
             [
                  [0,0,0],
                  [1,0,0],
                  [1,1,1]
             ],
             [
                  [1,1,0],
                  [1,0,0],
                  [1,0,0]
             ]
        ],
        [
             [
                   [0,0,0],
                   [0,1,1],
                   [0,1,1]
             ],
             [
                    [0,0,0],
                    [0,1,1],
                    [0,1,1]
             ],
             [
                    [0,0,0],
                    [0,1,1],
                    [0,1,1]
             ],
             [
                    [0,0,0],
                    [0,1,1],
                    [0,1,1]
             ]         
        ],
        [
             [
                    [1,1,1],
                    [0,1,0],
                    [0,1,0]
             ],
             [
                    [0,0,1],
                    [1,1,1],
                    [0,0,1]
             ],
             [
                    [0,1,0],
                    [0,1,0],
                    [1,1,1]
             ],
             [
                    [1,0,0],
                    [1,1,1],
                    [1,0,0]
             ]
        ],
        [
             [
                    [0,1,0],
                    [0,1,0],
                    [0,1,0]
             ],
             [
                    [0,0,0],
                    [1,1,1],
                    [0,0,0]
             ],
             [
                    [0,1,0],
                    [0,1,0],
                    [0,1,0]
             ],
             [
                    [0,0,0],
                    [1,1,1],
                    [0,0,0]
             ]
        ]
      ];
      
      #当前的方块
      curBrick = None;
      #当前方块数组
      arr = None;
      #当前方块形状
      shape = -1;
      #当前方块的行和列(最左上角)
      curRow = -10;
      curCol = -10;
      
      #背景
      back = list();
      #格子
      gridBack = list();
      
      #初始化
      def init(self):
        
        for i in range(0,self.rows):
          
          self.back.insert(i,list());
          self.gridBack.insert(i,list());
        
        for i in range(0,self.rows):
          
          for j in range(0,self.cols):
            
            self.back[i].insert(j,0);
            self.gridBack[i].insert(j,self.canvas.create_rectangle(30*j,30*i,30*(j+1),30*(i+1),fill="black"));
    
      #绘制游戏的格子
      def drawRect(self):
        
        for i in range(0,self.rows):
              
              for j in range(0,self.cols):
                
              
                if self.back[i][j]==1:
                  
                  self.canvas.itemconfig(self.gridBack[i][j],fill="blue",outline="white");
                  
                elif self.back[i][j]==0:
                  
                  self.canvas.itemconfig(self.gridBack[i][j],fill="black",outline="white");
      
                  
        #绘制当前正在运动的方块
        if self.curRow!=-10 and self.curCol!=-10:
          
          for i in range(0,len(self.arr)):
            
            for j in range(0,len(self.arr[i])):
              
              if self.arr[i][j]==1:          
                
                self.canvas.itemconfig(self.gridBack[self.curRow+i][self.curCol+j],fill="blue",outline="white");
                
        #判断方块是否已经运动到达底部
        if self.isDown:
          
          for i in range(0,3):
            
            for j in range(0,3):
              
              if self.arr[i][j]!=0:
                
                self.back[self.curRow+i][self.curCol+j] = self.arr[i][j];
                
          #判断整行消除
          self.removeRow();
            
          #获得下一个方块  
          self.getCurBrick();
    
      #判断是否有整行需要消除
      def removeRow(self):
        
        for i in range(0,self.rows):
    
          tag1 = True;      
          for j in range(0,self.cols):
            
            if self.back[i][j]==0:
              
              tag1 = False;
              break;
          
          if tag1==True:
            
            #从上向下挪动
            for m in xrange(i-1,0,-1):
              
              for n in range(0,self.cols):
                
                self.back[m+1][n] = self.back[m][n];
          
      #获得当前的方块
      def getCurBrick(self):
        
        self.curBrick = randint(0,len(self.brick)-1);
        self.shape = 0;
        #当前方块数组
        self.arr = self.brick[self.curBrick][self.shape];
        
        self.curRow = 0;
        self.curCol = 1;
        
        #是否到底部为False
        self.isDown = False;
        
      #监听键盘输入
      def onKeyboardEvent(self,event):
        
        #未开始,不必监听键盘输入
        if self.start == False:
          
          return;
        
        #记录原来的值
        tempCurCol = self.curCol;
        tempCurRow = self.curRow;
        tempShape = self.shape;
        tempArr = self.arr;
        direction = -1;
        
        if event.keycode==37:
          
          #左移
          self.curCol-=1;
          direction = 1;
        elif event.keycode==38:
          #变化方块的形状
          self.shape+=1;
          direction = 2;
          
          if self.shape>=4:
            
            self.shape=0;
          self.arr = self.brick[self.curBrick][self.shape];
        elif event.keycode==39:
          
          direction = 3;
          #右移
          self.curCol+=1;
        elif event.keycode==40:
          
          direction = 4;
          #下移
          self.curRow+=1;
          
        if self.isEdge(direction)==False:
          
          self.curCol = tempCurCol;
          self.curRow = tempCurRow;
          self.shape = tempShape;
          self.arr = tempArr;
            
        self.drawRect();
          
        return True;
      
      #判断当前方块是否到达边界
      def isEdge(self,direction):
        
        tag = True;
      
        #向左,判断边界
        if direction==1:
          
          for i in range(0,3):
            
            for j in range(0,3):
              
              if self.arr[j][i]!=0 and (self.curCol+i<0 or self.back[self.curRow+j][self.curCol+i]!=0):
                
                tag = False;
                break;
        #向右,判断边界
        elif direction==3:
          
          for i in range(0,3):
            
            for j in range(0,3):
              
              if self.arr[j][i]!=0 and (self.curCol+i>=self.cols or self.back[self.curRow+j][self.curCol+i]!=0):
                
                tag = False;
                break;
        #向下,判断底部
        elif direction==4:
          
          for i in range(0,3):
            
            for j in range(0,3):
              
              if self.arr[i][j]!=0 and (self.curRow+i>=self.rows or self.back[self.curRow+i][self.curCol+j]!=0):
                
                tag = False;
                self.isDown = True;
                break;
        #进行变形,判断边界
        elif direction==2:
          
          if self.curCol<0:
            
            self.curCol=0;
          
          if self.curCol+2>=self.cols:
            
            self.curCol = self.cols-3;
            
          if self.curRow+2>=self.rows:
            
            self.curRow = self.curRow-3;
        
        
        return tag;
      
      #方块向下移动
      def brickDown(self):
        
        while True:
          
          if self.start==False:
            
            print("exit thread");
            break;
          
          tempRow = self.curRow;
          self.curRow+=1;
          
          if self.isEdge(4)==False:
            
            self.curRow = tempRow;
            
          self.drawRect();
             
          #每一秒下降一格
          sleep(1);  
          
      #运行
      def __init__(self):
        
        self.window = Tk();
        self.window.title(self.title);
        self.window.minsize(self.width,self.height);
        self.window.maxsize(self.width,self.height);        
        
        self.frame1 = Frame(self.window,width=300,height=600,bg="black");
        self.frame1.place(x=20,y=30);
        
        self.canvas = Canvas(self.frame1,width=300,height=600,bg="black");
        
        self.init();
        
        #获得当前的方块
        self.getCurBrick();
        
        #按照数组,绘制格子
        self.drawRect();    
              
        self.canvas.pack();
        
        #监听键盘事件
        self.window.bind("<KeyPress>",self.onKeyboardEvent); 
        
        #启动方块下落线程
        downThread = threading.Thread(target=self.brickDown,args=());
        downThread.start();    
        
        self.window.mainloop(); 
        
        self.start=False;
        
      pass;
    
    if __name__=='__main__':
      
      brickGame = BrickGame();

    估计用图形界面会很少,因为俺是WEB开发。不过,怎样也抑制不住这颗喜欢写游戏的心啊!

关键字

上一篇: Python——生成矩阵

下一篇: python socket.recv(