鱼C论坛

 找回密码
 立即注册
楼主: 小甲鱼

[扩展阅读] 游戏中的角色移动:闭包(closure)在实际开发中的作用

    [复制链接]
发表于 2018-6-27 10:18:36 | 显示全部楼层
小甲鱼 发表于 2014-1-11 16:24
等于的话走else:分支,临界并不算超界

     就是说如果向右移动130步,为什么要让位置是(70,0),而不是走到100步时就停在100步位置是(100,0)呢?难道是走到100步后又倒回去走,直到走够130步为止?可方向就发生变化了,不符合向右移动啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-6-28 18:05:01 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-6-29 20:00:43 | 显示全部楼层
yu_wind 发表于 2014-1-11 16:55
我估计是我没看明白咋么移动的,
我的理解是, x轴上  原来-80 往左挪30  变成-110  然后 if  的结果是-90 ...

对,是的。从左边撞墙后从右边出来。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-6-30 09:14:30 | 显示全部楼层
yu_wind 发表于 2014-1-11 16:22
请问
if new_x < legal_x[0]:
            pos_x = legal_x[0] - (new_x - legal_x[0])

撞完墙往回走
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2018-7-3 11:18:21 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-18 11:27:21 | 显示全部楼层
本帖最后由 王达沛 于 2018-7-18 11:31 编辑

在看了小甲鱼的《零基础入门学习Python》的闭包函数后进了帖子观摩,
书本上的网址完全是错的,所以直接百度官网后注册搜索,才能进来,
估计是防止某些人恶意破坏,注册新账号后禁止发帖半个小时,,,

这代码本来我也看不懂,后来复制到Python3.65后,结合运行结果大概看明白了

先看 move = create() ,后面的调用方式是 move( 【1,0】,10 ) H]7XA)6Z274C3D02)}OH`CA.png
等价于  create()( 【1,0】,10 ) ,  create() 函数有默认形参,所以相当于
create( pos_x = 0 ,pos_y =  0)( direction = [ 1, 0] , step = 10 )
第一个括号为 原点(0,0),第二个括号 为闭包:内部函数 moving( direction = [ 1, 0] , step = 10 )
的调用,在函数  moving() 中 ,声明了 nonlocal pos_x, pos_y , 表明 pos_x, pos_y 属于
外部作用域:create() 中,即调用其原点位置。

在闭包中对全局变量 (列表list 类型 ) legal_x , legal_y 进行访问(没有进行修改哦),假如
移动后的新坐标 (x,y):  new_x,new_y 超出了规定的范围 legal_x , legal_y 则多出部分往反方向
移动, 即 最大的 x 坐标 为 100,当向右移动 300 时, 最终停留位置: pos_x = 100 - (300 - 100)= -100
超出的 200 ,变成向左移动 200,(如果超过300小甲鱼这个程序的结果就溢出规定范围了哦!)
list列表变量 direction 的含义是 : direction【0】 左右移动(0 左,1 右),direction【1】 上下移动
(0 下,1 上),返回值为终点: pos_x, pos_y  自动打包为元组的 (pos_x, pos_y)形式返回

所以 move( [0, 1], 400 ) = create( pos_x = 0 ,pos_y =  0)( direction = [ 0, 1] , step = 400 )
意思为 从原点 ( pos_x = 0 ,pos_y =  0)向上移动( 因为 direction【1】 = 1)400(step 移动步幅)

以上就是我个人的浅见了,初学请包容,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 2 反对 0

使用道具 举报

发表于 2018-7-18 20:38:29 | 显示全部楼层
书中说“在闭包中,外部函数的局部变量对应内部函数的局部变量”
比如这个例子:
def funX(x):
        def funY(y):
           return x * y
        return funY
意思是funX(x)里面的x的值等于funY(y)中的y吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-18 20:45:37 | 显示全部楼层
上边的
move = create()
print('向右移动10步后,位置是:', move([1, 0], 10))

虽然reate(pos_x=0, pos_y=0)里面的两个形参已有默认初值,但是move引用时候,怎么会跳过对pos_x,pos_y的赋值而直接对序列direction进行赋值?  起码 '向右移动10步的赋值应该是 move(某个值, 某个值, [1, 0], 10)' 这样子吧?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-22 21:28:46 | 显示全部楼层
向右移动10步后,位置是: (10, 0)
向上移动130步后,位置是: (10, 70)
向左移动10步后,位置是: (0, 70)
向上移动130步为什么位置是(10,70),不该是(0,70)吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-22 21:54:41 | 显示全部楼层
mathnawi 发表于 2018-7-22 21:28
向右移动10步后,位置是: (10, 0)
向上移动130步后,位置是: (10, 70)
向左移动10步后,位置是: (0, 7 ...

在执行语句:print('向右移动10步后,位置是:', move([1, 0], 10))   之后pos_x的值已经变成了10,
执行语句:print('向上移动130步后,位置是:', move([0, 1], 130))  之后pos_x=10,pos_y=70
再执行语句:print('向左移动10步后,位置是:', move([-1, 0], 10))  时,过程为:
new_x = pos_x + direction[0] * step  ==》new_x =10+(-1)*10即new_x=0
new_y = pos_y + direction[1] * step  ==》new_y =70+0*10即 new_y=70
QQ图片20180722215316.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-25 22:13:48 | 显示全部楼层
王达沛 发表于 2018-7-18 11:27
在看了小甲鱼的《零基础入门学习Python》的闭包函数后进了帖子观摩,
书本上的网址完全是错的,所以直接百 ...

总体思路没错 但是我觉得最后的结论说的不准确
按照你图上的命令 move( [0, 1], 400 ) 应该等于create(pos_x = 10, pos_y = 0)(direction = [0,1], step = 400)这里的pos_x 和 pos_y已经在上一步里面被赋值了 除非你在运行完第一个print之后重新运行一遍move = create() 否则pos_x和pos_y 不会初始化。
另外这个程序还有缺点 就是边界判断在步数超过300后 会出现如下结果

move = create()
print(move([0,1], 302))
(0, -102)

所以还需要加入pos_x pos_y 的边界判定
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-30 23:10:53 | 显示全部楼层
1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-8-2 14:33:35 | 显示全部楼层
闭包函数的作用在于:每次调用闭包函数(moving)都可以共享上一次调用moving函数所形成的“环境”结果,
这个环境指的就是外部函数的变量即nonlocal pos_x, pos_y。本例中pos_x,pos_y这组变量表明了当前位置状
态即人物所在坐标,而下一次的闭包函数moving调用会基于上次形成的坐标继续移动,形成新的坐标环境。
这就是闭包函数机制的作用。
再从闭包函数的调用机制上看,有人些认为:内部函数返回的元组return pos_x, pos_y直接被外部函数返回
(return moving),于是就认为调用create()得到的返回值是元组(pos_x, pos_y),这种理解是不对的!事实
上,外部函数create中的return的是“对内部函数对象的引用”,通过这个函数对象的引用才能继续反复多次的
调用内部函数,即move=create()得到的move是个函数对象引用,其指向的是闭包函数moving,通过move
对象可以多次调用moving函数并传以不同的参数(move([1, 0], 10)....)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-2 14:43:43 | 显示全部楼层
阿羚 发表于 2018-6-27 10:18
就是说如果向右移动130步,为什么要让位置是(70,0),而不是走到100步时就停在100步位置是(100, ...

这个只是作者设定的游戏规则,就是让人物反弹回去,不必在意
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-3 19:03:25 | 显示全部楼层
这个就是走到头然后再往回走的,如果设定为撞墙之后从另外一边出来的话在临界条件赋值取一个相反数就行了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-11 14:07:06 | 显示全部楼层
这个太高端了我怎么一点也看不懂啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-14 11:18:57 | 显示全部楼层
原来看不懂,今天再回来看,看懂了,博大精深啊。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-14 11:33:00 | 显示全部楼层
小甲鱼是天才程序员啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-17 18:31:31 | 显示全部楼层
当move被重新赋值之后,pose_x,pose_y 没有被初始化为0,而是在前面的基础上继续计算得到的,为什么呀?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-17 18:35:13 | 显示全部楼层
xiawb 发表于 2014-3-26 13:59
>>>
向右移动10步后,位置是: (10, 0)
向上移动130步后,位置是: (10, 70)

向右移动10步后,位置是: (10, 0)
向上移动130步后,位置是: (10, 70)
向左移动10步后,位置是: (0, 70)
move参数改变没有重置pose_x 和pose_y 的初始值,这个的运行结果就是上面所示,why?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-31 01:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表