当前课程知识点:Python 交互式程序设计导论 > 第4周 > A 课程视频(列表) > 碰撞和反射
返回《Python 交互式程序设计导论》慕课在线视频课程列表
同学们,大家好,欢迎来到python交互式程序设计导论mooc课堂
这一讲,我们给大家碰撞和反射
实际上,碰撞和反射,这一种自然现象,这个物理现象,大家应该是熟悉的
有些打篮球的同学,可能有这样的经历
你使劲把篮球拍向地面,篮球会反弹回来
乒乓球也一样,我们的拍子撞击到乒乓球,乒乓球会反弹回去
如果我们不考虑重力,不考虑摩擦力,不考虑这些因素
我们可以用中学学过的动量守恒定律,还有弹性碰撞,这些公式计算反弹以后的速度和方向
好,下面,我们通过程序来看看,实现在我们游戏当中处理这个碰撞和反弹的情况
注意看,这个程序里面,我们画板的大小是,宽度600, 高度600
我们定义了一个红色的圆,它的半径是60个像素,初始的位置在左上角是0和0
它的运动速度是0和0,速度为什么是两个值, 因为有x轴方向 y轴方向
因为我们在二维的平面上,所以,这种表示方法,你可以把它看成一个向量
我们有一个restart()函数,这个函数让圆心位置变成画布的正中央
让这个圆的运动速度x轴上面随机生成一个-5到6之间, 不包括6 之间的一个整数,y轴上也是,随机的生成-5到6,不包括6
-5 -4 -3 -2 -1 0 1 2 3 4 5 ,这当中的某一个数字
这是restart()函数完成的初始化功能
当然,我们有一个按钮会调用它,就是button,重新开始,这个按钮,会调用这个函数, 同样,我们这个程 一开始也会调用它一次
好,接着看,每次,我们的屏幕刷新函数,会调用update_display()这个函数 , 这个函数会让圆心的位置按照速度递增
换句话说,以已知的速度来运动
最后呢,在我们的函数中把这个圆画出来,大家都知道,这个函数是屏幕刷新函数
屏幕刷新的函数,每秒钟会被调用60次
好,现在看看,这个程序运行的效果
重新开始,有一个圆,再开始,再开始
注意, 每次这个圆的速度不一样, 因为x轴 y轴上的速度决定它向不同的方向运动, 快慢当然也不一样
但是,现在,我们这个程序,它的圆可以直接移动出我们的画板
我们现在希望 ,这个圆碰到画板的四壁以后反弹回来
比如说,碰到下面的壁,向上反弹, 碰到左边的壁向右反弹
好 ,大家注意一下, 如果这个圆向右运动 ,反弹回来, 实际上是x方向上的速度取反 , 原来是正的, 现在是负的,而y方向不发生变化
一样,如果是碰到上壁或者下壁,x轴原来的速度不发生变化
y轴原来是正数现在是负数
好, 我们如何来做到这一点
为了让游戏更加有趣,我们希望碰到壁以后,有个声音
所以,我们需要导入声音的资源
现在来运行我们的程序,注意看,我们的判断条件
当红色的圆心,它的x轴,减去它本身的半径,再加上速度的增量 小于等于0,这意味着它碰到了左壁 1 00:05:01,398 --> 00:05:08,654 或者是,当圆心加上半径再加上它运动的速度
就是一次变化的那个速度的位置
如果大于等于画布的宽度,意味着它碰到了右边的墙壁
这时候我们要求把x的速度取反
原来如果x是正速度,现在变为负速度,原来是负速度现在变成正速度
同时让它播放撞击墙的声音,好,我们看一下
注意看,注意看,注意看
对,左边右边都没问题,但是上下现在不起作用
下面不管用,左边没问题反弹回来了
好,现在我们希望碰到上臂和下臂也同样能够反弹回来
好,看一下,当圆心的外周减去圆的半径再加上速度的偏移量
如果小于零,那意味着碰到了上臂
或者,当圆心的外周加上半径再加上速度的增加量
大于等于画板的高度,那意味着碰到了画板的最下方,边缘
这时候我们要求外周上的速度取反,然后发出声音,好,运行
好,没问题!现在这个圆只能在这个画板范围内运动了
它碰到四壁都会发生反弹,而且这个反弹的角度是符合物理学规律的
当然我们没有考虑重力,摩擦力等其它因素,所以它会一致的运动下去
现在我们再添加一个蓝色的圆,让两个圆在这个画板当中运动
并且我们考虑两个圆碰撞以后会发生什么事情
在这里再声明一个蓝色的圆,它的半径也是60像素,初始位置,初始的圆心位置,初始的速度
接下来在restart函数当中,对两个圆的圆心位置和两个圆移动的速度进行初始化
而我们希望红色的圆在左上角出现,每次运行restart的时候
而蓝色的圆在右下角出现
所以左上角我们看是半径乘二就是直径,y也是一样半径乘二,这对红色的圆
而对蓝色的圆是宽度,因为我们是正方形宽和高是一样的都是600所以宽度减直径,那它在右下角
好,接下来我们修改uodate-desplay 这个函数来更新蓝色圆心的位置
用蓝色圆的速度去更新蓝色圆的圆心位置
好,然后在画板绘制蓝色的圆,运行一下看看她的效果
注意看,红色的圆从左上角开始出现,蓝色的圆呢从右下角出现
但是这时候蓝色的圆呢还没有进行四壁的碰撞处理,所以它就会飞出画板
而红色的圆没问题
下面我们来对蓝色圆碰撞四壁进行检测并处理
这个和红色圆的检测化一样,这个就不多说了,下面来运行看效果
没问题,重新开始,没问题
现在两个圆都已经能够碰到四壁以后反射回来
但是注意两个圆互相碰撞以后并没有发生弹性碰撞这种效果
我们怎么办呢?
好,我们看一看,两个物体发生碰撞以后它的速度怎么计算
好,假设两个物体碰撞以后它遵守动量守恒的弹性碰撞的规则
那么碰撞以后它的速度,新的速度会是什么样呢
好,我们看看这个公式
V1’假设代表红色圆它碰撞以后的速度
而V那就是碰撞以前的速度
它当然有X和Y两个分量
所以我们可以把它看成一个向量
这是m2、m1是两个圆的重量、质量
因为我们现在是两个大小一样的圆
可以看成是相等的
这一部分,就是2*m2/(m1+m2)实际上就是1
而后面的这一块,上面这一部分
V1-V2,是两个圆碰撞那一霎那间的速度
两个向量相减
而后面,X1-X2是两个圆碰撞那一霎那间它们圆心的位置相减
然后对它们进行点积运算
减后,两个向量相减还是向量
对它进行点积运算
除以两个圆心所表示的向量之差形成的一个新的向量它的模
长度,长度的平方
当然后面还乘了两个圆心的向量之差
一样,对蓝色的球也是这样的计算方法
好,这是它的计算公式
看起来挺复杂,实际上就是简单的加减乘除
我们来看看,在程序里头如何来判断两个圆发生碰撞
为此我们要定义一些辅助的函数
第一个辅助的函数用来计算两个点之间的距离
第一个point,point1是一个点X、Y构成,两个值构成
point2也是由两个点X、Y两个值构成
两个点的距离计算的公式,大家看一下
在平面坐标上,两个点P1、P2它的距离怎么计算
这个d等于X1-X2的平方加上Y1-Y2的平方,开根号
实际上就是勾股定理,这个很简单
我们看看这个函数,刚好和这一样的
X1-X2的平方加上Y1-Y2的平方,然后开根号
这是两个点之间距离的计算
好,两个向量之间的差,它的定义就是
X分量减X分量形成新的向量X分量
Y分量减Y分量就形成了新向量的Y的分量
那就是X1-X2,然后,后面是Y1-Y2
两个向量的点积V1和V2
是指它的X分量乘起来,X1乘X2
再加上Y分量乘起来,Y1乘上Y2,也很简单
好,下面计算向量长度的平方
这个向量里头X分量的平方加上这个向量的Y分量的平方
为0的平方加上为1的平方
有了这几个函数我们就可以计算两个圆是否相碰撞
首先如何来判断它是不是发生碰撞
注意我们来计算这两个圆心的距离
如果这两个圆心的距离小于等于这两个圆的半径之和
说明发生了碰撞
这时候我们首先播放音效
然后开始计算它的速度
碰撞后两个圆的速度
好,先计算向量的长度的平方,就是下面这个
两个竖杠X1-X2两个竖杠的平方,计算这一块
我们直接用向量减它的圆心
减出来以后我们用刚才那个函数去返回来
这是向量长度的平方
然后我们再来计算
这一部分本来是1,就不用去管它了
计算上面这一部分
加这一部分合起来我们把它叫做系数
先计算V1-V2,好,V1-V2,放到这里
然后计算X1-X2,放到这里
当然这个vec_sub前面这个函数已经定义了
然后计算点积除以我们前面计算过的向量长度的平方
好,用我们自己的点积函数计算这两个
然后除以这个长度的平方
好,这是红色圆的这部分系数已经计算完了
以此同样的方法计算蓝色圆的变化系数
好,下面我们看如何来计算碰撞以后的速度
碰撞以后的速度是V1’等于V1减去我们计算出来的这个系数
乘上两个圆的圆心相减以后形成的一个新的向量
圆心因为也是有X坐标和Y坐标
我们可以看成一个点,当然也可以看成一个向量
好,先看两个圆心减之后的X值,X分量,乘上我们的系数
用原来速度上X值减去我们新计算出的这个X值就是新的速度
同样的方法计算出Y分量上碰撞以后的速度
这是对红色的圆
然后对蓝色的圆也可以做这样的处理
最后我们得到新的速度
好,下面运行一下,看一下效果
好,两个圆碰撞以后会发生弹性碰撞
快一点、慢一点,效果都是一样
好,非常有趣
我们第四周的游戏,桌上冰球里头也会有碰撞和反射的问题
因此这一讲的内容对完成我们第四个游戏是非常重要的
好,刚才通过演示给大家介绍了两个物体发生碰撞以后如何实现它的反射
这是一种很好的,将物理的概念通过计算机模拟验证的一种方法
当然,我们第四个游戏项目叫桌上冰球
也会用到碰撞和反射这些知识
好,谢谢大家观看,咱们下次再见
-课程简介
--课程简介
-A 课程视频(算数操作符及表达式)
--绪论
-B 课程视频(变量及赋值)
--变量
--项目提交
-C 辅助视频(计算机结构、Python开发环境安装)
-D 辅助视频(如何提交项目)
--项目提交
-第0周--小测验
-本周项目:"我喜欢Python"
--游戏说明
--程序说明
--编码步骤
--评分标准
--项目模板
--项目提交
-A 课程视频(函数)
--函数
--其它操作符
--随机函数
-B 课程视频(逻辑及表达式)
--逻辑值和比较
--条件
--编程技巧
-第1周--小测验
-本周项目:“老虎杠子鸡虫”游戏
--游戏说明
--程序说明
--编码步骤
--评分标准
--项目模板
-A 课程视频(Python交互式应用)
--事件驱动编程
--按钮
-B 课程视频(输入框、全局变量)
--输入框
--编程技巧
-第2周--小测验A
-第2周--小测验B
-本周项目:猫咪藏在哪个房间
--游戏说明
--程序说明
--编码步骤
--评分标准
--项目模板
-A 课程视频(画布绘图)
--画布和图形绘制
--字符串处理
--图片和音效
-B 课程视频(计时器)
--计时器
--交互式绘图
--“神奇时钟”游戏
--编程技巧
-第3周--小测验A
-第3周--小测验B
-本周项目:“神奇时钟”
--游戏说明
--程序说明
--编码步骤
--评分标准
--项目模板
-A 课程视频(列表)
--列表
--键盘输入
--碰撞和反射
-B 课程视频(键盘控制)
--速度控制
--运动
--编程技巧
--“桌上冰球”游戏
-第4周--小测验A
-第4周--小测验B
-本周项目:“桌上冰球”游戏
--游戏说明
--程序说明
--编码步骤
--评分标准
--项目模板
-A 课程视频(鼠标输入、列表进阶)
--鼠标输入
--Video
--Video
--Video
-B 课程视频(字典和图片)
--Video
--Video
--Video
--Video
-第5周--小测验A
-第5周--小测验B
-本周项目:“世界杯八强连连看”
--游戏说明
--程序说明
--编码步骤
--评分标准
--项目模板
-A 课程视频(类)
--华容道中的类
-B 课程视频(平铺图片)
--平铺图片
--理解对象
--编程技巧
--“华容道”游戏
-第6周--小测验A
-第6周--小测验B
-本周项目:“华容道”游戏
--游戏说明
--程序说明
--编码步骤
--评分标准
--项目模板
-A 课程视频(类进阶及文件操作)
--集合
--文件操作
--文字块类
--处理停止的文字块
-B 课程视频(游戏状态控制)
--游戏记分规则
--编程技巧
-第7周--小测验A
-第7周--小测验B
-本周项目:决战三字经
--游戏说明
--程序说明
--编程步骤
--评分标准
--项目模板
-A、课程视屏(精灵集合)
--Video
--精灵类
--战士类
--编程技巧
-B、课程视屏(动画)
--精灵碰撞
--精灵动画
--编程技巧
--保卫家园游戏
-第8周--小测验
-本周项目:守卫家园
--游戏说明
--程序说明
--编程步骤
--评分标准
--项目模板