gamemaker吧 关注:13,650贴子:95,114
  • 8回复贴,共1

新人提问集中帖[2023]

取消只看楼主收藏回复

提问须知:
---基础---
0:确认你的问题在置顶帖、贴吧第一页、本集中帖的最后一页都无法找到答案;
1:确认你的问题不在引擎自带的新人教程范围;
2:请勿使用含贬义的词汇来形容你的问题,除非你确实想说“无法回答这个问题的都(贬义词)”;
3:通常来说,你的问题要包含这4个部分,即“你想做什么”(目的)、“你做了什么”(过程/已有内容或方式选择,注意这部分将决定问题的解决方向,什么都不说的话意味着完全答非所问的可能)、“现在的效果”(运行结果)、“决定性的差异”(要改进/改变的地方),除非你有充足的理由省略其中一项或多项;
4:如果附带代码截图,请把object名、事件名、代码行号一起截上,并保证截图里的“空白”尽可能少;
5:提问请注明当前使用的软件版本,如果是参照旧版(2.2或更早)教程,请查看建立script时自带注释的提示阅读文档,并按新的function结构(或者说把旧版教程的script格式转化为新版function格式)进行书写。
---进阶---
6:不要拿别人的代码出来提问;
7:请充分理解,绝大多数问题的解决方案都不唯一,不同人回答的可能是不同路线,且可能在方向上正好相反(如两件事冲突选择放弃/弱化哪一个)。一题多问会大幅度增加这种情况的发生概率;
8:请尽量避免提问类似“有没有人知道……”之类的问题,除非你想要的确实是“有”或“没有”这样的结果(做游戏/程序,严谨是必要的);
9:请尽量使用正式一些(括号齐全,按程序逻辑设置缩进)的代码格式,也许格式改好以后自己就能找到错误在哪;
10:加一个变量能解决的问题都不是问题,加两个变量/一个数据结构能解决的问题也都不是问题;
11:能自己做个demo测试一次就知道答案的问题都不是问题,无论怎样都设计不出demo来做出区分的选择对你来说选哪个都一样,不必纠结。
---传承---
12:如果问题的复杂度较高,且有计划逐步攻克问题并记录完整解决方案的话,建议单独开帖,本吧精华帖类别“经典问答”正是为此准备;
13:问题完美解决以后,希望能留下解决问题的记录(用了什么方法,或参照哪个回答的方案),这里有不少“哟,我这坏了不能用”这样不明所以的提问又在几天之后追加个“哟,现在能用了”这种不明所以的解决方法,对后续搜到帖子的读者没有任何帮助;
---碎碎念---
吧主位空缺的时候,度娘连过滤广告都困难;当选以后,度娘连正常问答都吞帖。


IP属地:北京1楼2022-12-29 09:38回复
    @RTX院长 在2楼的提问解答:
    首先澄清一点,魔塔的通用设计是基于“格子”而非“像素”的。关于“能否移动”、“移动到哪”、“是否与怪物战斗”、“是否拾取物品”的判定也是基于格子进行。这种规则下咱其实更推荐使用数据结构(比如数组/buffer)存储地图信息,而不是在房间里直接摆放,同时解决了各层之间切换时容易出现的“已打过的怪刷新”、“已拾取的物品再出现”、“已消耗过钥匙的门又有了”这样的BUG。“加入一些不规则的设计”感觉有些意味不明,在没有其他信息支撑的情况下,是个就算拿来当噱头也是犯傻程度远高于设计感的东西。
    如果要加入移动动画(其实不推荐,影响游戏节奏),在整格规则下可以使用的方案之一是这样:玩家的移动仍然是“整格”,但加入一个变量是“剩余移动时间”,这个变量的值平时是0,一旦发生移动的话就会变成10,并在每个step自行减少,玩家sprite的绘制位置是由“之前所在的格子”、“当前所在格子”、“剩余移动时间”共同决定,根据需要可以设置成“剩余移动时间非0的时候不能继续移动”
    如果题主坚持不用整格而继续使用像素坐标的话,事情要复杂一点(好在还不至于无解)。首先要明确的是到底是想让角色“走到整格位置停下”还是如问题原文所说的“到再走一像素就撞墙的时候才停止”。前者可以使用时间控制(格子32像素、移动速度4像素的话要移动8次,不推荐无法整除的设计)或坐标判断(比如墙面坐标是100、140、180这样的数字,玩家也要在对40取余数为20时停下)。后者的话,是要在发生碰撞后(或预移动进行碰撞检测后)进行坐标补偿。当然了,这里要补偿到的位置不是网格吸附,而是基于“碰撞目标的坐标”和“移动方向”计算出的值。移动方向题主应该容易记录,碰撞目标的坐标不要使用obj_wall.x表示,而要在碰撞事件里使用other.x,这里涉及到的是object和instance的区别,碰撞事件的other是用来表示“正在和自身发生碰撞的特殊实例”的。
    这里的设计相对要繁琐,一方面要注意step循环的顺序,一方面要注意“移动时同时碰到了两个坐标不同的实例”会导致的BUG。咱推荐的方式是这样:在标准step里进行常规移动,在碰撞事件里完成“推开1像素”的最终坐标确认,注意这里要使用min/max函数保证最终坐标是“可能推到的最远位置”以防止碰撞事件顺序错乱致使“更靠里的墙由于事件触发靠后,反倒把角色‘拉进去’”的BUG。最后在end step里将玩家放到最终坐标。


    IP属地:北京3楼2023-01-05 09:32
    回复
      @贴吧用户_7bb9DC3772 在10层的问题解答
      硬说的话,方案也有……实在不想在GMS2里开DND,拿GM8截个图好了。

      判定的“变量”可以不是“变量”而是“包含变量的表达式”。当然方案不唯一,也可以判定(i-1)*(i-2)*(i-5)*(i-8)是不是等于0,甚至(abs(i-3)-2)*(abs(i-5)-3)是不是等于0……但如果只想一次判断i是否等于某个值就达到一次把1、2、5、8都判定到,在咱已知的范围里是不行的。


      IP属地:北京12楼2023-01-17 23:48
      回复
        @捉摸不透的屑☞ 在2021(居然都不是2022而是2021,雷点0)帖子203层关于“改变精灵没反应”的提问:
        0、从照片(而不是截图,雷点1)上可以看到,此object自定义了draw(绘制)事件
        1、此object的draw事件动作没有截图/照片(即存在“自定义事件里强行绘制sprite6而无视当前sprite选择是什么”这种可能)
        2、运行的照片(也许都不是)没有补充说明,可以说是处于“意义不明”状态
        也许你认为“这是显而易见/约定俗成/正常(正确)思维的人都会这样想/这样做的事,没必要说明”,但请想好“正确思路下制作的结果不会存在这个BUG”。而且人和人不一样,出BUG的地方也会千差万别。如果问题仍未解决,请在今年的帖子里补充问题细节。


        IP属地:北京16楼2023-02-10 10:05
        回复
          @Acilen- 在19楼的提问
          首先:通常我的说法里,object是对象,instance是实例。
          第一个:
          如果版本是GMS2,那么碰撞范围检测函数(如collision_rectangle)都会有一个对应的“获得所有实例”的版本(collision_rectangle_list)。否则请使用with结构。
          第二个:
          请使用with结构。
          with结构:
          0、with结构内的代码不由本实例执行,而是由with到的实例执行;
          1、with结构内,with到的实例是self,原实例是other;
          2、parent关系除了事件-动作关系继承外,还会继承碰撞检测和with是否引用(如果没有改的话);
          那么假设要在obj_A执行代码检测所有obj_B及对应子对象实例,同样使用maxid和maxpower来记录数据,且和示例代码一样只取正值,写法是这样:
          maxid=-1;
          maxpower=0;
          with(obj_B){
            if(power>other.maxpower){
              other.maxpower=power;
              other.maxid=id;
            }
          }
          注意with到的多个实例的执行顺序一定程度上说是不可控的,当有两个或更多目标的power相等且都是最大时可能返回预期外的结果。另外可以和例子一样使用object_index,作用是排除obj_B仅检测子对象。


          IP属地:北京20楼2023-02-23 01:49
          收起回复
            @阿啦心好累 在22层提问的解答:(严格来说,这层仅做出了陈述,并没有进行提问,但还是先当个问题回答一下吧)
            首先,如果有代码截图,请注明事件。以下回答均按图1是初始化部分,图2与图3分别实现了“按键结束对话”和“按键结束打字机效果显示全部文本”两个功能,现在是想整合到一起。
            当前截图的缩进和括号……比较难看,用表格整理了一下逻辑(if为true时执行左边,else放右边)

            其中,待改部分为图2的16-18行、图3的16行。既然这里是想放入两个不同的功能(且只执行一个),那么非常关键的一件事,就是用程序写出“应该在什么时候执行‘显示全部’,什么时候执行‘结束对话’”(分支讨论)。不要想当然认为“这还用说吗,当然是……”我也认为当然是“如果打字机还没结束就是全部显示,如果结束了就是结束对话”。但这件事必须要用代码告诉电脑才行。
            如果题主这些代码都是自己写的,有这些提示应该足够了;如果是照搬的,请参照下面这段:
            if(textposition < string_length(text[textpage])){
            <图3的16行>
            }else{
            <图2的16-18行>
            }
            更新后的逻辑如下

            也许这就是题主的设计逻辑,但这其实是和多数游戏的文本显示逻辑不同的。实际一个3页的对话,第一页尚未完全显示的时候按下按键,会直接翻到第二页,玩家想要看到全部文本只能选择等待。毕竟按照逻辑,只要显示的不是最后一页就要执行翻页,只有最后一页才可能用到“全部显示”的那行代码。
            修正到常规游戏逻辑的话,应该换成这样

            最后再提醒一下,if的圆括号,常规语句行尾的分号,不同深度的缩进,这些习惯建议从一开始就培养(而不是等后期纠正)。

            至于你的游戏里对话过程中玩家和nearbyobj会不会移动,这个判定会不会失效,这里就先不展开了。


            IP属地:北京23楼2023-03-10 14:28
            收起回复
              @贴吧用户_7bb9DC3772 在58楼问题的答复:
              关于石头碰撞:

              这个逻辑可能有些漏洞。就是当人物斜方向起跳,下落时“碰撞”到了石头。如果先计算水平推开,可能明明落在石头顶端(上图右侧红箭头)也会从边缘滑下;如果先计算竖直推开,那么明明人物只是蹭到了石头边缘(上图左侧红箭头),也会成功登顶。实际人物与地形物的交互会基于二者速度、坐标差、动作状态(如果你做了这部分)决定后续状态,并不推荐在DND环境下进行这种判断。
              关于“可跃下平台”:
              这个平台存在多种不同的实现方案,暂时取消平台的碰撞判定(包括但不限于换obj、换sprite、换mask、更改image scale但强行以原比例绘制等方式)是其中一种。好处是好做,坏处是可扩展性不足(处理该动作时同一地形上的其他玩家、怪物、需要考虑掉落的物品装饰物之类的东西也会掉下去)。不过看你在做的游戏,似乎是单人且玩家移动区域没有这些东西,如果今后也不打算做这些的话,使用这个方案问题不大。


              IP属地:北京59楼2023-07-17 16:36
              收起回复
                字数超了就不写在楼中楼里了。
                回一下@我是K小鱼♬ 在84层的问题:
                0、和楼中楼里提到的一样,房间里摆放的各实例,在游戏运行到此房间时,实例放入、自身create事件、ICC这3部分的实行顺序是应该注意的。(且这部分似乎还有版本差异?)提供一个参考的“歪门邪道”是新建个obj_init_level_1来处理所有实例的放入和特殊变量赋值。
                1、一般咱的大框架是编辑阶段针对object,运行阶段针对instance。所以上面提到的“当otrap_parent收到条件”有些怪异,最多有“children没有设置相应事件时直接继承parent对应事件的动作”这种做法。从下文“按理来说可以将otrap_parent的一个实例”来推测,题主是想移动otrap_parent实例。但题主当前提供的消息里并没有什么地方显示出是什么方法在触发变量值变化和/或user0事件。
                2、这里涉及GM版本差异可能我的回答不适用,但不建议用这样的做法。那就是调用script的实例里用了某个变量,script里var了同名变量,script里嵌套with再使用other的该变量……虽说当前这段代码下似乎无论调用到哪个都是相同的值。
                其中,预计序号1的问题是最核心的,但其他两个最好也注意一下。


                IP属地:北京85楼2023-11-27 13:33
                收起回复
                  关于@魔導紳士 在89层的提问:
                  首先是阅读理解,从原文里拆出问题要点发现信息不全,要脑补一部分,如果有猜错的地方,请指出,不然解决方案的方向可能和需求完全不相关。
                  0、要实现的目的:到达准确位置。结合后文提到的速度,推测需要的是“有过程的移动”;
                  1、目前的做法:推测为以常规的定义速度方式移动;
                  2、现状:推测是因为距离与速度的非整数倍数关系,永远无法到达目标,而是超过目标继续 或 在目标位置处左右横跳,所以目前追加了一个alarm事件,来让单位在合适的时间“瞬移”到合适的位置上。
                  问题:除了追加alarm,还有没有其他的方法了?(该方案是否是该问题的唯一解)
                  回答:有。(不是唯一解)
                  /*如果不是想要这个答案,下次可以试试尽量避免问答案是布尔类型(只有true和flase)的问题。*/
                  大部分效果的实现方法都不唯一,不同选择会有实现难度/框架复杂度/可扩展性(兼容性)的差异。alarm方案可以预期的一个情况是,该单位在移动到目标位置的这段时间里“必须不能被打扰”。不然即使移动过程遇到阻碍/减速/击退,该单位还是会在“原计划的时间”突然出现在目标位置上。程序基本都是决定“现在应该做什么”,这种定义“未来要做什么”的情况基本都要考虑“如果预设未来到达之前出现了其他状况”时应该怎么处理。另外这个方案几乎仅适用于匀速移动方式,可扩展的方向几乎没有保留。

                  回到原始模型。有一种常见做法是移动方式本身就分了两部分,首先判定自身与目标位置的间距是否大于步长,如果大于,就移动步长值,否则就“迈一小步到达目标位置”。如果单位移动不受干扰,而且速度不必做出严格限定的话,也可以写一些更好看的移动函数(图示的是直线轨迹,位移量是两段二次曲线)。一边敲这句话的时候还在想一些机甲拼装画面也许用贝塞尔曲线做轨迹效果也不错?


                  IP属地:北京90楼2023-12-20 09:46
                  收起回复