用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实现简单的TCP代理服务器
Oct 08 Python
python通过openpyxl生成Excel文件的方法
May 12 Python
Python Matplotlib库入门指南
May 18 Python
使用Python实现一个栈判断括号是否平衡
Aug 23 Python
python使用KNN算法识别手写数字
Apr 25 Python
pandas DataFrame 交集并集补集的实现
Jun 24 Python
python itsdangerous模块的具体使用方法
Feb 17 Python
Python操作MongoDb数据库流程详解
Mar 05 Python
python+selenium 简易地疫情信息自动打卡签到功能的实现代码
Aug 22 Python
python 爬取免费简历模板网站的示例
Sep 27 Python
python向企业微信发送文字和图片消息的示例
Sep 28 Python
工程师必须了解的LRU缓存淘汰算法以及python实现过程
Oct 15 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
基于mysql的论坛(1)
2006/10/09 PHP
Laravel框架中实现使用阿里云ACE缓存服务
2015/02/10 PHP
ExtJS Ext.MessageBox.alert()弹出对话框详解
2010/04/02 Javascript
jquery根据属性和index来查找属性值并操作
2014/07/25 Javascript
用循环或if语句从json中取数据示例
2014/08/18 Javascript
jQuery中die()方法用法实例
2015/01/19 Javascript
js+div实现文字滚动和图片切换效果代码
2015/08/27 Javascript
Javascript基于AJAX回调函数传递参数实例分析
2015/12/15 Javascript
Javascript数组Array基础介绍
2016/03/13 Javascript
微信小程序  action-sheet详解及实例代码
2016/11/09 Javascript
AngularJS Toaster使用详解
2017/02/24 Javascript
老生常谈javascript的面向对象思想
2017/08/22 Javascript
Vue微信项目按需授权登录策略实践思路详解
2018/05/07 Javascript
Layer组件多个iframe弹出层打开与关闭及参数传递的方法
2019/09/25 Javascript
详解一些适用于Node.js的命名约定
2019/12/08 Javascript
JS实现网页烟花动画效果
2020/03/10 Javascript
通过vue刷新左侧菜单栏操作
2020/08/06 Javascript
[00:58]他们到底在电话里听到了什么?
2017/11/21 DOTA
[02:39]我与DAC之Newbee.Moogy:从论坛到TI
2018/03/26 DOTA
python使用正则表达式分析网页中的图片并进行替换的方法
2015/03/26 Python
python中pygame针对游戏窗口的显示方法实例分析(附源码)
2015/11/11 Python
python编程之requests在网络请求中添加cookies参数方法详解
2017/10/25 Python
浅析PHP与Python进行数据交互
2018/05/15 Python
Python3之手动创建迭代器的实例代码
2019/05/22 Python
使用python脚本自动创建pip.ini配置文件代码实例
2019/09/20 Python
python识别验证码图片实例详解
2020/02/17 Python
Python3 操作 MySQL 插入一条数据并返回主键 id的实例
2020/03/02 Python
Django+Django-Celery+Celery的整合实战
2021/01/20 Python
使用分层画布来优化HTML5渲染的教程
2015/05/08 HTML / CSS
Html5实现二维码扫描并解析
2016/01/20 HTML / CSS
意大利体育用品网上商城:Nencini Sport
2016/08/18 全球购物
PHP数据运算类型都有哪些
2013/11/05 面试题
《两个铁球同时着地》教学反思
2014/02/13 职场文书
不服劳动仲裁起诉书
2015/05/20 职场文书
Nginx已编译的nginx-添加新模块
2021/04/01 Servers
解决golang post文件时Content-Type出现的问题
2021/05/02 Golang