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

俄罗斯方块游戏,使用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()
(0)

相关推荐

  • 用Python写一个无界面的2048小游戏

    以前游戏2048火的时候,正好用其他的语言编写了一个,现在学习python,正好想起来,便决定用python写一个2048,由于没学过python里面的界面编程,所以写了一个极其简单的无界面2048.游戏2048的原理和实现都不难,正好可以拿来练手,要是不知道这游戏的话,可以去网上查一下,或者下载一个到手机来玩一下,我就不在说其原理.我知道不放图的话大家一点兴趣都没,下面首先放一张游戏成型图,然后我们在来讲如何一步步用最基础的知识来实现. 一.生成4*4的矩阵 游戏的第一步便是生成一个4*4的矩

  • 用Python设计一个经典小游戏

    本文主要介绍如何用Python设计一个经典小游戏:猜大小. 在这个游戏中,将用到前面我介绍过的所有内容:变量的使用.参数传递.函数设计.条件控制和循环等,做个整体的总结和复习. 游戏规则: 初始本金是1000元,默认赔率是1倍,赢了,获得一倍金额,输了,扣除1倍金额. 玩家选择下注,押大或押小: 输入下注金额: 摇3个骰子,11≤骰子总数≤18为大,3≤骰子总数≤10为小: 如果赢了,获得1倍金额,输了,扣除1倍金额,本金为0时,游戏结束. 程序运行结果是这样的: 现在,我们来梳理下思路. 我们

  • 基于Python实现的扫雷游戏实例代码

    本文实例借鉴mvc模式,核心数据为model,维护1个矩阵,0表无雷,1表雷,-1表已经检测过. 本例使用python的tkinter做gui,由于没考虑可用性问题,因此UI比较难看,pygame更有趣更强大更好看,做这些小游戏更合适,感兴趣的读者可以尝试一下! 具体的功能代码如下: # -*- coding: utf-8 -*- import random import sys from Tkinter import * class Model: """ 核心数据类,维护一

  • python开发的小球完全弹性碰撞游戏代码

    完成这个小球的完全弹性碰撞游戏灵感来自于: 下面是我花了一周下班时间所编写的一个小球完全弹性碰撞游戏: 游戏初始化状态: 最下面的游标和修改小球的移动速度 源码部分: 复制代码 代码如下: #python tkinter#python version 3.3.2 from tkinter import * '''    判断    两个小球    {        圆心:A(x1,y1)  半径:r  X轴速度:Vax  Y轴速度:Vay        圆心:B(x2,y2)  半径:R  X轴

  • python实现的简单猜数字游戏

    本文实例讲述了python实现的简单猜数字游戏.分享给大家供大家参考.具体如下: 给定一个1-99之间的数,让用户猜数字,当用户猜错时会提示用户猜的数字是过大还是过小,知道用户猜对数字为止,猜对数字用的次数越少成绩越好. import random n = random.randint(1, 99) guess = int(raw_input("Enter an integer from 1 to 99: ")) while n != "guess": print

  • Python写的贪吃蛇游戏例子

    第一次用Python写这种比较实用且好玩的东西,权当练手吧 游戏说明: * P键控制"暂停/开始"* 方向键控制贪吃蛇的方向 源代码如下: 复制代码 代码如下: from Tkinter import *import tkMessageBox,sysfrom random import randint class Grid(object):    def __init__(self,master=None,window_width=800,window_height=600,grid_

  • 跟老齐学Python之做一个小游戏

    在讲述有关list的时候,提到做游戏的事情,后来这个事情一直没有接续.不是忘记了,是在想在哪个阶段做最合适.经过一段时间学习,看官已经不是纯粹小白了,已经属于python初级者了.现在就是开始做那个游戏的时候了. 游戏内容:猜数字游戏 太简单了吧.是的,游戏难度不大,不过这个游戏中蕴含的东西可是值得玩味的. 游戏过程描述 程序运行起来,随机在某个范围内选择一个整数. 提示用户输入数字,也就是猜程序随即选的那个数字. 程序将用户输入的数字与自己选定的对比,一样则用户完成游戏,否则继续猜. 使用次数

  • 一步步教你用Python实现2048小游戏

    前言 2048游戏规则:简单的移动方向键让数字叠加,并且获得这些数字每次叠加后的得分,当出现2048这个数字时游戏胜利.同时每次移动方向键时,都会在这个4*4的方格矩阵的空白区域随机产生一个数字2或者4,如果方格被数字填满了,那么就GameOver了. 主逻辑图 逻辑图解:黑色是逻辑层,蓝色是外部方法,红色是类内方法,稍后即可知道~ 下面容我逐行解释主逻辑main()函数,并且在其中穿叉外部定义的函数与类. 主逻辑代码解读(完整代码见文末) 主逻辑main如下,之后的是对主函数中的一些方法的解读

  • Python实现的弹球小游戏示例

    本文实例讲述了Python实现的弹球小游戏.分享给大家供大家参考,具体如下: 弹球 1. Ball 类 draw负责移动Ball 碰撞检测,反弹,Ball检测Paddle 2.Paddle类 draw负责移动Paddle 碰撞检测,确定能不能继续 监听键盘事件 3.主循环 绘制Ball和Paddle update sleep 代码 from Tkinter import * import random import time class Ball: def __init__(self, canv

  • Python基于pygame实现的弹力球效果(附源码)

    本文实例讲述了Python基于pygame实现的弹力球效果.分享给大家供大家参考,具体如下: 运行效果: 代码部分如下: #A bouncing ball import sys, pygame __author__ = {'name' : 'Hongten', 'mail' : 'hongtenzone@foxmail.com', 'QQ' : '648719819', 'Version' : '1.0'} pygame.init() size = width, height = 600, 50

  • Python新手实现2048小游戏

    接触 Python 不久,看到很多人写2048,自己也捣鼓了一个,主要是熟悉Python语法. 程序使用Python3 写的,代码150行左右,基于控制台,方向键使用输入字符模拟. 演示图片 2048.py # -*- coding:UTF-8 -*- #! /usr/bin/python3 import random v = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] def display(v, score): '''显示

  • python实现2048小游戏

    2048的python实现.修改自某网友的代码,解决了原网友版本的两个小bug: 1. 原版游戏每次只消除一次,而不是递归消除.如 [2 ,2 ,2 ,2] 左移动的话应该是 [4, 4, 0, 0] , 而不是[8 , 0 , 0 ,0] 2. 对游戏结束的侦测有bug,已经改正. 2048game.py # -*- coding: utf-8 -*- """ Created on Tue Jul 1 14:15:39 2014 @author: kelvin "

随机推荐