8、俄罗斯方块
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
17
目 录 Success Words Contents
第三部分 继承和多态
18
继承
• 面向对象三大特性
1. 封装根据职责将属性和方法封装到一个抽象的类中 2. 继承实现代码的重用,相同的代码不需要重复的编写 3. 多态不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活度
19
继承
• 继承的概念、语法和特点
3
面向对象
• 面相过程 和 面相对象 基本概念
面相过程 —— 怎么做? 1. 把完成某一个需求的所有步骤从头到尾逐步实现 2. 根据开发需求,将某些功能独立的代码封装成一个又一个函数 3. 最后完成的代码,就是顺序地调用不同的函数
特点: 1. 注重步骤与过程,不注重职责分工 2. 如果需求复杂,代码会变得很复杂 3. 开发复杂项目,没有固定的套路,开发难度很大!
15
对象的封装
• 初始化方法
在初始化方法内部定义属性
在 __init__ 方法内部使用 self.属性名 = 属性的初始值 就可以 定义属性
定义属性之后,再使用 Cat 类创建的对象,都会拥有该属性
class Cat: def __init__(self): print("这是一个初始化方法") # 定义用 Cat 类创建的猫对象都有一个 name 的属性 self.name = "Tom" def eat(self): print("%s 爱吃鱼" % self.name)
2) 对父类方法进行扩展
如果在开发中,子类的方法实现中包含父类的方法实现父类原本封装的方法实现是子类方法的一部分就可以使用 扩展的方式在子类中 重写父类的方法在需要的位置使用super().父类方法 来调用父类方法的执行代码其他的位置 针对子类的需求,编写子类特有的代码实现
24
多态
• 多态是指不同的子类对象调用相同的父类方法,产生不同的执行结果,也就是 定义时的类型和运行时的类型不一样,此时就称为多态,多态可以增加代码的 灵活度,多态以继承和重写父类方法为前提,是调用方法的技巧,不会影响到 类的内部设计。
AttributeError: 'Cat' object has no
attribute 'name' 属性错误:'Cat' 对象没有 'name' 属性
在日常开发中,不推荐在类的外部给对象增加属性如果在运行时,没有找到属性,程序 会报错对象应该包含有哪些属性,应该封装在类的内部
14
对象的封装
• 初始化方法
传递 self 参数在方法内部可以通过 self. 访问对象的属性也可以通过 self. 调用其他的对象方
法改造代码如下:
class Cat: def eat(self): print("%s 爱吃鱼" % self.name)
tom = Cat() tom.name = "Tom" tom.eat()
收外部传递的参数在创建对象时,使用 类名(属性1, 属性2...) 调用
class Cat: def __init__(self, name): print("初始化方法 %s" % name) self.name = name ...
tom = Cat("Tom") ... lazy_cat = Cat("大懒猫") ...
tom.name = "Tom" ... lazy_cat.name = "大懒猫"
注意:这种方式虽然简单,但是不推荐使用!
12
对象的封装
• 方法中的 self 参数
由哪一个对象调用的方法,方法内的self就是哪一个对象的引用
在类封装的方法内部,self就表示当前调用方法的对象自己调用方法时,程序员不需要
第四部分 游戏基本设计思路
27
游戏基本设计思路
• 画背景棋盘
俄罗斯方块屏幕有两个区域,一个是游戏区域, 一个是方块预览区域。
游戏区域用于下落方块进行堆积。 预览区域用于显示下一个要下落的方块类型。
28
游戏基本设计思路
• 将界面拆分成若干个的网格 • 每个格是10*10的大小 • 将预览窗口也同样拆分成网格 • 游戏就是控制在不同的时机渲染不同的网
10
对象的封装
• 创建对象 对象变量 = 类名()
• 第一个面向对象程序 • 需求
小猫 爱吃鱼,小猫要喝 水 分析
定义一个猫类 Cat 定义两个方法 eat 和 drink 按照需求 —— 不需要定义属性
class Cat: """这是一个猫类"""
def eat(self): print("小猫爱吃鱼")
32
俄罗斯方块的代码分析
• 画背景网格
class Grid(object): def __init__(self, master = None, x = 10, y = 10, w = 193, h = 303): self.x = x self.y = y self.w = w self.h = h self.rows = h//10 self.cols = w//10 self.bg = 0x000000; print(self.rows,self.cols)
• Python崇尚“鸭子类型”,“鸭子类型”可以这样表述:“当看到一只鸟走 起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭 子”,也就是关注的不是对象的类型本身,而是它是如何使用的。
25
多态
• 多态更容易编写出出通用的代码,做出通用的编程,以适应需求的不断变化!
Байду номын сангаас26
目 录 Success Words Contents
格
29
游戏基本设计思路
• 消除机制: 当某行没有空的方块时,会消除这行,同
时对这行以上的所有行进行移动,向下移动一 行。 • 失败条件
当第0行不为空时,则游戏结束
30
目 录 Success Words Contents
第五部分 俄罗斯方块代码分析
31
俄罗斯方块的代码分析
• 画背景网格
主要使用方法: 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:背景颜色
继承的概念:子类拥有父类的所有方法和属性
20
继承
• 继承的语法 class 类名(父类名): pass 子类 继承自父类,可以直接享受父类中已经封装好的方法,不需要再次开发 子类 中应该根据职责,封装子类特有的属性和方法
例子:
Dog 类是 Animal 类的子类,Animal 类是 Dog 类的父类,Dog 类从 Animal 类继承 Dog 类是 Animal 类的派生类,Animal 类是 Dog 类的基类,Dog 类从 Animal 类派生
#画背景 for i in range(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);
def drink(self): print("小猫在喝水")
tom = Cat() tom.drink() tom.eat()
11
对象的封装
• 对象的属性
在 Python 中,要 给对象设置属性,非常的容易,但是不推荐使用 因为:对象属性的封装应该封装在类的内部 只需要在 类的外部的代码 中直接通过 . 设置一个属性即可
5
面向对象
•类
类是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用 特征 被称为 属性 行为 被称为 方法 类:就相当于制造飞机时的图纸, 是一个模板,是负责创建对象的
6
面向对象
• 对象
对象 是由类创建出来的一个具体存在,可以直接使用 由哪一个类创建出来的对象,就拥有在哪一个类中定义的:属性、方法
继承
• 方法的重写 子类拥有父类的所有方法和属性 子类继承自父类,可以直接享受父类中已经
封装好的方法,不需要再次开发 当父类的方法实现不能满足子类需求时,
可以对方法进行重写(override)
23
继承
• 重写父类方法有两种情况:
1) 覆盖父类的方法
如果在开发中,父类的方法实现和子类的方法实现,完全不同就可以使用覆盖的方式,在子类中重新编写父类的 方法实现具体的实现方式,就相当于在子类中定义了一个和父类同名的方法并且实现重写之后,在运行时,只会 调用子类中重写的方法,而不再会调用父类封装的方法
lazy_cat = Cat() lazy_cat.name = "大懒猫" lazy_cat.eat()
13
对象的封装
• 初始化方法
之前代码存在的问题 —— 在类的外部给对象增加属性 将案例代码进行调整,先调用方法再设置属性,观察一下执行效果
tom = Cat() tom.drink() tom.eat() tom.name = "Tom" print(tom)
对象被初始化时,会被自动调用
对象被从内存中销毁前,会被自 动调用 返回对象的描述信息,print 函数 输出使用
对象的封装
• 定义只包含方法的类
class 类名: def 方法1(self, 参数列表): pass def 方法2(self, 参数列表): pass
• 方法 的定义格式和之前学习过的函数几乎一样 • 区别在于第一个参数必须是 self,大家暂时先记住,稍后介绍 self • 注意:类名的命名规则要符合大驼峰命名法
21
继承
• 继承的传递性 C 类从 B 类继承,B 类又从 A 类继承 那么 C 类就具有 B 类和 A 类的所有属性和方法
子类拥有父类以及父类的父类中封装的所有属性和方法
提问 哮天犬 能够调用 Cat 类中定义的 catch 方法吗? 答案 不能,因为 哮天犬 和 Cat 之间没有 继承 关系
22
+
牛艾科技
硬件趣学Python编程 做一个融入集体的方块,俄罗斯方块的游戏制作
目 录 Success Words Contents
第一部分
面向对象
第二部分
对象的封装
第三部分
继承和多态
第四部分 第五部分
游戏基本设计思路 俄罗斯方块的代码分析
2
目 录 Success Words Contents
第一部分 面向对象
4
面向对象
• 面向对象 —— 谁来做?
相比较函数,面向对象是更大的封装,根据职责在一个对象中封装多个方法
1. 在完成某一个需求前,首先确定职责—— 要做的事情(方法) 2. 根据职责确定不同的对象,在对象内部封装不同的方法(多个) 3. 最后完成的代码,就是顺序地让不同的对象调用不同的方法
特点:
1. 注重 对象和职责,不同的对象承担不同的职责 2. 更加适合应对复杂的需求变化,是专门应对复杂项目开发,提供的固定套路 3. 需要在面向过程基础上,再学习一些面向对象的语法
# 使用类名()创建对象的时候,会自动调用初始化方法 __init__ tom = Cat() tom.eat()
16
对象的封装
• 初始化方法
改造初始化方法 —— 初始化的同时设置初始值
在开发中,如果希望在 创建对象的同时,就设置对象的属性,可以对 __init__ 方法进行
改造把希望设置的属性值,定义成 __init__ 方法的参数在方法内部使用 self.属性 = 形参 接
对象 就相当于用图纸制造的飞机在程序开发中,应该 先有类,再有对象
7
目 录 Success Words Contents
第二部分 对象的封装
8
对象的封装
• 内置函数 序号 01 02 03
04
方法名 __new__ __init__ __del__
类型 方法 方法 方法
__str__ 方法
作用
创建对象时,会被自动调用
当使用 类名() 创建对象时,会自动执行以下操作: 为对象在内存中分配空间 —— 创建对象 为对象的属性设置初始值 —— 初始化方法(init) 这个初始化方法就是 __init__ 方法,__init__ 是对象的内置方法 __init__ 方法是 专门 用来定义一个类具有哪些属性的方法!
class Cat: """这是一个猫类""" def __init__(self): print("初始化方法")
目 录 Success Words Contents
第三部分 继承和多态
18
继承
• 面向对象三大特性
1. 封装根据职责将属性和方法封装到一个抽象的类中 2. 继承实现代码的重用,相同的代码不需要重复的编写 3. 多态不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活度
19
继承
• 继承的概念、语法和特点
3
面向对象
• 面相过程 和 面相对象 基本概念
面相过程 —— 怎么做? 1. 把完成某一个需求的所有步骤从头到尾逐步实现 2. 根据开发需求,将某些功能独立的代码封装成一个又一个函数 3. 最后完成的代码,就是顺序地调用不同的函数
特点: 1. 注重步骤与过程,不注重职责分工 2. 如果需求复杂,代码会变得很复杂 3. 开发复杂项目,没有固定的套路,开发难度很大!
15
对象的封装
• 初始化方法
在初始化方法内部定义属性
在 __init__ 方法内部使用 self.属性名 = 属性的初始值 就可以 定义属性
定义属性之后,再使用 Cat 类创建的对象,都会拥有该属性
class Cat: def __init__(self): print("这是一个初始化方法") # 定义用 Cat 类创建的猫对象都有一个 name 的属性 self.name = "Tom" def eat(self): print("%s 爱吃鱼" % self.name)
2) 对父类方法进行扩展
如果在开发中,子类的方法实现中包含父类的方法实现父类原本封装的方法实现是子类方法的一部分就可以使用 扩展的方式在子类中 重写父类的方法在需要的位置使用super().父类方法 来调用父类方法的执行代码其他的位置 针对子类的需求,编写子类特有的代码实现
24
多态
• 多态是指不同的子类对象调用相同的父类方法,产生不同的执行结果,也就是 定义时的类型和运行时的类型不一样,此时就称为多态,多态可以增加代码的 灵活度,多态以继承和重写父类方法为前提,是调用方法的技巧,不会影响到 类的内部设计。
AttributeError: 'Cat' object has no
attribute 'name' 属性错误:'Cat' 对象没有 'name' 属性
在日常开发中,不推荐在类的外部给对象增加属性如果在运行时,没有找到属性,程序 会报错对象应该包含有哪些属性,应该封装在类的内部
14
对象的封装
• 初始化方法
传递 self 参数在方法内部可以通过 self. 访问对象的属性也可以通过 self. 调用其他的对象方
法改造代码如下:
class Cat: def eat(self): print("%s 爱吃鱼" % self.name)
tom = Cat() tom.name = "Tom" tom.eat()
收外部传递的参数在创建对象时,使用 类名(属性1, 属性2...) 调用
class Cat: def __init__(self, name): print("初始化方法 %s" % name) self.name = name ...
tom = Cat("Tom") ... lazy_cat = Cat("大懒猫") ...
tom.name = "Tom" ... lazy_cat.name = "大懒猫"
注意:这种方式虽然简单,但是不推荐使用!
12
对象的封装
• 方法中的 self 参数
由哪一个对象调用的方法,方法内的self就是哪一个对象的引用
在类封装的方法内部,self就表示当前调用方法的对象自己调用方法时,程序员不需要
第四部分 游戏基本设计思路
27
游戏基本设计思路
• 画背景棋盘
俄罗斯方块屏幕有两个区域,一个是游戏区域, 一个是方块预览区域。
游戏区域用于下落方块进行堆积。 预览区域用于显示下一个要下落的方块类型。
28
游戏基本设计思路
• 将界面拆分成若干个的网格 • 每个格是10*10的大小 • 将预览窗口也同样拆分成网格 • 游戏就是控制在不同的时机渲染不同的网
10
对象的封装
• 创建对象 对象变量 = 类名()
• 第一个面向对象程序 • 需求
小猫 爱吃鱼,小猫要喝 水 分析
定义一个猫类 Cat 定义两个方法 eat 和 drink 按照需求 —— 不需要定义属性
class Cat: """这是一个猫类"""
def eat(self): print("小猫爱吃鱼")
32
俄罗斯方块的代码分析
• 画背景网格
class Grid(object): def __init__(self, master = None, x = 10, y = 10, w = 193, h = 303): self.x = x self.y = y self.w = w self.h = h self.rows = h//10 self.cols = w//10 self.bg = 0x000000; print(self.rows,self.cols)
• Python崇尚“鸭子类型”,“鸭子类型”可以这样表述:“当看到一只鸟走 起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭 子”,也就是关注的不是对象的类型本身,而是它是如何使用的。
25
多态
• 多态更容易编写出出通用的代码,做出通用的编程,以适应需求的不断变化!
Байду номын сангаас26
目 录 Success Words Contents
格
29
游戏基本设计思路
• 消除机制: 当某行没有空的方块时,会消除这行,同
时对这行以上的所有行进行移动,向下移动一 行。 • 失败条件
当第0行不为空时,则游戏结束
30
目 录 Success Words Contents
第五部分 俄罗斯方块代码分析
31
俄罗斯方块的代码分析
• 画背景网格
主要使用方法: 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:背景颜色
继承的概念:子类拥有父类的所有方法和属性
20
继承
• 继承的语法 class 类名(父类名): pass 子类 继承自父类,可以直接享受父类中已经封装好的方法,不需要再次开发 子类 中应该根据职责,封装子类特有的属性和方法
例子:
Dog 类是 Animal 类的子类,Animal 类是 Dog 类的父类,Dog 类从 Animal 类继承 Dog 类是 Animal 类的派生类,Animal 类是 Dog 类的基类,Dog 类从 Animal 类派生
#画背景 for i in range(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);
def drink(self): print("小猫在喝水")
tom = Cat() tom.drink() tom.eat()
11
对象的封装
• 对象的属性
在 Python 中,要 给对象设置属性,非常的容易,但是不推荐使用 因为:对象属性的封装应该封装在类的内部 只需要在 类的外部的代码 中直接通过 . 设置一个属性即可
5
面向对象
•类
类是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用 特征 被称为 属性 行为 被称为 方法 类:就相当于制造飞机时的图纸, 是一个模板,是负责创建对象的
6
面向对象
• 对象
对象 是由类创建出来的一个具体存在,可以直接使用 由哪一个类创建出来的对象,就拥有在哪一个类中定义的:属性、方法
继承
• 方法的重写 子类拥有父类的所有方法和属性 子类继承自父类,可以直接享受父类中已经
封装好的方法,不需要再次开发 当父类的方法实现不能满足子类需求时,
可以对方法进行重写(override)
23
继承
• 重写父类方法有两种情况:
1) 覆盖父类的方法
如果在开发中,父类的方法实现和子类的方法实现,完全不同就可以使用覆盖的方式,在子类中重新编写父类的 方法实现具体的实现方式,就相当于在子类中定义了一个和父类同名的方法并且实现重写之后,在运行时,只会 调用子类中重写的方法,而不再会调用父类封装的方法
lazy_cat = Cat() lazy_cat.name = "大懒猫" lazy_cat.eat()
13
对象的封装
• 初始化方法
之前代码存在的问题 —— 在类的外部给对象增加属性 将案例代码进行调整,先调用方法再设置属性,观察一下执行效果
tom = Cat() tom.drink() tom.eat() tom.name = "Tom" print(tom)
对象被初始化时,会被自动调用
对象被从内存中销毁前,会被自 动调用 返回对象的描述信息,print 函数 输出使用
对象的封装
• 定义只包含方法的类
class 类名: def 方法1(self, 参数列表): pass def 方法2(self, 参数列表): pass
• 方法 的定义格式和之前学习过的函数几乎一样 • 区别在于第一个参数必须是 self,大家暂时先记住,稍后介绍 self • 注意:类名的命名规则要符合大驼峰命名法
21
继承
• 继承的传递性 C 类从 B 类继承,B 类又从 A 类继承 那么 C 类就具有 B 类和 A 类的所有属性和方法
子类拥有父类以及父类的父类中封装的所有属性和方法
提问 哮天犬 能够调用 Cat 类中定义的 catch 方法吗? 答案 不能,因为 哮天犬 和 Cat 之间没有 继承 关系
22
+
牛艾科技
硬件趣学Python编程 做一个融入集体的方块,俄罗斯方块的游戏制作
目 录 Success Words Contents
第一部分
面向对象
第二部分
对象的封装
第三部分
继承和多态
第四部分 第五部分
游戏基本设计思路 俄罗斯方块的代码分析
2
目 录 Success Words Contents
第一部分 面向对象
4
面向对象
• 面向对象 —— 谁来做?
相比较函数,面向对象是更大的封装,根据职责在一个对象中封装多个方法
1. 在完成某一个需求前,首先确定职责—— 要做的事情(方法) 2. 根据职责确定不同的对象,在对象内部封装不同的方法(多个) 3. 最后完成的代码,就是顺序地让不同的对象调用不同的方法
特点:
1. 注重 对象和职责,不同的对象承担不同的职责 2. 更加适合应对复杂的需求变化,是专门应对复杂项目开发,提供的固定套路 3. 需要在面向过程基础上,再学习一些面向对象的语法
# 使用类名()创建对象的时候,会自动调用初始化方法 __init__ tom = Cat() tom.eat()
16
对象的封装
• 初始化方法
改造初始化方法 —— 初始化的同时设置初始值
在开发中,如果希望在 创建对象的同时,就设置对象的属性,可以对 __init__ 方法进行
改造把希望设置的属性值,定义成 __init__ 方法的参数在方法内部使用 self.属性 = 形参 接
对象 就相当于用图纸制造的飞机在程序开发中,应该 先有类,再有对象
7
目 录 Success Words Contents
第二部分 对象的封装
8
对象的封装
• 内置函数 序号 01 02 03
04
方法名 __new__ __init__ __del__
类型 方法 方法 方法
__str__ 方法
作用
创建对象时,会被自动调用
当使用 类名() 创建对象时,会自动执行以下操作: 为对象在内存中分配空间 —— 创建对象 为对象的属性设置初始值 —— 初始化方法(init) 这个初始化方法就是 __init__ 方法,__init__ 是对象的内置方法 __init__ 方法是 专门 用来定义一个类具有哪些属性的方法!
class Cat: """这是一个猫类""" def __init__(self): print("初始化方法")