用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标准库urllib2的一些使用细节总结
Mar 16 Python
Python随机生成一个6位的验证码代码分享
Mar 24 Python
python使用pil生成图片验证码的方法
May 08 Python
Python实现Linux的find命令实例分享
Jun 04 Python
python实现各进制转换的总结大全
Jun 18 Python
pandas.DataFrame 根据条件新建列并赋值的方法
Apr 08 Python
python爬取淘宝商品销量信息
Nov 16 Python
详解python中的hashlib模块的使用
Apr 22 Python
Python全栈之列表数据类型详解
Oct 01 Python
pytorch ImageFolder的覆写实例
Feb 20 Python
python实现飞机大战项目
Mar 11 Python
python logging通过json文件配置的步骤
Apr 27 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
PHP 和 XML: 使用expat函数(二)
2006/10/09 PHP
使用NetBeans + Xdebug调试PHP程序的方法
2011/04/12 PHP
教你如何使用php session
2013/10/28 PHP
PHP5.3以上版本安装ZendOptimizer扩展
2015/03/27 PHP
thinkphp3.2.3版本的数据库增删改查实现代码
2016/09/22 PHP
php封装的page分页类完整实例
2016/10/18 PHP
php array_multisort 对数组进行排序详解及实例代码
2016/10/27 PHP
JS处理VBArray的函数使用说明
2008/05/11 Javascript
javascript 数组排序函数
2009/08/20 Javascript
页面版文本框智能提示JS代码
2009/11/20 Javascript
js打印纸函数代码(递归)
2010/06/18 Javascript
Map.vue基于百度地图组件重构笔记分享
2017/04/17 Javascript
浅谈angular.js跨域post解决方案
2017/08/30 Javascript
javascript实现电脑和手机版样式切换
2017/11/10 Javascript
elementUI select组件默认选中效果实现的方法
2019/03/25 Javascript
js使用文档就绪函数动态改变页面内容示例【innerHTML、innerText】
2019/11/07 Javascript
Vue实现渲染数据后控制滚动条位置(推荐)
2019/12/09 Javascript
JavaScript 链表定义与使用方法示例
2020/04/28 Javascript
[01:54]TI珍贵瞬间系列(三):翻盘
2020/08/28 DOTA
Python扩展内置类型详解
2018/03/26 Python
Python一键安装全部依赖包的方法
2019/08/12 Python
Django如何实现网站注册用户邮箱验证功能
2019/08/14 Python
tensorflow没有output结点,存储成pb文件的例子
2020/01/04 Python
Python日志syslog使用原理详解
2020/02/18 Python
详解pandas中iloc, loc和ix的区别和联系
2020/03/09 Python
python实现粒子群算法
2020/10/15 Python
中专自我鉴定范文
2013/10/16 职场文书
教学实习自我评价
2014/01/28 职场文书
开办大学饮食联盟创业计划书
2014/01/29 职场文书
交通事故检查书范文
2014/01/30 职场文书
乡镇干部十八大感言
2014/02/17 职场文书
出生公证书
2015/01/23 职场文书
房屋维修申请报告
2015/05/18 职场文书
小学语文教学随笔
2015/08/14 职场文书
谢师宴学生答谢词
2015/09/30 职场文书
导游词之青城山景区
2019/09/27 职场文书