gamemaker吧 关注:13,619贴子:94,847
  • 38回复贴,共1

新人关于物体的碰撞实现

只看楼主收藏回复

用place(x,y,obj)好还是用instance_place(x,y,obj)好
我第一次用place,效果不错,但是太慢了,且我碰到墙后就无法做其他的运动了
第二次试了试instance,结果穿墙了,有时候又不穿墙

两次代码如下。
本来录了屏,但是贴吧放不出来。
疑问:1.为什么用二方案会穿墙。
2.为什么把x+spd*h换成x后,player就一头扎进墙里出不来了
3.我没有对wall(黑块)做操作。平常你们都这么写吗吗,或者说我写的效率太低下。


IP属地:江西1楼2024-09-21 23:23回复
    去百度搜 gamemaker8.0从入门到入土(网址由gm8打头接.nihil那个.cc) ,细细阅读 运动 碰撞 键盘与鼠标 栏目
    对于这种简单且基础的要求,希望您先找个文字或视频教程,看不懂再来问,谢谢!


    IP属地:山东2楼2024-09-22 13:02
    收起回复
      用那个move_contact啥的


      IP属地:广东3楼2024-09-23 20:57
      回复
        好吧,被8u狠狠得拷打了
        感谢火柴哥给我推荐的教程,确实比我看文档舒服多了
        之前我是只看了碰撞,所以说问题没有解决。但现在看来,应该从头重写框架。
        模板与我的代码对比:
        1.我的想法是:利用一个表示方向的单位向量h,v做v正负号的调整,按了不同的键,hv的值不一样。但可能我写的时候比较迷糊,打错了好多东西
        2.由于不知道内置hspeed,vspeed这东西,就自定义了水平数值despd_x,spd_y。这两个我不知道效果是否一致,测试时看不出来,除了我要写x+=spd_x
        3.我想说同时按了左右键不动,用了一个else if,为什么他用(D - U)来直接解决?我的猜想:按下d,返回一个值给
        D,按下u,返回一个同样的值给U,这样能保证结果只有-1,0,1三种。
        4.将各种数据放在创建事件,一目了然,我认为这是个好习惯。目前我已知的好的规划习惯有:绘制里只放draw系列的代码,将不同功能的代码放不同的代码框,将全局的变量放入world,还有什么比较好的习惯请求补充一下
        5.固体的局限性是不能处理小于相对速度的距离,所以他用了place_free来解决。我没看懂这个函数的作用。里面(x + hspeed, y + vspeed + gravity)为什么要加上速度依旧不理解,被一笔带过了。问题:(x,y)到底指什么?加上速度,是否是因为让他的固体检测范围减少一个相对速度的大小,所以能让他看上去刚好与贴图没有缝隙。搞懂了place_free我就差不多搞懂这个碰撞了的代码了
        6.这个二段跳的实现逻辑,从else if(!jump)到jump+=1这看不明白。我的理解是:jump=0是指可以跳,此时跳跃速度为jump[1],如果不能跳,则jump=1。这里不应该是!isfirstjump吗,但这么改之后角色实现了无限跳。
        后面,_s的返回值只有0,1,都小于2,这句因该是废话,但是删掉后就会一直自动跳跃。并且isfristjump到底是怎么检测这是不是第一次跳跃的?我以为jump是检测已经跳跃了多少次,但是第二次跟这个没关系


        问的比较多,是因为确实菜到了极点,还是希望有个比较详细的说明


        IP属地:江西5楼2024-10-01 16:22
        收起回复
          这段代码先来问就问吧(虽然的确不太礼貌),然后发问带行数不然改你大脑第3298行代码
          1不是问题
          2.hspeed和vspeed一般的确是与您的写法相等的,不过h/vspeed的坐标运动会自动在步结束事件之前,步事件之后执行,所以主要是方便和统一
          3.数学问题,布尔本身可按照true==1,false==0看待,请楼主枚举可能的四种情况(既D0U0 D1U0 D0U1 D1U1)然后在纸上划拉划拉
          4.看习惯不知道怎么说,一般就是放哪能实现功能且好搞就放哪,然后全局变量一般会使用global.变量
          5是碰撞上的问题(完球咱是杠上了),碰撞本质就是判断重不重合,place_free就是检测该对象目前的碰撞箱在(x,y)的位置上是否与任意一个固体目前的碰撞箱重合,不是就返回1,是就反之。加上速度就是要看到了速度处理后的坐标有没有碰着东西,然后去看move_contact_soild,就是一直往一个方向走,有固体了就贴上去再停止移动,然后在本身步结束时他已经碰到了,所以move_contact_soild就主要只有贴在固体边上的用处了
          6.isFirstJump看得就是你是不是踩地上了,所以其更好的说法为isOnTheGround,处理碰撞后你就应该是地面与你碰撞箱竖着差一像素属于擦边但没重合。你的问题我猜测是11行那个else if(行数很重要的),jump是处理次数的,上限一直到2(0地面大跳,1空中小跳,2及之后不能跳了,既jump==2不能跳了),作者本意是实现i wanna的二段跳(指地面算额外的第一段跳,空中永远算第二段跳)所以那一行就是刷新下落空中二段跳的,楼主的逻辑就成为了“踩地上可以大跳,不踩地上无限小跳”,_S是判断你按下跳了吗,不用判断按不按下跳那可不就一直跳了吗
          哥们我努力解释了,还哪里不懂再问,顺便连碰撞都没搞清咱的确是先试做八向移动比较好


          IP属地:山东6楼2024-10-04 08:14
          收起回复
            此贴还没完,等我周末拿到电脑,我重新把八向移动,以及二段跳重写一遍,我想到了一个二段跳的办法


            IP属地:江西来自Android客户端7楼2024-10-09 13:07
            回复
              完美实现了,此贴终结


              IP属地:江西8楼2024-10-20 09:08
              回复
                啊这,我也是新人,你说了八向移动我就过来了。
                按八向移动来说,这个样子不就可以了吗?


                IP属地:广东来自Android客户端9楼2024-10-21 15:08
                收起回复