python练手--自制俄罗斯方块(文末附源码)
2017-06-12 21:00
501 查看
小白python学习中,刚把面向对象弄了个大概,打算找个项目练练手,于是决定做一个俄罗斯方块吧!然后到现在一个月就过去了。。。。。
期间接触了一下pygame,参考了目光博客的Pygame教程,当时感觉看懂了,等到用的时候,哈哈哈,感觉把pygame用成了画图程序。。。。。
其实,到现在我的俄罗斯方块也只是完成了一个DEMO,还有很多东西没有完善,而且也没考虑过性能,不过要出差一段时间不能学习了,所以决定先把DEMO发出来,等回头再来填坑。。。。。
整个程序如果不看注释,只看代码,应该大概是400行吧,运行时图如下,
主要说一下显示区,方块系统,和碰撞检测的思路吧,其他的都比较简单了。
显示区,通过维护四个列表,分别记录正在下落方块和已经落地方块的坐标和颜色,之后在把方块画出来。这里的坐标不是方块在窗口显示位置的坐标,而是列表内的‘相对坐标’,其实就是索引值。
什么是列表内的‘相对坐标’呢,这个得先说一下这个列表是什么鬼。
因为我的显示区,是一个以20像素的方块为单位,一共宽10个方块,高22个方块的区域,所以我的想法是,建立一个12*26的列表来与之对应(为什么是12*26呢,一开始我确实是做了一个10*22的列表,不过后来为了加入边界,把列表加到了12*23,再后来为了让方块从屏幕外一格一格进入显示区,就变成了12*26,这些后面再说。。。),在这个12*26的列表里面,0表示没有方块,1表示左右边界和下边界,然后当方块进入显示区以后,0变成1,表示此处有方块,而刚才所说的相对坐标,其实就是这个列表的索引值了。
这样我们有了相对坐标系,不过还不能用它来画方块,因为pygame画方块需要窗口坐标,所以我还要把相对坐标转换成屏幕坐标,比较简单,就是坐标系换算,一道数学题而已。
然后方块系统,我的方块系统只包括了上下左右四个操作,分别对应了旋转,向下移动一格,向左移动一格,向右移动一格,我把他们做成一个类的四个方法,其中左右下三个操作很简单,坐标加1减1就可以了,就是上操作,旋转,比较麻烦,没想到好办法,我只能将7个方块的所有状态一一编号,然后把旋转时坐标的相对变化全都写出来,累。。。。。中间还加上了贴墙位移,是为了防止旋转以后方块进到墙里面去,或者因为与墙面发生碰撞检测而导致不能旋转的情况。
算旋转时坐标变化的草图如下(要注意转一圈以后能转回初始位置,不然一直转的话,方块会产生位移)
再然后是碰撞检测,原理就是先记录动作前的坐标,然后执行动作,判断动作后的坐标,与墙面,与已经落地方块的坐标,是否重合。因为碰撞检测在每一次动作的时候都要执行一次,所以在实现的时候,我把它做成了一个装饰器,装饰在方块类上。(为了做这个装饰器,现学的如何对类进行装饰。。。。。)
其他的还有一个自己做的用来完成坐标运算的类,非常简陋,因为只是为了一次使用做的,所以只有一个加法运算,而且没有优化。这个类是参考了目光博客pygame教程里面向量运算的类做的。
剩下的就是逻辑了,本来以为写逻辑很简单的,没想到写逻辑写到一度怀疑自己没有逻辑。。。。尤其是,一直想做的按住左键就能一直向左移动的功能,感觉应该可以靠逻辑实现,不过到目前还没想出来。
总结写俄罗斯方块这一段时间的学习,对类有了新的认识,之前觉得类主要就是为了继承而存在的,不过这次虽然也写了类,却没用到继承,反而发现类的属性简直太好用了!!!
对于俄罗斯方块这个程序来说,感觉最难的是一开始,构想如何把方块画出来,这里还要考虑方块旋转,还要考虑以后消除行的时候能不能操作,还要考虑碰撞检测。最开始没有决定用列表和坐标解决这个问题的时候,还考虑过用精灵表示一个方块,不过方块是不规则的,不知道如何来做碰撞检测,上网去搜,在网上看见小甲鱼有一个飞机大战里面讲到对透明部分进行处理,然后完成不规则的碰撞检测,不过没有搞懂,去研究官方文档也没搞懂,还有什么掩码什么的,也是搞得我晕头转向,所以不得不暂时放弃了使用精灵的打算,看来想入门游戏要学的还有太多,手动哭一个吧。。。。
最后附上代码,和代码下载地址,欢迎讨论,欢迎指导,一起成长,手动笑。
下载地址,http://download.csdn.net/detail/highmiao_19/9868601
代码如下:
期间接触了一下pygame,参考了目光博客的Pygame教程,当时感觉看懂了,等到用的时候,哈哈哈,感觉把pygame用成了画图程序。。。。。
其实,到现在我的俄罗斯方块也只是完成了一个DEMO,还有很多东西没有完善,而且也没考虑过性能,不过要出差一段时间不能学习了,所以决定先把DEMO发出来,等回头再来填坑。。。。。
整个程序如果不看注释,只看代码,应该大概是400行吧,运行时图如下,
主要说一下显示区,方块系统,和碰撞检测的思路吧,其他的都比较简单了。
显示区,通过维护四个列表,分别记录正在下落方块和已经落地方块的坐标和颜色,之后在把方块画出来。这里的坐标不是方块在窗口显示位置的坐标,而是列表内的‘相对坐标’,其实就是索引值。
什么是列表内的‘相对坐标’呢,这个得先说一下这个列表是什么鬼。
因为我的显示区,是一个以20像素的方块为单位,一共宽10个方块,高22个方块的区域,所以我的想法是,建立一个12*26的列表来与之对应(为什么是12*26呢,一开始我确实是做了一个10*22的列表,不过后来为了加入边界,把列表加到了12*23,再后来为了让方块从屏幕外一格一格进入显示区,就变成了12*26,这些后面再说。。。),在这个12*26的列表里面,0表示没有方块,1表示左右边界和下边界,然后当方块进入显示区以后,0变成1,表示此处有方块,而刚才所说的相对坐标,其实就是这个列表的索引值了。
这样我们有了相对坐标系,不过还不能用它来画方块,因为pygame画方块需要窗口坐标,所以我还要把相对坐标转换成屏幕坐标,比较简单,就是坐标系换算,一道数学题而已。
然后方块系统,我的方块系统只包括了上下左右四个操作,分别对应了旋转,向下移动一格,向左移动一格,向右移动一格,我把他们做成一个类的四个方法,其中左右下三个操作很简单,坐标加1减1就可以了,就是上操作,旋转,比较麻烦,没想到好办法,我只能将7个方块的所有状态一一编号,然后把旋转时坐标的相对变化全都写出来,累。。。。。中间还加上了贴墙位移,是为了防止旋转以后方块进到墙里面去,或者因为与墙面发生碰撞检测而导致不能旋转的情况。
算旋转时坐标变化的草图如下(要注意转一圈以后能转回初始位置,不然一直转的话,方块会产生位移)
再然后是碰撞检测,原理就是先记录动作前的坐标,然后执行动作,判断动作后的坐标,与墙面,与已经落地方块的坐标,是否重合。因为碰撞检测在每一次动作的时候都要执行一次,所以在实现的时候,我把它做成了一个装饰器,装饰在方块类上。(为了做这个装饰器,现学的如何对类进行装饰。。。。。)
其他的还有一个自己做的用来完成坐标运算的类,非常简陋,因为只是为了一次使用做的,所以只有一个加法运算,而且没有优化。这个类是参考了目光博客pygame教程里面向量运算的类做的。
剩下的就是逻辑了,本来以为写逻辑很简单的,没想到写逻辑写到一度怀疑自己没有逻辑。。。。尤其是,一直想做的按住左键就能一直向左移动的功能,感觉应该可以靠逻辑实现,不过到目前还没想出来。
总结写俄罗斯方块这一段时间的学习,对类有了新的认识,之前觉得类主要就是为了继承而存在的,不过这次虽然也写了类,却没用到继承,反而发现类的属性简直太好用了!!!
对于俄罗斯方块这个程序来说,感觉最难的是一开始,构想如何把方块画出来,这里还要考虑方块旋转,还要考虑以后消除行的时候能不能操作,还要考虑碰撞检测。最开始没有决定用列表和坐标解决这个问题的时候,还考虑过用精灵表示一个方块,不过方块是不规则的,不知道如何来做碰撞检测,上网去搜,在网上看见小甲鱼有一个飞机大战里面讲到对透明部分进行处理,然后完成不规则的碰撞检测,不过没有搞懂,去研究官方文档也没搞懂,还有什么掩码什么的,也是搞得我晕头转向,所以不得不暂时放弃了使用精灵的打算,看来想入门游戏要学的还有太多,手动哭一个吧。。。。
最后附上代码,和代码下载地址,欢迎讨论,欢迎指导,一起成长,手动笑。
下载地址,http://download.csdn.net/detail/highmiao_19/9868601
代码如下:
#俄罗斯方块 # -*- coding: utf-8 -*- import pygame, random, time from pygame.locals import * pygame.init() #pygame.key.set_repeat(1, 100) #重复输入模式 #窗口 screen = pygame.display.set_mode((660,520), 0, 32) #静态界面(背景、色块等) interface = pygame.image.load(r'C:\Users\Administrator\Desktop\interface.jpg').convert() gameover = pygame.image.load(r'C:\Users\Administrator\Desktop\GAME_OVER.jpg').convert() #方块名称、颜色、初始位置 squares_dict = {0:'z_left', 1:'z_right', 2:'long', 3:'cross', 4:'rect', 5:'l_left', 6:'l_right'} '''color_dict用于实例化的时候生成颜色标记''' color_dict = {'z_left':1, 'z_right':2, 'long':3, 'cross':4, 'rect':5, 'l_left':6, 'l_right':7} '''color_sheet用于表示颜色标记对应的颜色RGB''' color_sheet = {1:(231,63,136), 2:(192,219,64), 3:(168,201,206), 4:(143,111,161), 5:(254,252,66), 6:(59,140,170), 7:(249,159,15)} init_pos_dict = {'z_left':[(4,1), (5,1), (5,2), (6,2)], 'z_right':[(7,1), (6,1), (6,2), (5,2)], 'long':[(4,2), (5,2), (6,2), (7,2)], 'cross':[(5,1), (6,1), (7,1), (6,2)], 'rect':[(5,1), (6,1), (5,2), (6,2)], 'l_left':[(4,1), (5,1), (6,1), (6,2)], 'l_right':[(7,1), (6,1), (5,1), (5,2)]} #碰撞检测系统(装饰器,对squares类内的方法进行装饰) def pp_test(cls): class new_class: def __init__(self, name, color, now_pos, flag, stop_flag): self.wrapper = cls(name, color, now_pos, flag, stop_flag) self.name = self.wrapper.name self.color = self.wrapper.color self.now_pos = self.wrapper.now_pos self.flag = self.wrapper.flag self.stop_flag = self.wrapper.stop_flag def TURN(self): temp = self.wrapper.now_pos temp1 = self.wrapper.flag self.wrapper.TURN() for i in self.wrapper.now_pos: if area[i[1]][i[0]] == 1: self.wrapper.now_pos = temp self.wrapper.flag = temp1 self.now_pos = self.wrapper.now_pos self.flag = self.wrapper.flag def LEFT(self): temp = self.wrapper.now_pos self.wrapper.LEFT() for i in self.wrapper.now_pos: if area[i[1]][i[0]] == 1: self.wrapper.now_pos = temp self.now_pos = self.wrapper.now_pos def RIGHT(self): temp = self.wrapper.now_pos self.wrapper.RIGHT() for i in self.wrapper.now_pos: if area[i[1]][i[0]] == 1: self.wrapper.now_pos = temp self.now_pos = self.wrapper.now_pos def DOWN(self): temp = self.wrapper.now_pos self.wrapper.DOWN() for i in self.wrapper.now_pos: if area[i[1]][i[0]] == 1: self.wrapper.now_pos = temp self.wrapper.stop_flag = 1 self.now_pos = self.wrapper.now_pos self.stop_flag = self.wrapper.stop_flag return new_class #方块系统 @pp_test #碰撞检测装饰器 class squares: def __init__(self, name, color, now_pos, flag, stop_flag): self.name = name self.color = color self.now_pos = now_pos self.flag = flag self.stop_flag = stop_flag #方块的旋转操作 def TURN(self): global now_pos now_pos = self.now_pos #z_left的两种状态 if self.name == 'z_left': if self.flag == 0: now_pos[0] = Pos(self.now_pos[0]) + (2,-1) now_pos[1] = Pos(self.now_pos[1]) + (1,0) now_pos[2] = Pos(self.now_pos[2]) + (0,-1) now_pos[3] = Pos(self.now_pos[3]) + (-1,0) self.flag += 1 elif self.flag == 1: if now_pos[2][0] == 1: #贴墙位移 now_pos = Pos(self.now_pos) + (1,0) self.now_pos = now_pos now_pos[0] = Pos(self.now_pos[0]) + (-2,1) now_pos[1] = Pos(self.now_pos[1]) + (-1,0) now_pos[2] = Pos(self.now_pos[2]) + da2d (0,1) now_pos[3] = Pos(self.now_pos[3]) + (1,0) self.flag -= 1 #z_right的两种状态 elif self.name == 'z_right': if self.flag == 0: now_pos[0] = Pos(self.now_pos[0]) + (-2,-1) now_pos[1] = Pos(self.now_pos[1]) + (-1,0) now_pos[2] = Pos(self.now_pos[2]) + (0,-1) now_pos[3] = Pos(self.now_pos[3]) + (1,0) self.flag += 1 elif self.flag == 1: if now_pos[2][0] == 10: #贴墙位移 now_pos = Pos(self.now_pos) + (-1,0) self.now_pos = now_pos now_pos[0] = Pos(self.now_pos[0]) + (2,1) now_pos[1] = Pos(self.now_pos[1]) + (1,0) now_pos[2] = Pos(self.now_pos[2]) + (0,1) now_pos[3] = Pos(self.now_pos[3]) + (-1,0) self.flag -= 1 #long的两种状态 elif self.name == 'long': if self.flag == 0: now_pos[0] = Pos(self.now_pos[0]) + (2,-2) now_pos[1] = Pos(self.now_pos[1]) + (1,-1) now_pos[2] = Pos(self.now_pos[2]) + (0,0) now_pos[3] = Pos(self.now_pos[3]) + (-1,1) self.flag += 1 elif self.flag == 1: if now_pos[2][0] == 1: #贴墙位移 now_pos = Pos(self.now_pos) + (2,0) self.now_pos = now_pos elif now_pos[2][0] == 2: #贴墙位移 now_pos = Pos(self.now_pos) + (1,0) self.now_pos = now_pos elif now_pos[2][0] == 10: #贴墙位移 now_pos = Pos(self.now_pos) + (-1,0) self.now_pos = now_pos now_pos[0] = Pos(self.now_pos[0]) + (-2,2) now_pos[1] = Pos(self.now_pos[1]) + (-1,1) now_pos[2] = Pos(self.now_pos[2]) + (0,0) now_pos[3] = Pos(self.now_pos[3]) + (1,-1) self.flag -= 1 #cross的四种状态 elif self.name == 'cross': if self.flag == 0: now_pos[0] = Pos(self.now_pos[0]) + (1,-1) now_pos[1] = Pos(self.now_pos[1]) + (0,0) now_pos[2] = Pos(self.now_pos[2]) + (-1,1) now_pos[3] = Pos(self.now_pos[3]) + (-1,-1) self.flag += 1 elif self.flag == 1: if now_pos[2][0] == 10: #贴墙位移 now_pos = Pos(self.now_pos) + (-1,0) self.now_pos = now_pos now_pos[0] = Pos(self.now_pos[0]) + (1,1) now_pos[1] = Pos(self.now_pos[1]) + (0,0) now_pos[2] = Pos(self.now_pos[2]) + (-1,-1) now_pos[3] = Pos(self.now_pos[3]) + (1,-1) self.flag += 1 elif self.flag == 2: now_pos[0] = Pos(self.now_pos[0]) + (-1,1) now_pos[1] = Pos(self.now_pos[1]) + (0,0) now_pos[2] = Pos(self.now_pos[2]) + (1,-1) now_pos[3] = Pos(self.now_pos[3]) + (1,1) self.flag += 1 elif self.flag == 3: if now_pos[2][0] == 1: #贴墙位移 now_pos = Pos(self.now_pos) + (1,0) self.now_pos = now_pos now_pos[0] = Pos(self.now_pos[0]) + (-1,-1) now_pos[1] = Pos(self.now_pos[1]) + (0,0) now_pos[2] = Pos(self.now_pos[2]) + (1,1) now_pos[3] = Pos(self.now_pos[3]) + (-1,1) self.flag -= 3 #rect无变化 elif self.name == 'rect': pass #l_left的四种状态 elif self.name == 'l_left': if self.flag == 0: now_pos[0] = Pos(self.now_pos[0]) + (2,-1) now_pos[1] = Pos(self.now_pos[1]) + (1,0) now_pos[2] = Pos(self.now_pos[2]) + (0,1) now_pos[3] = Pos(self.now_pos[3]) + (-1,0) self.flag += 1 elif self.flag == 1: if now_pos[2][0] == 10: #贴墙位移 now_pos = Pos(self.now_pos) + (-1,0) self.now_pos = now_pos now_pos[0] = Pos(self.now_pos[0]) + (1,2) now_pos[1] = Pos(self.now_pos[1]) + (0,1) now_pos[2] = Pos(self.now_pos[2]) + (-1,0) now_pos[3] = Pos(self.now_pos[3]) + (0,-1) self.flag += 1 elif self.flag == 2: now_pos[0] = Pos(self.now_pos[0]) + (-2,0) now_pos[1] = Pos(self.now_pos[1]) + (-1,-1) now_pos[2] = Pos(self.now_pos[2]) + (0,-2) now_pos[3] = Pos(self.now_pos[3]) + (1,-1) self.flag += 1 elif self.flag == 3: if now_pos[2][0] == 1: #贴墙位移 now_pos = Pos(self.now_pos) + (1,0) self.now_pos = now_pos now_pos[0] = Pos(self.now_pos[0]) + (-1,-1) now_pos[1] = Pos(self.now_pos[1]) + (0,0) now_pos[2] = Pos(self.now_pos[2]) + (1,1) now_pos[3] = Pos(self.now_pos[3]) + (0,2) self.flag -= 3 #l_right的四种状态 elif self.name == 'l_right': if self.flag == 0: now_pos[0] = Pos(self.now_pos[0]) + (-1,1) now_pos[1] = Pos(self.now_pos[1]) + (0,0) now_pos[2] = Pos(self.now_pos[2]) + (1,-1) now_pos[3] = Pos(self.now_pos[3]) + (0,-2) self.flag += 1 elif self.flag == 1: if now_pos[3][0] == 1: #贴墙位移 now_pos = Pos(self.now_pos) + (1,0) self.now_pos = now_pos now_pos[0] = Pos(self.now_pos[0]) + (-2,0) now_pos[1] = Pos(self.now_pos[1]) + (-1,1) now_pos[2] = Pos(self.now_pos[2]) + (0,2) now_pos[3] = Pos(self.now_pos[3]) + (1,1) self.flag += 1 elif self.flag == 2: now_pos[0] = Pos(self.now_pos[0]) + (1,-2) now_pos[1] = Pos(self.now_pos[1]) + (0,-1) now_pos[2] = Pos(self.now_pos[2]) + (-1,0) now_pos[3] = Pos(self.now_pos[3]) + (0,1) self.flag += 1 elif self.flag == 3: if now_pos[2][0] == 1: #贴墙位移 now_pos = Pos(self.now_pos) + (1,0) self.now_pos = now_pos now_pos[0] = Pos(self.now_pos[0]) + (1,1) now_pos[1] = Pos(self.now_pos[1]) + (0,0) now_pos[2] = Pos(self.now_pos[2]) + (-1,-1) now_pos[3] = Pos(self.now_pos[3]) + (-2,0) self.flag -= 3 self.now_pos = now_pos #方块的向左操作 def LEFT(self): now_pos = Pos(self.now_pos) + (-1, 0) self.now_pos = now_pos #方块的向右操作 def RIGHT(self): now_pos = Pos(self.now_pos) + (1, 0) self.now_pos = now_pos #方块的下降操作 def DOWN(self): now_pos = Pos(self.now_pos) + (0, 1) self.now_pos = now_pos #虚拟寄存坐标系(对应游戏显示区,边界和有方块的坐标,在area中值为1,无方块为0)坐标转换,返回方块在窗口内的实际位置 area = [] for i in range(25): area.append([1,0,0,0,0,0,0,0,0,0,0,1]) area.append([1,1,1,1,1,1,1,1,1,1,1,1]) '''建立12*26的虚拟坐标系(其中头三行用于存放顶部越界的方块,然后左右下有一圈1,代表边界,此坐标系只存放已经stop的方块)''' def stop_pos_to_area(obj): for i in obj.now_pos: area[i[1]][i[0]] = 1 #方块虚拟坐标系横轴x,纵轴y,存入列表的话,xy需要互换 '''将方块stop时的位置写进area''' def now_pos_to_temp_area(obj): global temp_area temp_area = [] for i in range(25): temp_area.append([1,0,0,0,0,0,0,0,0,0,0,1]) temp_area.append([1,1,1,1,1,1,1,1,1,1,1,1]) for i in obj.now_pos: temp_area[i[1]][i[0]] = 1 '''将移动中方块的动态位置写进temp_area''' #颜色标记系统 '''绘制方块的时候发现没法上颜色,无奈,只能在开一个标记颜色的坐标系''' stop_color = [] for i in range(25): stop_color.append([1,0,0,0,0,0,0,0,0,0,0,1]) stop_color.append([1,1,1,1,1,1,1,1,1,1,1,1]) '''建立12*26的虚拟坐标系(其中头三行用于存放顶部越界的方块,然后左右下有一圈1,代表边界,此坐标系只存放已经stop的方块)''' def color_to_stop_color(obj): for i in obj.now_pos: stop_color[i[1]][i[0]] = obj.color #方块虚拟坐标系横轴x,纵轴y,存入列表的话,xy需要互换 '''将方块stop时的颜色写进stop_color''' def color_to_temp_color(obj): global temp_color temp_color = [] for i in range(25): temp_color.append([1,0,0,0,0,0,0,0,0,0,0,1]) temp_color.append([1,1,1,1,1,1,1,1,1,1,1,1]) for i in obj.now_pos: temp_color[i[1]][i[0]] = obj.color '''将移动中方块的颜色写进temp_color''' #将颜色和位置(方块的状态)存进rect_box def area_to_rect_box(): rect_box = [] c1 = -1 for i in area: c1 += 1 c2 = -1 for j in i: c2 += 1 if j == 1 and c1 > 2 and c2 != 0 and c2 != 11 and c1 != 25: #c1 > 2才开始计入rect_box,头三行不需要画 rect_box.append( (stop_color[c1][c2], (20*(c2-1)+40, 20*(c1-3)+40, 20, 20)) ) c3 = -1 for k in temp_area: c3 += 1 c4 = -1 for l in k: c4 += 1 if l == 1 and c3 > 2 and c4 != 0 and c4 != 11 and c3 != 25: rect_box.append( (temp_color[c3][c4], (20*(c4-1)+40, 20*(c3-3)+40, 20, 20)) ) return rect_box '''将area中值为1的坐标(边界除外),转换为实际坐标,并生成rect格式,存入rect_box中''' #消除系统 def remove(): v = -1 for i in area: v += 1 result = 0 for j in i: result += j if result == 12 and v != 25: del area[v] area.insert(0,[1,0,0,0,0,0,0,0,0,0,0,1]) del stop_color[v] stop_color.insert(0,[1,0,0,0,0,0,0,0,0,0,0,1]) global score score += 1 level_just() #game over系统 def game_over(): result = 0 for i in area[2]: result += i if result > 2: global game_over game_over = 1 #方块位置运算系统,用于运算方块的position class Pos: def __init__(self, pos): #ob_pos = Pos([(x1, y1), (x2,y2), (x3, y3), (x4, y4)]) self.len = len(pos) self.pos = pos def __add__(self, pair): if type(self.pos[0]) != int: return list((self.pos[i][0] + pair[0], self.pos[i][1] + pair[1]) for i in range(self.len)) else: return list((self.pos[0] + pair[0], self.pos[1] + pair[1])) #音乐系统 #计分系统(挂在消除系统里,每次消除的时候score+1) score = 0 #计时系统 start_time = time.clock() def TIME(): over_time = time.clock() used_time = over_time - start_time global time_sec, time_min, time_hour time_sec = int(used_time % 60) time_min = int((used_time // 60) % 60) time_hour = int((used_time // 60) // 60) #等级系统(挂在消除系统里,每次消除后,计分,判断等级,不同等级速度不同) level_list = [511, 255, 127, 63, 31] level = level_list[0] def level_just(): global level if score < 10: level = level_list[0] elif score < 20: level = level_list[1] elif score < 30: level = level_list[2] elif score < 40: level = level_list[3] elif score < 50: level = level_list[4] #下一个方块预览图 surface_z_left = pygame.image.load(r'C:\Users\Administrator\Desktop\surface_z_left.png').convert_alpha() surface_z_right = pygame.image.load(r'C:\Users\Administrator\Desktop\surface_z_right.png').convert_alpha() surface_long = pygame.image.load(r'C:\Users\Administrator\Desktop\surface_long.png').convert_alpha() surface_cross = pygame.image.load(r'C:\Users\Administrator\Desktop\surface_cross.png').convert_alpha() surface_rect = pygame.image.load(r'C:\Users\Administrator\Desktop\surface_rect.png').convert_alpha() surface_l_left = pygame.image.load(r'C:\Users\Administrator\Desktop\surface_l_left.png').convert_alpha() surface_l_right = pygame.image.load(r'C:\Users\Administrator\Desktop\surface_l_right.png').convert_alpha() next_square = {'z_left':surface_z_left, 'z_right':surface_z_right, 'long':surface_long, 'cross':surface_cross, 'rect':surface_rect, 'l_left':surface_l_left, 'l_right':surface_l_right} #动态文字、图形(右侧菜单显示的分数、时间、等级、下一个) score_font = pygame.font.SysFont('tahoma.ttf', 40) level_font = pygame.font.SysFont('tahoma.ttf', 40) time_font = pygame.font.SysFont('tahoma.ttf', 40) #画出 def draw(obj, next_name): now_pos_to_temp_area(obj) color_to_temp_color(obj) #画界面、文字、按钮 screen.blit(interface,(0, 0)) score_surface = score_font.render('{0}'.format(score), True, (0, 0, 0)) #因为分数是动态的,所以每次画之前刷新一遍surface screen.blit(score_surface,(300, 100)) TIME() time_surface = time_font.render('{0:0>2}:{1:0>2}:{2:0>2}'.format(time_hour, time_min, time_sec), True, (0, 0, 0)) screen.blit(time_surface,(480, 100)) level_surface = level_font.render('{0}'.format(level_list.index(level)), True, (0, 0, 0)) #因为等级是动态的,所以每次画之前刷新一遍surface screen.blit(level_surface,(480,340)) screen.blit(next_square[next_name],(280, 330)) new_rect_box = area_to_rect_box() for i in new_rect_box: pygame.draw.rect(screen, color_sheet[i[0]], i[1], 0) pygame.display.update() #初始化第一个方块 next_name = squares_dict[random.randint(0,6)] def main(): while True : global next_name this_name = next_name next_name = squares_dict[random.randint(0,6)] dynamic_square = squares(this_name, color_dict[this_name], init_pos_dict[this_name], flag = 0, stop_flag = 0) draw(dynamic_square, next_name) while True : for event in pygame.event.get(): if event.type == QUIT: exit() if event.type == KEYDOWN: if event.key == K_LEFT: dynamic_square.LEFT() draw(dynamic_square, next_name) elif event.key == K_RIGHT: dynamic_square.RIGHT() draw(dynamic_square, next_name) elif event.key == K_UP: dynamic_square.TURN() draw(dynamic_square, next_name) elif event.key == K_DOWN: dynamic_square.DOWN() draw(dynamic_square, next_name) while int(pygame.time.get_ticks()) & level == 1: #每当时间循环到1的时候就下降一格 dynamic_square.DOWN() draw(dynamic_square, next_name) break if dynamic_square.stop_flag == 1: #如果stop_flag = 1,则方块落地,记录位置和颜色,判断是否需要消除,或者GAME OVER,然后跳过本次循环,开始下一方块 stop_pos_to_area(dynamic_square) color_to_stop_color(dynamic_square) remove() game_over() break if game_over == 1: break screen.blit(gameover,(0,0)) pygame.display.update() if __name__ == '__main__': main() '''碰撞检测在TURN时会失效_____bug l_left在turn时出现bug_____bug(2次了,原因尚不明确) 刚开始的下降不稳定,有时候会一次下降两格_____bug 持续按键还未实现_____func 还没有暂停功能_____func 消除的动画还没有加_____cool 画面贴图还没做_____cool 音乐还没有加_____cool 最高分功能还没有____func 开始界面_____func'''
相关文章推荐
- [VB.NET源码]俄罗斯方块游戏实例(点对点)
- 游戏发布:俄罗斯方块MFC版源码
- 一份精辟的俄罗斯方块源码(335行)
- 俄罗斯方块源码
- C语言之俄罗斯方块游戏源码
- [转载]俄罗斯方块AI源码!
- (难度:40%)纯js的俄罗斯方块游戏(含源码)
- 发布一个Java写的俄罗斯方块源码 算法简单(300行) 注释详细
- 俄罗斯方块源码
- 俄罗斯方块源码
- 【Python】用Python实现一个俄罗斯方块游戏
- (转)发布一个Java写的俄罗斯方块源码 算法简单(300行) 注释详细
- 发布一个Java写的俄罗斯方块源码 算法简单(300行) 注释详细
- Windows API 俄罗斯方块源码 -- 俄罗斯方块.cpp
- 俄罗斯方块源码解析(带下载)[1]
- 一个俄罗斯方块的源码(原创)
- 【技术收藏】enpaodelvzi编写:一个Java写的俄罗斯方块源码 算法简单(300行) 注释详细
- 俄罗斯方块源码解析(带下载)[3]
- windows phone7 项目一俄罗斯方块源码 及说明
- Android俄罗斯方块游戏源码