版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
+硬件趣学Python编程
做一个融入集体的方块,俄罗斯方块的游戏制作牛艾科技目录ContentsSuccessWords2第二部分对象的封装第三部分继承和多态第四部分游戏基本设计思路第五部分俄罗斯方块的代码分析第一部分面向对象目录ContentsSuccessWords3第一部分面向对象4面向对象面相过程和面相对象基本概念
面相过程——怎么做?把完成某一个需求的所有步骤从头到尾逐步实现根据开发需求,将某些功能独立的代码封装成一个又一个函数最后完成的代码,就是顺序地调用不同的函数
特点:注重步骤与过程,不注重职责分工如果需求复杂,代码会变得很复杂开发复杂项目,没有固定的套路,开发难度很大!5面向对象面向对象——谁来做?
相比较函数,面向对象是更大的封装,根据职责在一个对象中封装多个方法在完成某一个需求前,首先确定职责——要做的事情(方法)根据职责确定不同的对象,在对象内部封装不同的方法(多个)最后完成的代码,就是顺序地让不同的对象调用不同的方法特点:注重对象和职责,不同的对象承担不同的职责更加适合应对复杂的需求变化,是专门应对复杂项目开发,提供的固定套路需要在面向过程基础上,再学习一些面向对象的语法6面向对象类
类是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用特征被称为属性行为被称为方法类:就相当于制造飞机时的图纸,是一个模板,是负责创建对象的7面向对象对象
对象是由类创建出来的一个具体存在,可以直接使用由哪一个类创建出来的对象,就拥有在哪一个类中定义的:属性、方法对象就相当于用图纸制造的飞机在程序开发中,应该先有类,再有对象目录ContentsSuccessWords8第二部分对象的封装对象的封装内置函数序号方法名类型作用01__new__方法创建对象时,会被自动调用02__init__方法对象被初始化时,会被自动调用03__del__方法对象被从内存中销毁前,会被自动调用04__str__方法返回对象的描述信息,print函数输出使用10对象的封装定义只包含方法的类方法的定义格式和之前学习过的函数几乎一样区别在于第一个参数必须是self,大家暂时先记住,稍后介绍self注意:类名的命名规则要符合大驼峰命名法class类名:def方法1(self,参数列表):pass
def方法2(self,参数列表):pass11对象的封装创建对象对象变量=类名()第一个面向对象程序需求小猫爱吃鱼,小猫要喝水分析
定义一个猫类Cat定义两个方法eat和drink按照需求——不需要定义属性classCat:"""这是一个猫类"""defeat(self):print("小猫爱吃鱼")defdrink(self):print("小猫在喝水")tom=Cat()tom.drink()tom.eat()12对象的封装对象的属性在Python中,要给对象设置属性,非常的容易,但是不推荐使用因为:对象属性的封装应该封装在类的内部只需要在类的外部的代码中直接通过.设置一个属性即可注意:这种方式虽然简单,但是不推荐使用!="Tom"...lazy_="大懒猫"13对象的封装方法中的self参数由哪一个对象调用的方法,方法内的self就是哪一个对象的引用在类封装的方法内部,self就表示当前调用方法的对象自己调用方法时,程序员不需要传递self参数在方法内部可以通过self.访问对象的属性也可以通过self.调用其他的对象方法改造代码如下:
classCat:defeat(self):print("%s爱吃鱼"%)tom=Cat()="Tom"tom.eat()lazy_cat=Cat()lazy_="大懒猫"lazy_cat.eat()14对象的封装初始化方法
之前代码存在的问题——在类的外部给对象增加属性将案例代码进行调整,先调用方法再设置属性,观察一下执行效果
在日常开发中,不推荐在类的外部给对象增加属性如果在运行时,没有找到属性,程序会报错对象应该包含有哪些属性,应该封装在类的内部
tom=Cat()tom.drink()tom.eat()="Tom"print(tom)AttributeError:'Cat'objecthasnoattribute'name'属性错误:'Cat'对象没有'name'属性15对象的封装初始化方法
当使用类名()创建对象时,会自动执行以下操作:为对象在内存中分配空间——创建对象为对象的属性设置初始值——初始化方法(init)这个初始化方法就是__init__方法,__init__是对象的内置方法__init__方法是专门用来定义一个类具有哪些属性的方法!
classCat:"""这是一个猫类"""def__init__(self):print("初始化方法")16对象的封装初始化方法
在初始化方法内部定义属性在__init__方法内部使用self.属性名=属性的初始值就可以定义属性定义属性之后,再使用Cat类创建的对象,都会拥有该属性
classCat:def__init__(self):print("这是一个初始化方法")#定义用Cat类创建的猫对象都有一个name的属性="Tom"defeat(self):print("%s爱吃鱼"%)#使用类名()创建对象的时候,会自动调用初始化方法__init__tom=Cat()tom.eat()17对象的封装初始化方法
改造初始化方法——初始化的同时设置初始值在开发中,如果希望在创建对象的同时,就设置对象的属性,可以对__init__方法进行改造把希望设置的属性值,定义成__init__方法的参数在方法内部使用self.属性=形参接收外部传递的参数在创建对象时,使用类名(属性1,属性2...)调用
classCat:def__init__(self,name):print("初始化方法%s"%name)=name...tom=Cat("Tom")...lazy_cat=Cat("大懒猫")...目录ContentsSuccessWords18第三部分继承和多态19继承面向对象三大特性封装根据职责将属性和方法封装到一个抽象的类中继承实现代码的重用,相同的代码不需要重复的编写多态不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活度
20继承继承的概念、语法和特点
继承的概念:子类拥有父类的所有方法和属性21继承继承的语法class类名(父类名):
pass子类继承自父类,可以直接享受父类中已经封装好的方法,不需要再次开发子类中应该根据职责,封装子类特有的属性和方法例子:Dog类是Animal类的子类,Animal类是Dog类的父类,Dog类从Animal类继承Dog类是Animal类的派生类,Animal类是Dog类的基类,Dog类从Animal类派生22继承继承的传递性C类从B类继承,B类又从A类继承那么C类就具有B类和A类的所有属性和方法子类拥有父类以及父类的父类中封装的所有属性和方法提问哮天犬能够调用Cat类中定义的catch方法吗?答案不能,因为哮天犬和Cat之间没有继承关系23继承方法的重写子类拥有父类的所有方法和属性子类继承自父类,可以直接享受父类中已经封装好的方法,不需要再次开发当父类的方法实现不能满足子类需求时,可以对方法进行重写(override)24继承重写父类方法有两种情况:
1)覆盖父类的方法2)对父类方法进行扩展如果在开发中,父类的方法实现和子类的方法实现,完全不同就可以使用覆盖的方式,在子类中重新编写父类的方法实现具体的实现方式,就相当于在子类中定义了一个和父类同名的方法并且实现重写之后,在运行时,只会调用子类中重写的方法,而不再会调用父类封装的方法如果在开发中,子类的方法实现中包含父类的方法实现父类原本封装的方法实现是子类方法的一部分就可以使用扩展的方式在子类中重写父类的方法在需要的位置使用super().父类方法来调用父类方法的执行代码其他的位置针对子类的需求,编写子类特有的代码实现25多态多态是指不同的子类对象调用相同的父类方法,产生不同的执行结果,也就是定义时的类型和运行时的类型不一样,此时就称为多态,多态可以增加代码的灵活度,多态以继承和重写父类方法为前提,是调用方法的技巧,不会影响到类的内部设计。Python崇尚“鸭子类型”,“鸭子类型”可以这样表述:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子”,也就是关注的不是对象的类型本身,而是它是如何使用的。26多态多态更容易编写出出通用的代码,做出通用的编程,以适应需求的不断变化!目录ContentsSuccessWords27第四部分游戏基本设计思路28游戏基本设计思路画背景棋盘
俄罗斯方块屏幕有两个区域,一个是游戏区域,一个是方块预览区域。游戏区域用于下落方块进行堆积。预览区域用于显示下一个要下落的方块类型。
29游戏基本设计思路将界面拆分成若干个的网格每个格是10*10的大小将预览窗口也同样拆分成网格游戏就是控制在不同的时机渲染不同的网格30游戏基本设计思路消除机制:
当某行没有空的方块时,会消除这行,同时对这行以上的所有行进行移动,向下移动一行。失败条件
当第0行不为空时,则游戏结束目录ContentsSuccessWords31第五部分俄罗斯方块代码分析32俄罗斯方块的代码分析画背景网格
主要使用方法:
1、画直线screen.drawline(x1,y1,x2,y2,pensize,pencolor)
#x1:起点横坐标,y1:起点纵坐标,
#x2:终点横坐标,y2:终点纵坐标,
#pensize:画笔宽度,pencolor:画笔颜色
2、输出文本
text.draw(str,x,y,textColor,bgColor)
#str:文本,x:左上角顶点横坐标,y:左上角顶点纵坐标,#textColor:前景颜色,bgColor:背景颜色33俄罗斯方块的代码分析画背景网格classGrid(object):def__init__(self,master=None,x=10,y=10,w=193,h=303):self.x=xself.y=yself.w=wself.h=hself.rows=h//10self.cols=w//10self.bg=0x000000;print(self.rows,self.cols)
#画背景foriinrange(320):screen.drawline(0,i,239,i,1,self.bg);
#画边界screen.drawline(x,y,x+w-1,y,1,0xFFFFFF);screen.drawline(x+w-1,y,x+w-1,y+h,1,0xFFFFFF);screen.drawline(x,y+h,x+w-1,y+h,1,0xFFFFFF);screen.drawline(x,y,x,y+h,1,0xFFFFFF);初始化参数渲染背景颜色画左侧区域的边框34俄罗斯方块的代码分析画背景网格#画提示框边界screen.drawline(204,10,204+32-1,10,1,0xFFFFFF);screen.drawline(204+32-1,10,204+32-1,10+32,1,0xFFFFFF);screen.drawline(204,10+32,204+32-1,10+32,1,0xFFFFFF);screen.drawline(204,10,204,10+32,1,0xFFFFFF);
defdrawgrid(self,pos,color):x=pos[1]*10+self.x+2y=pos[0]*10+self.y+2foriinrange(9):screen.drawline(x,y+i,x+9-1,y+i,1,color);
defdrawpre(self,pos,color):x=pos[1]*10+204+2y=pos[0]*10+10+2foriinrange(9):screen.drawline(x,y+i,x+9-1,y+i,1,color);渲染网格画右侧区域的边框将网格坐标转换为实际坐标画预览区域的网格35俄罗斯方块的代码分析方块种类brick=[[[[1,1,1],[0,0,1],[0,0,0]],[[0,0,1],[0,0,1],[0,1,1]],[[0,0,0],[1,0,0],[1,1,1]],[[1,1,0],[1,0,0],[1,0,0]]],用嵌套列表,声明可用的方块的数据[[[0,0,0],[0,1,1],[0,1,1]],[[0,0,0],[0,1,1],[0,1,1]],[[0,0,0],[0,1,1],[0,1,1]],[[0,0,0],[0,1,1],[0,1,1]]],[
[[1,1,1],[0,1,0],[0,1,0]],[[0,0,1],[1,1,1],[0,0,1]],[[0,1,0],[0,1,0],[1,1,1]],[[1,0,0],[1,1,1],[1,0,0]]]]36俄罗斯方块的代码分析游戏类classGame(Grid):def__init__(self):super().__init__()self.back=[[0foriinrange(0,self.cols)]foriinrange(0,self.rows)]self.curRow=-10self.curCol=-10self.start=Trueself.shape=-1self.isDown=Trueself.oldrow=0self.oldcol=0self.haverow=29self.nextBrick=-1self.shape=0self.arr=[[0foriinrange(0,3)]foriinrange(0,3)]self.nextarr=[[0foriinrange(0,3)]foriinrange(0,3)]self.color={0:0x0000FF,1:0x00FF00,2:0xFF0000,3:0xFFFF00}初始化一个二维数组,用于保存屏幕上的网格数据,1表示这个网格需要被渲染,0表示不需要继承自Grid类,可以使用之前的渲染网格的方法储存当前的方块储存预览的方块用字典保存颜色37俄罗斯方块的代码分析绘制当前的下落方块defdrawRect(self):foriinrange(0,len(self.nextarr)):forjinrange(0,len(self.nextarr[i])):pos=(i,j)ifself.nextarr[i][j]==0:self.drawpre(pos,self.bg);elifself.nextarr[i][j]==1:self.drawpre(pos,self.color[self.nextBrick])foriinrange(0,3):forjinrange(0,3):ifself.oldrow+i>=self.rows)orself.oldcol+j>=self.colsorself.oldcol+j<-1:breakifself.oldcol+j<0:pos=(self.oldrow+i,0)else:pos=(self.oldrow+i,self.oldcol+j)ifself.back[self.oldrow+i][self.oldcol+j]==0:self.drawgrid(pos,self.bg);绘制预览区域的方块,双重循环遍历self.nextarr数组,调用父类的drawpre方法进行渲染渲染渲染下一个要显示的方块前,先将当前的位置渲染成背景颜色判断是否已经到达边界调用父类渲染成背景颜色38俄罗斯方块的代码分析绘制当前的下落方块if(self.curRow!=-10)and(self.curCol!=-10):foriinrange(0,len(self.arr)):forjinrange(0,len(self.arr[i])):ifself.arr[i][j]==1:pos=(self.curRow+i,self.curCol+j)ifself.isDown:ifi<self.haverow:self.haverow=iself.drawgrid(pos,0x00FFFF)else:self.drawgrid(pos,self.color[self.curBrick])ifself.isDown:foriinrange(0,3):forjinrange(0,3):ifself.arr[i][j]!=0:self.back[self.curRow+i][self.curCol+j]=self.arr[i][j]self.oldrow=0self.oldcol=0self.removeRow()self.isDead()self.getCurBrick()else:self.oldrow=self.curRowself.oldcol=self.curCol绘制当前正在下落的方块,循环遍历arr数组,根据arr中的数据进行渲染如果方块已经到底则改变方块的颜色为蓝色调用父类方法渲染当前方块方块到底之后,更新back数组,back数组中存放当前所有固定的方块的位置调用removeRow进行消除判断调用isDead判断游戏失败条件取下一个方块的数据更新当前行和列的值39俄罗斯方块的代码分析行的消除defremoveRow(self):rownum=0foriinrange(0,self.rows):tag1=Trueforjinrange(0,self.cols):ifself.back[i][j]==0:tag1=Falsebreakiftag1==True:print(i,j)rownum=iforminrange(i-1,0,-1):forninrange(0,self.cols):self.back[m+1][n]=self.back[m][n]ifrownum>0:self.drawBack(rownum)行的消除判断函数可以消除则,从当前行向上到0行开始循环,将方块向下移动从0行0列开始循环发现有为空的网格,则说明本行没有被填满,不能消除直接break可能存在同时消除多行的情况,处理完back数组之后调drawBack进行渲染40俄罗斯方块的代码分析已固定的方块的渲染defdrawBack(self,rownum):foriinrange(self.haverow,rownum+1):forjinrange(0,self.cols):pos=(i,j)ifself.back[i][j]==0:self.drawgrid(pos,self.bg)else:self.drawgrid(pos,0x00FFFF)self.haverow+=1ifself.haverow>=self.rows:self.haverow=self.rows-1循环遍历所有已有的固定行根据back数组,如果为0则渲染背景色,为1则渲染蓝色defgetCurBrick(self):self.shape=0ifself.nextBrick==-1:self.curBrick=randint(0,len(brick)-1)self.nextBrick=randint(0,len(brick)-1)elifself.isDown:self.curBrick=self.nextBrickself.nextBrick=randint(0,len(brick)-1)self.nextarr=brick[self.nextBrick][self.shape]self.arr=brick[self.curBrick][self.shape]self.curRow=-1self.curCol=8self.isDown=False第一次调用时,同时随机产生当前的方块和预览方块当前方块已经落到底之后,则用预览方块替换当前方块,并随机产生新的预览方块更新nextarr和arr两个数组的数据41俄罗斯方块的代码分析按键控制defonKeyboardEvent(self,key):keymatch=["Down","Left","Up","Right"]ifself.start==False:returntempCurCol=self.curColtempCurRow=self.curRowtempShape=self.shapetempArr=self.arrdirection=-1ifkeymatch[key]=="Left":self.curCol-=1direction=1elifkeymatch[key]=="Up":self.shape+=1direction=2ifself.shape>=4:self.shape=0self.arr=brick[self.curBrick][self.shape]elifkeymatch[key]=="Right":direction=3self.curCol+=1elifkeymatch[key]=="Down":direction=4self.curRow+=2ifself.isEdge(direction)==False:self.curCol=tempCurColself.curRow=tempCurRowself.shape=tempShapeself.arr=tempArrreturnTrue将键值对应的列表初始化向左,则更改当前列-1,方向为1向上,则更改方块形状,shape+1方向还是向下,如果shape已经到4了则变回第一个形状0调用isEdage进行边界判断,如果到达边界则恢复原始位置defisEdge(self,direction):tag=Trueifdirection==1:foriinrange(0,3):forjinrange(0,3):if(self.arr[j][i]!=0)and(self.curCol+i<0orself.back[self.curRow+j][self.curCol+i]!=0):tag=Falsebreakelifdirection==3:foriinrange(0,3):forjinrange(0,3):if(self.arr[j][i]!=0)and(self.curCol+i>=self.colsorself.back[self.curRow+j][self.curCol+i]!=0):tag=Falsebreakelifdirection==4:foriinrange(0,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026广西北海市农业农村局招录公益性岗位人员1人考试备考试题及答案解析
- 2026浙江杭州市妇产科医院(杭州市妇幼保健院)上半年高层次、紧缺专业人才招聘15人(总)备考考试题库及答案解析
- 2026南平顺昌县农业农村局招聘动物检疫协检人员1人笔试参考题库及答案解析
- 2026年聊城市技师学院“水城优才”人才引进备考考试试题及答案解析
- 2026内蒙古包头交通投资集团有限公司招聘37人考试备考试题及答案解析
- 2026北京海淀区中法实验学校招聘考试参考题库及答案解析
- 2026德安县消防大队招聘2人备考考试题库及答案解析
- 2026西安巨量星图文化传媒有限公司公司招聘笔试参考题库及答案解析
- 2026年河北衡水市人民医院寒假志愿者招募备考考试试题及答案解析
- 水利工程师-水利工程管理考试模拟题+答案(附解析)
- 华东理工大学2026年管理与其他专业技术岗位统一招聘备考题库含答案详解
- 2026上海碧海金沙投资发展有限公司社会招聘参考题库含答案
- 2026四川成都市金牛区城市管理局招聘编外聘用工作人员2人参考题库必考题
- 输血科质控 年度总结汇报
- 2026年浙江高考语文考试真题
- 2025年贵州省公务员录用考试《公安专业科目》真题
- 高压注浆加固施工方案
- 无人驾驶(从想象到现实)
- 三片罐行业分析
- 道德经和道家智慧课件
- 中国家庭金融调查报告
评论
0/150
提交评论