gpt4 book ai didi

ios - 动画时,CCSprite在其他CCSprite之上的定位问题吗?

转载 作者:行者123 更新时间:2023-12-02 03:03:35 25 4
gpt4 key购买 nike

在我的应用程序中,我有一个有脚的角色,我想制作它,以便在我的应用程序中,它看起来像是站在另一个CCSprite上方,并向上移动到屏幕上(动画)。一切工作正常,除了有一个定位问题,我只是无法解决!
让我再解释一下这个问题,当角色位于CCSprite的顶部时,似乎角色以非常快的间隔上下移动约10点。

有谁知道为什么会这样吗?

谢谢!

最终编辑:,我想再次感谢您为我提供的所有帮助。首先,由于帖子过长,我删除了所有其他编辑,如果出于任何原因需要引用旧的编辑,只需浏览一下我的编辑历史即可!

因此,经过大约一个小时的测试,我将其范围缩小到您前面提到的一个问题,用于检查角色和地板是否碰撞的if语句为,而不是,它们在游戏循环中的每次迭代都被称为应该 be(就它们在用户界面中的外观而言)。

我的cocosGameLoop日志在所有碰撞检测代码之前且之前,但仍在游戏循环中。f

我还注意到我的NSLogs中有一个模式,如下所示:

2012-05-27 17:00:54.791 App[2769:707] cocosGameLoop
2012-05-27 17:00:54.811 App[2769:707] cocosGameLoop
2012-05-27 17:00:54.825 App[2769:707] cocosGameLoop
2012-05-27 17:00:54.841 App[2769:707] cocosGameLoop
2012-05-27 17:00:54.858 App[2769:707] cocosGameLoop
2012-05-27 17:00:54.874 App[2769:707] cocosGameLoop
2012-05-27 17:00:54.891 App[2769:707] cocosGameLoop
2012-05-27 17:00:54.908 App[2769:707] cocosGameLoop
2012-05-27 17:00:54.924 App[2769:707] cocosGameLoop
2012-05-27 17:00:54.928 App[2769:707] collisiontwo
2012-05-27 17:00:54.929 App[2769:707] two
2012-05-27 17:00:54.941 App[2769:707] cocosGameLoop
2012-05-27 17:00:54.944 App[2769:707] collisiontwo
2012-05-27 17:00:54.945 App[2769:707] two
2012-05-27 17:00:54.958 App[2769:707] cocosGameLoop
2012-05-27 17:00:54.974 App[2769:707] cocosGameLoop
2012-05-27 17:00:54.991 App[2769:707] cocosGameLoop
2012-05-27 17:00:55.008 App[2769:707] cocosGameLoop
2012-05-27 17:00:55.025 App[2769:707] cocosGameLoop
2012-05-27 17:00:55.043 App[2769:707] cocosGameLoop
2012-05-27 17:00:55.058 App[2769:707] cocosGameLoop
2012-05-27 17:00:55.076 App[2769:707] cocosGameLoop
2012-05-27 17:00:55.078 App[2769:707] collisiontwo
2012-05-27 17:00:55.078 App[2769:707] two
2012-05-27 17:00:55.091 App[2769:707] cocosGameLoop
2012-05-27 17:00:55.094 App[2769:707] collisiontwo

我还注意到,当我用NSLog记录字符Y坐标时,它会在同一点附近保持几次交互(即使它应该发生碰撞,以使其与上面NSLog中的一堆cocosGameLoop调用重合),然后当它实际发生碰撞(以编程方式),它从之前的Y坐标向上移动了大约14个点。因此,上下抖动约为14点。

因此,最重要的是,如何使碰撞代码称为“每次迭代”,并且不会抖动约14点?我不想更改 anchor ,因为那样会弄乱我的动画位置等等。无论如何,您有什么建议?另外请记住,我仅使用Box2D进行碰撞检测,因此我必须将所有内容都保留在Cocos2D代码中。

最后,我认为我的应用程序由于重力而存在舍入点错误,但是即使当我弄乱了将重力更改为整数之类的值时,它也无法解决闪烁问题,所以这是我上面提到的问题的100% 。

无论如何,这是问题的核心,我认为您可以看到我看不到的东西!让我知道你的想法 :)

非常感谢!

最佳答案

看起来很奇怪的第一件事是您在Some other tag collision checking before注释之后检查了标签。这将更有意义:

else if ((spriteA.tag == 1 && spriteB.tag == 5) || (spriteB.tag == 1 && spriteA.tag == 5))
...
else if ((spriteA.tag == 6 && spriteB.tag == 1) || (spriteB.tag == 6 && spriteA.tag == 1))
...

也就是说,这假设您要测试的碰撞接触可以使您以任意顺序获得两个物体-例如对于两个碰撞的对象(例如角色和地面),接触监听器可以将地面作为主体A,将脚作为主体B,或者将脚作为主体A,将地面作为主体B。上面的语句将保证,无论顺序如何,您都可以执行相同的操作有条件的块。您的执行路径是否有可能在两个 else if块之间振荡,从而在进入错误的块时设置了错误的位置?

好的,假设这些条件都是正确的(并且我只是看不到,因为我也不知道标签也引用了什么主体,联系监听器的设置方式等),那么振荡必然是由物理模拟。使用Box2D在Cocos2d中设置CCSprite的位置时会发生什么?设置子画面的位置是否还会更改物理物体的位置,还是将两者分开(通常将子图形渲染在物理物体的位置)?自从我使用Cocos2d以来已经有一段时间了,而且自从早期以来,它已经发生了很大的变化,所以我不确定在不破解最新版本并进行查看的情况下。如果更改CCSprite的位置也更改了物理物体的位置,那么这是一件坏事-所有运动都应由物理模拟控制(因此,如果要移动物理物体,则应对其施加力或冲动,而不是直接设置位置)。在进行下一步的物理模拟时,更改物理位置在物理之外的位置可能会导致振荡或对物理对象施加不正确的脉冲。如果要在不破坏物理模拟的情况下更改子画面的位置,请考虑在要直接设置位置的所有时间中,从物理模拟中删除与该子画面关联的物理主体,然后在以后重新添加如果您希望它在物理作用下起作用。如果没有干净的方法可以从物理世界中添加/删除物理主体,则可能意味着删除该物理主体,然后在以后重新创建它。

另一个解决方案是在要一起移动的实体之间创建关节。距离连接或焊接接头将是最合适的。这将导致它们被连接,因此,当您四处移动时,另一方也将移动,从而使两个实体之间保持相同的距离。在这种情况下,它们都将在物理模拟下起作用。

实际上,我突然想到,您可能正在更改角色以及角色所站在的CCSprite的物理实体的位置。在这种情况下,这不仅不好,因为物理模拟不受控制,而且您的位置计算还可能导致两个物体稍微重叠,因此当物理模拟下次运行时,它将对两个物体施加很大的力迫使它们分开,但是随后您将位置改回为再次重叠,因此下一次更新会再次产生很大的作用力。

如果更改CCSprite的位置实际上并没有更改物理物体的位置,并且您基本上只是将播放器的渲染位置设置为与物理物体在世界中的位置不同,那么您需要考虑物理 body 正在发生什么。它是滚来滚去,跌落世界,在其他物体或其他物体之间振荡吗?如果不了解您的游戏,我很难判断可能会发生什么。但是发生的事情可能会影响您的排名计算。如果要在 Sprite 周围移动而不让它们受到物理模拟的影响,请考虑从物理世界中删除物理对象。与物理物体打交道时,进行某种类型的调试是非常宝贵的,因此,无论您自己的 Sprite 或其他艺术品如何,您都可以看到每个物体的确切形状和位置以及与物体交互的对象。不知道Cocos2D/Box2D组合是否开箱即用,但如果不能,则强烈考虑实现它,并以一种简单的方式来打开/关闭它。

还有两件事需要考虑:
if (spriteA.position.x - spriteA.boundingBox.size.height*.5 <= spriteB.position.x + spriteB.boundingBox.size.height*.5)


if (spriteB.position.x - spriteB.boundingBox.size.height*.5 <= spriteA.position.x + spriteA.boundingBox.size.height*.5)

您是否尝试过删除这两个语句,以便在每帧中设置一个新的位置,而不是等待位置中的一些错误来累积几个帧?如果要移动一个对象,而又希望另一个对象像固定一样移动,则需要每帧更新位置。可能是您每30个帧中仅传递了10个条件帧,因此假设30 fps,这将产生非常明显的抖动运动,而不是您想要的平滑运动。

希望以上所述可以解决您的问题,或者至少可以让您更好地了解从何处着手。在您的问题中提供更多信息-也许是对我提到的一些假设/未知的回答-应该可以帮助我们深入了解您的问题:)

编辑1

感谢您为我们提供额外的细节-这使事情变得更加清晰。现在,您知道我只在使用Box2D进行碰撞检测,因此您正在做的事情变得非常有意义。

我想说要解决您的问题,请在 for循环中查看联系人,并在其中检测到已建立联系人,您应该只设置一个标志而不是在此时更改字符的位置,例如 BOOL characterOnPlatform-当检测到联系时将其设置为 YES。在该 for循环之外(尽管不一定采用相同的方法-它可以在每个帧中被调用的任何地方,并且在最有意义的地方),您将检查该标志以及 characterOnPlatfom == YES,然后将字符的位置设置为位置计算您当前正在联系人监听器 for循环中进行操作。即在联系人监听器 for循环 中不执行任何操作,但会更改您将在其他地方引用的某些状态。

所做的更改将使您的角色在平台上完全移动。如果您仍然希望角色能够从平台上跳下来,那么如果玩家进行了跳跃之类的输入,则需要将该标志设置回 NO,否则我们将迫使他们进入某个位置来覆盖他们想要的移动在平台上。

编辑2

真的不可能确切了解新代码的运行情况。例如,您的 resetgravity方法中发生了什么?您如何将 hasCollided设置为NO(即如何检测平台上不再存在该字符)?您的角色仍然在上下晃动吗?或者您提到的闪烁与以前有所不同吗?

假设您仍在上下移动,我仍然希望这是由于您发布的代码未在每一帧都被调用,或者是与其他定位代码(例如,无论您移动到何处)作斗争角色以响应玩家的输入,您可以在其中施加重力等)。

确保将字符保留在平台上的代码不会将位置设置得太高,并导致字符被检测为不在平台上,否则您将陷入以下恶性循环:
  • 字符与平台
  • 碰撞
  • 字符位置设置为刚好在平台
  • 上方
  • 角色不再与平台冲突,因此定位代码不会运行以将其重新放置在平台上
  • 字符由于重力的影响而下降(或者您可以对此进行模拟)
  • 字符与平台
  • 碰撞
  • ...

  • 如果是这种情况,那么您需要改进对角色何时不与平台碰撞或偏移定位代码的检测,以使角色保持与平台相交(如果在外观上看起来不太好,则可能需要将小 Sprite 与Box2D形状稍微偏移,以便物理主体与平台略微相交,但角色的脚似乎恰好在平台上。

    编辑3

    听起来您已经排除了很多可能引起抖动的因素!我问了另一位游戏开发人员,他建议您的问题可能是由从世界空间到屏幕空间的转换引起的。因此,您可以尝试注销角色的世界位置以及渲染角色的屏幕位置(这可能意味着在完成此转换的Cocos2D中更改代码)。至少查看注销的值可能有助于缩小一些抖动/振荡的值。您还可以查找可能引入的任何舍入点错误,例如将浮点精度截断为整数。如果您的抖动看起来仅在+或-1像素范围内,那么很值得研究世界位置与屏幕位置。记录这些值比停止每帧调试器要容易得多。

    关于ios - 动画时,CCSprite在其他CCSprite之上的定位问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10569980/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com