专栏首页python3Python写的俄罗斯方块

Python写的俄罗斯方块

在公司实习。公司推崇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开发。不过,怎样也抑制不住这颗喜欢写游戏的心啊!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • day23 03 组合的例子

    对象=类名()----实例化过程:创建了一个self对象,执行_init_方法初始化,返回self对象给外部

    py3study
  • 【python 验证码】产生中文验证码

    py3study
  • 用python实现一个转盘

    py3study
  • python pyqt5 QDockWidget

    import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.Qt...

    用户5760343
  • 我的小工具-远程读卡器web客户端(nodejs+websocket实现实时指令交互)

    之前的小工具,远程读卡器web客户端,实现原理是把读写卡服务装在远程(现场)的电脑上,这样有一些缺点,比如现场电脑必须开启端口映射,让客户端能否访问到。只能写好...

    特立独行的猫a
  • Pytorch实现卷积神经网络训练量化(QAT)

    深度学习在移动端的应用越来越广泛,而移动端相对于GPU服务来讲算力较低并且存储空间也相对较小。基于这一点我们需要为移动端定制一些深度学习网络来满足我们的日常续需...

    BBuf
  • 10.带人机对战的五子棋程序

    今天我们带来一个带人机对战功能的五子棋程序。程序基于前面文章中的框架搭建,新增人机对战的策略。程序基于规则进行决策,不考虑禁手,玩家执黑子先行。棋盘规模采用15...

    用户4381798
  • 6.wxPython防止窗体重画棋子消失的机制

    可以画图的类中wx.ClientDC不必依赖窗体绘画事件,可以随时实例化,随时画图。但是窗体最小化之后再恢复,重画的窗体上通过wx.ClientDC绘制的棋子会...

    用户4381798
  • 手把手教你用Python开发“剪刀石头布”小游戏【附源码】

    最近在学习PyQt5可视化界面,这是一个内容非常丰富的gui库,相对于tkinter库,功能更加强大,界面更加美观,操作也不难。于是我开始小试牛刀,用PyQt...

    python学习教程
  • 机器学习|用Q-Learning走迷宫

    上文中我们了解了Q-Learning算法的思想,基于这种思想我们可以实现很多有趣的功能和小demo,本文让我们通过Q-Learning算法来实现用计算机来走迷宫...

    数据山谷

扫码关注云+社区

领取腾讯云代金券