用Python编写一个简单的俄罗斯方块游戏的教程


Posted in Python onApril 03, 2015

俄罗斯方块游戏,使用Python实现,总共有350+行代码,实现了俄罗斯方块游戏的基本功能,同时会记录所花费时间,消去的总行数,所得的总分,还包括一个排行榜,可以查看最高记录。

排行榜中包含一系列的统计功能,如单位时间消去的行数,单位时间得分等。

 

附源码:

   

from Tkinter import * 
  from tkMessageBox import * 
  import random 
  import time 
  #俄罗斯方块界面的高度 
  HEIGHT = 18 
  #俄罗斯方块界面的宽度 
  WIDTH  = 10 
  ACTIVE = 1 
  PASSIVE = 0 
  TRUE  = 1 
  FALSE  = 0 
  root=Tk();root.title('Russia') 
  class App(Frame): 
    def __init__(self,master): 
      Frame.__init__(self) 
      master.bind('<Up>',self.Up) 
      master.bind('<Left>',self.Left) 
      master.bind('<Right>',self.Right) 
      master.bind('<Down>',self.Down) 
      #master.bind('<Down>',self.Space) 
      master.bind('<space>',self.Space) 
      master.bind('<Control-Shift-Key-F12>',self.Play) 
      master.bind('<Key-F6>',self.Pause) 
      self.backg="#%02x%02x%02x" % (120,150,30) 
      self.frontg="#%02x%02x%02x" % (40,120,150) 
      self.nextg="#%02x%02x%02x" % (150,100,100) 
      self.flashg="#%02x%02x%02x" % (210,130,100) 
      self.LineDisplay=Label(master,text='Lines: ',bg='black',fg='red') 
      self.Line=Label(master,text='0',bg='black',fg='red') 
      self.ScoreDisplay=Label(master,text='Score: ',bg='black',fg='red') 
      self.Score=Label(master,text='0',bg='black',fg='red') 
      #Display time 
      self.SpendTimeDisplay=Label(master,text='Time: ',bg='black',fg='red') 
      self.SpendTime=Label(master,text='0.0',bg='black',fg='red') 
      self.LineDisplay.grid(row=HEIGHT-2,column=WIDTH,columnspan=2) 
      self.Line.grid(row=HEIGHT-2,column=WIDTH+2,columnspan=3) 
      self.ScoreDisplay.grid(row=HEIGHT-1,column=WIDTH,columnspan=2) 
      self.Score.grid(row=HEIGHT-1,column=WIDTH+2,columnspan=3) 
      #Display time 
      self.SpendTimeDisplay.grid(row=HEIGHT-4,column=WIDTH,columnspan=2) 
      self.SpendTime.grid(row=HEIGHT-4,column=WIDTH+2,columnspan=3) 
      self.TotalTime=0.0 
      self.TotalLine=0;self.TotalScore=0 
      #Game over 
      self.isgameover=FALSE 
      #Pause 
      self.isPause=FALSE 
      #Start 
      self.isStart=FALSE 
      self.NextList=[];self.NextRowList=[] 
      r=0;c=0 
      for k in range(4*4): 
        LN=Label(master,text='  ',bg=str(self.nextg),fg='white',relief=FLAT,bd=4) 
        LN.grid(row=r,column=WIDTH+c,sticky=N+E+S+W) 
        self.NextRowList.append(LN) 
        c=c+1 
        if c>=4: 
          r=r+1;c=0 
          self.NextList.append(self.NextRowList) 
          self.NextRowList=[] 
      self.BlockList=[];self.LabelList=[] 
      self.BlockRowList=[];self.LabelRowList=[] 
      row=0;col=0 
      for i in range(HEIGHT*WIDTH): 
        L=Label(master,text='  ',bg=str(self.backg),fg='white',relief=FLAT,bd=4) 
        L.grid(row=row,column=col,sticky=N+E+S+W) 
        L.row=row;L.col=col;L.isactive=PASSIVE 
        self.BlockRowList.append(0);self.LabelRowList.append(L) 
        col=col+1 
        if col>=WIDTH: 
          row=row+1;col=0 
          self.BlockList.append(self.BlockRowList) 
          self.LabelList.append(self.LabelRowList) 
          self.BlockRowList=[];self.LabelRowList=[] 
      #file 
      fw=open('text.txt','a') 
      fw.close() 
      hasHead=FALSE 
      f=open('text.txt','r') 
      if f.read(5)=='score': 
        hasHead=TRUE 
      f.close() 
      self.file=open('text.txt','r+a') 
      if hasHead==FALSE: 
        self.file.write('score  line  time  scorePtime  linePtime  scorePline  date/n') 
        self.file.flush() 
         
      self.time=1000 
      self.OnTimer() 
    def __del__(self): 
      #self.file.close() 
      pass 
       
    def Pause(self,event): 
      self.isPause=1-self.isPause 
    def Up(self,event): 
      BL=self.BlockList;LL=self.LabelList 
      Moveable=TRUE 
      xtotal=0;ytotal=0;count=0 
      for i in range(HEIGHT): 
        for j in range(WIDTH): 
          if LL[i][j].isactive==ACTIVE: 
            xtotal=xtotal+i;ytotal=ytotal+j;count=count+1 
      SourceList=[];DestList=[] 
      for i in range(HEIGHT): 
        for j in range(WIDTH): 
          if LL[i][j].isactive==ACTIVE: 
            x0=(xtotal+ytotal)/count;y0=(ytotal-xtotal )/count 
            xr=(xtotal+ytotal)%count;yr=(ytotal-xtotal)%count 
            x=x0-j;y=y0+i 
            if xr>=count/2:x=x+1 
            if yr>=count/2:y=y+1 
            SourceList.append([i,j]);DestList.append([x,y]) 
            if x<0 or x>=HEIGHT or y<0 or y>=WIDTH:Moveable=FALSE 
            if x>=0 and x<HEIGHT and y>=0 and y<WIDTH and BL[x][y]==1 and LL[x][y].isactive==PASSIVE:Moveable=FALSE 
      if Moveable==TRUE: 
        for i in range(len(SourceList)): 
          self.Empty(SourceList[i][0],SourceList[i][1]) 
        for i in range(len(DestList)): 
          self.Fill(DestList[i][0],DestList[i][1]) 
    def Left(self,event): 
      BL=self.BlockList;LL=self.LabelList 
      Moveable=TRUE 
      for i in range(HEIGHT): 
        for j in range(WIDTH): 
          if LL[i][j].isactive==ACTIVE and j-1<0:Moveable=FALSE 
          if LL[i][j].isactive==ACTIVE and j-1>=0 and BL[i][j-1]==1 and LL[i][j-1].isactive==PASSIVE:Moveable=FALSE 
      if Moveable==TRUE: 
        for i in range(HEIGHT): 
          for j in range(WIDTH): 
            if j-1>=0 and LL[i][j].isactive==ACTIVE and BL[i][j-1]==0: 
              self.Fill(i,j-1);self.Empty(i,j) 
    def Right(self,event): 
      BL=self.BlockList;LL=self.LabelList 
      Moveable=TRUE 
      for i in range(HEIGHT): 
        for j in range(WIDTH): 
          if LL[i][j].isactive==ACTIVE and j+1>=WIDTH:Moveable=FALSE 
          if LL[i][j].isactive==ACTIVE and j+1<WIDTH and BL[i][j+1]==1 and LL[i][j+1].isactive==PASSIVE:Moveable=FALSE 
      if Moveable==TRUE: 
        for i in range(HEIGHT-1,-1,-1): 
          for j in range(WIDTH-1,-1,-1): 
            if j+1<WIDTH and LL[i][j].isactive==ACTIVE and BL[i][j+1]==0: 
              self.Fill(i,j+1);self.Empty(i,j) 
    def Space(self,event): 
      while 1: 
        if self.Down(0)==FALSE:break 
    def OnTimer(self): 
      if self.isStart==TRUE and self.isPause==FALSE: 
        self.TotalTime = self.TotalTime + float(self.time)/1000 
        self.SpendTime.config(text=str(self.TotalTime)) 
       
      if self.isPause==FALSE: 
        self.Down(0) 
      if self.TotalScore>=1000:self.time=900 
      if self.TotalScore>=2000:self.time=750 
      if self.TotalScore>=3000:self.time=600 
      if self.TotalScore>=4000:self.time=400 
      self.after(self.time,self.OnTimer) 
    def Down(self,event): 
      BL=self.BlockList;LL=self.LabelList 
      Moveable=TRUE 
      for i in range(HEIGHT): 
        for j in range(WIDTH): 
          if LL[i][j].isactive==ACTIVE and i+1>=HEIGHT:Moveable=FALSE 
          if LL[i][j].isactive==ACTIVE and i+1<HEIGHT and BL[i+1][j]==1 and LL[i+1][j].isactive==PASSIVE:Moveable=FALSE 
      if Moveable==TRUE: 
        for i in range(HEIGHT-1,-1,-1): 
          for j in range(WIDTH-1,-1,-1): 
            if i+1<HEIGHT and LL[i][j].isactive==ACTIVE and BL[i+1][j]==0: 
              self.Fill(i+1,j);self.Empty(i,j) 
      if Moveable==FALSE: 
        for i in range(HEIGHT): 
          for j in range(WIDTH): 
            LL[i][j].isactive=PASSIVE 
        self.JudgeLineFill() 
        self.Start() 
        if self.isgameover==TRUE:showinfo('T_T','The game is over!');self.Distroy();return FALSE 
        for i in range(4): 
          for j in range(4): 
            self.NextEmpty(i,j) 
        self.Rnd() 
      return Moveable 
    def JudgeLineFill(self): 
      BL=self.BlockList;LL=self.LabelList 
      count=0;LineList=[] 
      for i in range(WIDTH):LineList.append(1) 
      #display flash 
      for i in range(HEIGHT): 
        if BL[i]==LineList: 
          count=count+1 
          for k in range(WIDTH): 
            LL[i][k].config(bg=str(self.flashg)) 
            LL[i][k].update() 
      if count!=0:self.after(100) 
      #delete block 
      for i in range(HEIGHT): 
        if BL[i]==LineList: 
          #count=count+1 
          for j in range(i,0,-1): 
            for k in range(WIDTH): 
              BL[j][k]=BL[j-1][k] 
              LL[j][k]['relief']=LL[j-1][k].cget('relief') 
              LL[j][k]['bg']=LL[j-1][k].cget('bg') 
          for l in range(WIDTH): 
            BL[0][l]=0 
            LL[0][l].config(relief=FLAT,bg=str(self.backg)) 
      self.TotalLine=self.TotalLine+count 
      if count==1:self.TotalScore=self.TotalScore+1*WIDTH 
      if count==2:self.TotalScore=self.TotalScore+3*WIDTH 
      if count==3:self.TotalScore=self.TotalScore+6*WIDTH 
      if count==4:self.TotalScore=self.TotalScore+10*WIDTH 
      self.Line.config(text=str(self.TotalLine)) 
      self.Score.config(text=str(self.TotalScore)) 
    def Fill(self,i,j): 
      if j<0:return 
      if self.BlockList[i][j]==1:self.isgameover=TRUE 
      self.BlockList[i][j]=1 
      self.LabelList[i][j].isactive=ACTIVE 
      self.LabelList[i][j].config(relief=RAISED,bg=str(self.frontg)) 
    def Empty(self,i,j): 
      self.BlockList[i][j]=0 
      self.LabelList[i][j].isactive=PASSIVE 
      self.LabelList[i][j].config(relief=FLAT,bg=str(self.backg)) 
    def Play(self,event): 
      showinfo('Made in China','^_</font></p> 
  <p><span mce_name="em" style="font-style: italic;" class="Apple-style-span" mce_style="font-style: italic;"><span style="font-size: small; " id="" mce_style="font-size: small;"><br></span></span></p> 
  <p><span mce_name="em" style="font-style: italic;" class="Apple-style-span" mce_style="font-style: italic;"><span style="font-size: small; " id="" mce_style="font-size: small;">  </span></span></p> 
  <p><br></p>) 
    def NextFill(self,i,j): 
      self.NextList[i][j].config(relief=RAISED,bg=str(self.frontg)) 
    def NextEmpty(self,i,j): 
      self.NextList[i][j].config(relief=FLAT,bg=str(self.nextg)) 
    def Distroy(self): 
      #save 
      if self.TotalScore!=0: 
        savestr='%-9u%-8u%-8.2f%-14.2f%-13.2f%-14.2f%s/n' % (self.TotalScore,self.TotalLine,self.TotalTime 
                          ,self.TotalScore/self.TotalTime 
                          ,self.TotalLine/self.TotalTime 
                          ,float(self.TotalScore)/self.TotalLine 
                          ,time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())) 
        self.file.seek(0,2) 
        self.file.write(savestr) 
        self.file.flush() 
       
      for i in range(HEIGHT): 
        for j in range(WIDTH): 
          self.Empty(i,j) 
      self.TotalLine=0;self.TotalScore=0;self.TotalTime=0.0 
      self.Line.config(text=str(self.TotalLine)) 
      self.Score.config(text=str(self.TotalScore)) 
      self.SpendTime.config(text=str(self.TotalTime)) 
      self.isgameover=FALSE 
      self.isStart=FALSE 
      self.time=1000 
      for i in range(4): 
        for j in range(4): 
          self.NextEmpty(i,j) 
    def Start(self): 
      if self.x==1:self.Fill(0,WIDTH/2-2);self.Fill(0,WIDTH/2-1);self.Fill(0,WIDTH/2);self.Fill(0,WIDTH/2+1) 
      if self.x==2:self.Fill(0,WIDTH/2-1);self.Fill(0,WIDTH/2);self.Fill(1,WIDTH/2-1);self.Fill(1,WIDTH/2) 
      if self.x==3:self.Fill(0,WIDTH/2);self.Fill(1,WIDTH/2-1);self.Fill(1,WIDTH/2);self.Fill(1,WIDTH/2+1) 
      if self.x==4:self.Fill(0,WIDTH/2-1);self.Fill(1,WIDTH/2-1);self.Fill(1,WIDTH/2);self.Fill(1,WIDTH/2+1) 
      if self.x==5:self.Fill(0,WIDTH/2+1);self.Fill(1,WIDTH/2-1);self.Fill(1,WIDTH/2);self.Fill(1,WIDTH/2+1) 
      if self.x==6:self.Fill(0,WIDTH/2-1);self.Fill(0,WIDTH/2);self.Fill(1,WIDTH/2);self.Fill(1,WIDTH/2+1) 
      if self.x==7:self.Fill(0,WIDTH/2);self.Fill(0,WIDTH/2+1);self.Fill(1,WIDTH/2-1);self.Fill(1,WIDTH/2) 
      self.isStart=TRUE 
    def Rnd(self): 
      self.x=random.randint(1,7) 
      if self.x==1:self.NextFill(0,0);self.NextFill(0,1);self.NextFill(0,2);self.NextFill(0,3) 
      if self.x==2:self.NextFill(0,1);self.NextFill(0,2);self.NextFill(1,1);self.NextFill(1,2) 
      if self.x==3:self.NextFill(0,2);self.NextFill(1,1);self.NextFill(1,2);self.NextFill(1,3) 
      if self.x==4:self.NextFill(0,1);self.NextFill(1,1);self.NextFill(1,2);self.NextFill(1,3) 
      if self.x==5:self.NextFill(0,3);self.NextFill(1,1);self.NextFill(1,2);self.NextFill(1,3) 
      if self.x==6:self.NextFill(0,1);self.NextFill(0,2);self.NextFill(1,2);self.NextFill(1,3) 
      if self.x==7:self.NextFill(0,2);self.NextFill(0,3);self.NextFill(1,1);self.NextFill(1,2) 
    def RndFirst(self): 
      self.x=random.randint(1,7) 
    def Show(self): 
      self.file.seek(0) 
      strHeadLine=self.file.readline() 
      dictLine={} 
      strTotalLine='' 
      for OneLine in self.file.readlines(): 
        temp=int(OneLine[:5]) 
        dictLine[temp]=OneLine 
         
      list=sorted(dictLine.items(),key=lambda d:d[0]) 
      ii=0     
      for onerecord in reversed(list): 
        ii=ii+1 
        if ii<11: 
          strTotalLine+=onerecord[1] 
      showinfo('Ranking', strHeadLine+strTotalLine) 
  def Start(): 
    app.RndFirst();app.Start();app.Rnd() 
  def End(): 
    app.Distroy() 
  def Set(): 
    pass 
  def Show(): 
    app.Show() 
   
  mainmenu=Menu(root) 
  root['menu']=mainmenu 
  gamemenu=Menu(mainmenu) 
  mainmenu.add_cascade(label='game',menu=gamemenu) 
  gamemenu.add_command(label='start',command=Start) 
  gamemenu.add_command(label='end',command=End) 
  gamemenu.add_separator() 
  gamemenu.add_command(label='exit',command=root.quit) 
  setmenu=Menu(mainmenu) 
  mainmenu.add_cascade(label='set',menu=setmenu) 
  setmenu.add_command(label='set',command=Set) 
  showmenu=Menu(mainmenu) 
  mainmenu.add_cascade(label='show',menu=showmenu) 
  showmenu.add_command(label='show',command=Show) 
  app=App(root) 
  root.mainloop()
Python 相关文章推荐
python使用datetime模块计算各种时间间隔的方法
Mar 24 Python
Python操作串口的方法
Jun 17 Python
Python 数据结构之堆栈实例代码
Jan 22 Python
Python 关于反射和类的特殊成员方法
Sep 14 Python
ubuntu环境下python虚拟环境的安装过程
Jan 07 Python
python实现遍历文件夹修改文件后缀
Aug 28 Python
详解python使用turtle库来画一朵花
Mar 21 Python
Python3实现二叉树的最大深度
Sep 30 Python
wxpython实现按钮切换界面的方法
Nov 19 Python
python中urllib.request和requests的使用及区别详解
May 05 Python
python怎么提高计算速度
Jun 11 Python
python-地图可视化组件folium的操作
Dec 14 Python
用Python代码来绘制彭罗斯点阵的教程
Apr 03 #Python
利用Python演示数型数据结构的教程
Apr 03 #Python
简洁的十分钟Python入门教程
Apr 03 #Python
初步解析Python中的yield函数的用法
Apr 03 #Python
几个提升Python运行效率的方法之间的对比
Apr 03 #Python
对于Python的Django框架使用的一些实用建议
Apr 03 #Python
《Python之禅》中对于Python编程过程中的一些建议
Apr 03 #Python
You might like
1982年日本摄影师镜头下的中国孩子 那无忧无虑的童年
2020/03/12 杂记
Zerg建筑一览
2020/03/14 星际争霸
PHP+Mysql树型结构(无限分类)数据库设计的2种方式实例
2014/07/15 PHP
PHP中开启gzip压缩的2种方法
2015/01/31 PHP
PHP使用DirectoryIterator显示下拉文件列表的方法
2015/03/13 PHP
浅析php静态方法与非静态方法的用法区别
2016/05/17 PHP
Yii框架连接mongodb数据库的代码
2016/07/27 PHP
strpos() 函数判断字符串中是否包含某字符串的方法
2019/01/16 PHP
html超链接打开窗口大小的方法
2013/03/05 Javascript
js阻止浏览器默认行为触发的通用方法(推荐)
2016/05/15 Javascript
微信小程序 网络API发起请求详解
2016/11/09 Javascript
微信小程序 textarea 组件详解及简单实例
2017/01/10 Javascript
ajax分页效果(bootstrap模态框)
2017/01/23 Javascript
解决html-jquery/js引用外部图片时遇到看不了或出现403的问题
2017/09/22 jQuery
JS运动改变单物体透明度的方法分析
2018/01/23 Javascript
ES6知识点整理之模块化的应用详解
2019/04/15 Javascript
深入浅析Vue 中 ref 的使用
2019/04/29 Javascript
Async/Await替代Promise的6个理由
2019/06/15 Javascript
基于Vue实现微前端的示例代码
2020/04/24 Javascript
JavaScript 引用类型实例详解【数组、对象、严格模式等】
2020/05/13 Javascript
使用JavaScript和MQTT开发物联网应用示例解析
2020/08/07 Javascript
小程序组件传值和引入sass的方法(使用vant Weapp组件库)
2020/11/24 Javascript
[07:48]DOTA2上海特级锦标赛主赛事首日RECAP
2016/03/04 DOTA
利用Python的Django框架中的ORM建立查询API
2015/04/20 Python
wxPython电子表格功能wx.grid实例教程
2019/11/19 Python
HTML5通用接口详解
2016/06/12 HTML / CSS
Mytheresa英国官网:拥有160多个奢侈品品牌
2016/10/09 全球购物
中东地区最大的奢侈品市场:The Luxury Closet
2019/04/09 全球购物
洛佩桑酒店官方网站:Lopesan Hotels
2019/04/15 全球购物
如何向接受结构参数的函数传入常数值
2016/02/17 面试题
介绍一下Transact-SQL中SPACE函数的用法
2015/09/01 面试题
小学生2014国庆节演讲稿:祖国在我心中
2014/09/21 职场文书
2016年先进班集体事迹材料
2016/02/26 职场文书
2019银行员工个人工作自我鉴定
2019/06/27 职场文书
win11高清晰音频管理器在哪里?win11找不到高清晰音频管理器解决办法
2022/04/08 数码科技
Android开发EditText禁止输入监听及InputFilter字符过滤
2022/06/10 Java/Android