更改具有physicsBody的SKSpriteNode的位置

时间:2023-01-23 00:25:59

I can't change the position of a SKSpriteNode by changing

我无法通过更改来更改SKSpriteNode的位置

self.position = newPosition;

It doesn't work anymore if it has a physicsBody.

如果它有物理实体,它就不再起作用了。

A workaround I got is:

我得到的解决方法是:

    self.myStar.physicsBody = nil;

    [self.myStar changePosition];

    self.myStar.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:self.myStar.size.width/2];

Or

要么

    [self runAction:[SKAction moveTo:newPosiion duration:0.0]];

But #2 isn't smooth. It needs to pop up on another position without a moving action.

但#2并不顺利。它需要在没有移动动作的情况下弹出另一个位置。

5 个解决方案

#1


9  

I had the same problem. Apparently you cannot explicitly set the position of a Sprite node once it has a PhysicsBody. I solved it by temporarily removing the sprite node's PhysicsBody.

我有同样的问题。显然,一旦拥有PhysicsBody,你就无法显式设置Sprite节点的位置。我通过暂时删除精灵节点的PhysicsBody来解决它。

CGFloat yPosition = 400.f;
SKPhysicsBody* goldfishPhysicsBody = _goldfish.physicsBody;
_goldfish.physicsBody = nil;
_goldfish.position = CGPointMake(_goldfish.position.x, yPosition);
_goldfish.physicsBody = goldfishPhysicsBody;

#2


3  

Yes, you can!

是的你可以!

I'm not sure what exactly you're doing and where exactly you run this code and what the observed effect is that you meant by "can't change position" but changing a node's position always works, whether the node has a physicsBody or not, and whether the physicsBody is dynamic or static. I verified this in a simple test project with dynamic set to both YES and NO, with both circle and edge loop body types, using both position property and move actions.

我不确定你到底在做什么以及你在哪里运行这段代码以及观察到的效果是什么意思是“无法改变位置”但改变节点的位置始终有效,无论节点是否有物理实体或不,以及physicsBody是动态的还是静态的。我在一个简单的测试项目中验证了这一点,动态设置为YES和NO,同时使用圆形和边循环体类型,同时使用position属性和move动作。

You can change the node's position either by setting the position property directly or by using a move action - both variants work. If you use a 0 duration for the move action, it effectively becomes the same as setting the position property.

您可以通过直接设置position属性或使用移动操作来更改节点的位置 - 两种变体都可以工作。如果对移动操作使用0持续时间,则它实际上与设置position属性相同。

So whatever problem you're observing, it's not because you can't generally change a node's position once it has a physicsBody. That's absolutely not the case.

所以无论你观察到什么问题,都不是因为一旦它有物理实体,你通常不能改变一个节点的位置。绝对不是这样的。

I'm guessing you may have run into one of the following problems:

我猜你可能遇到以下问题之一:

  • node is already running a different move action, overriding your position changes
  • 节点已在运行不同的移动操作,覆盖您的位置更改
  • you were looking at the wrong node (use logs to verify actual position of the node in question)
  • 你正在查看错误的节点(使用日志来验证相关节点的实际位置)
  • you change position elsewhere, for example setting the node's position every frame thus invalidating any other position change
  • 你在其他地方改变位置,例如每帧设置节点的位置,从而使任何其他位置变化无效
  • if it's not one of the above, then possibly something else I couldn't think of ...
  • 如果它不是上述之一,那么可能是我想不到的其他东西......

#3


3  

I had a problem like this where I tried to update position inside didBeginContact:, but it was not having any effect, I think because the physics simulation immediately clobbers the value.

我有一个这样的问题,我试图更新didBeginContact:中的位置,但它没有任何影响,我认为因为物理模拟立即破坏了价值。

My solution was to cache the new position in a property on my scene and then update the position of the node next time update: was called on my scene.

我的解决方案是在我的场景中的属性中缓存新位置,然后在我的场景上调用下次update:时更新节点的位置。

[SKAction moveTo:newPosition duration:0.0] worked for me, too, and there was no popping. I haven't decided yet which is more elegant.

[SKAction moveTo:newPosition duration:0.0]也适用于我,并且没有弹出。我还没有决定哪个更优雅。

#4


3  

I think the problem you are having is that in order for you to control a phsyics body, you need to set it to dynamic.

我认为你遇到的问题是,为了控制一个phsyics体,你需要将它设置为动态。

self.myStar.physicsBody.dynamic = NO;

self.myStar.physicsBody.dynamic = NO;

If the dynamic property is set to YES, then the physics engine is in control of it's movement.

如果动态属性设置为YES,则物理引擎控制它的移动。

As noted in the comments, setting dynamic to NO shouldn't restrict movement via SKAction or position property. However, if it is set to YES, it's possible that something in the physics engine is affecting your attempt to move the node.

如评论中所述,将动态设置为NO不应限制通过SKAction或位置属性的移动。但是,如果将其设置为YES,则物理引擎中的某些内容可能会影响您移动节点的尝试。

If you want the movement to not pop, then you need to set a duration higher than zero to your SKAction or it will pop as you have described. Setting duration to 0.0 is the same as just changing the position.

如果您希望移动不弹出,则需要为SKAction设置大于零的持续时间,否则它将按照您的描述弹出。将持续时间设置为0.0与仅更改位置相同。

For example :

例如 :

[self runAction:[SKAction moveTo:newPosition duration:1.0]];

[self runAction:[SKAction moveTo:newPosition duration:1.0]];

will move the node to the new position over 1 second.

将节点移动到1秒钟以上的新位置。

#5


0  

Seems similar to SKSPriteNode position changes to 0,0 for no reason

似乎类似于SKSPriteNode位置变为0,0无缘无故

As stated in answer and comments of this question, it seems you must either set the position before setting the physicsBody and/or set the physicsBody after adding the node to your scene.

正如在这个问题的答案和评论中所述,似乎你必须在设置physicsBody之前设置位置和/或在将节点添加到场景后设置physicsBody。

I've had this problem in several scenarios and I haven't found out what exactly causes it to fail sometimes.

我在几个场景中遇到过这个问题而且我还没有找到究竟是什么原因导致它有时失败。

#1


9  

I had the same problem. Apparently you cannot explicitly set the position of a Sprite node once it has a PhysicsBody. I solved it by temporarily removing the sprite node's PhysicsBody.

我有同样的问题。显然,一旦拥有PhysicsBody,你就无法显式设置Sprite节点的位置。我通过暂时删除精灵节点的PhysicsBody来解决它。

CGFloat yPosition = 400.f;
SKPhysicsBody* goldfishPhysicsBody = _goldfish.physicsBody;
_goldfish.physicsBody = nil;
_goldfish.position = CGPointMake(_goldfish.position.x, yPosition);
_goldfish.physicsBody = goldfishPhysicsBody;

#2


3  

Yes, you can!

是的你可以!

I'm not sure what exactly you're doing and where exactly you run this code and what the observed effect is that you meant by "can't change position" but changing a node's position always works, whether the node has a physicsBody or not, and whether the physicsBody is dynamic or static. I verified this in a simple test project with dynamic set to both YES and NO, with both circle and edge loop body types, using both position property and move actions.

我不确定你到底在做什么以及你在哪里运行这段代码以及观察到的效果是什么意思是“无法改变位置”但改变节点的位置始终有效,无论节点是否有物理实体或不,以及physicsBody是动态的还是静态的。我在一个简单的测试项目中验证了这一点,动态设置为YES和NO,同时使用圆形和边循环体类型,同时使用position属性和move动作。

You can change the node's position either by setting the position property directly or by using a move action - both variants work. If you use a 0 duration for the move action, it effectively becomes the same as setting the position property.

您可以通过直接设置position属性或使用移动操作来更改节点的位置 - 两种变体都可以工作。如果对移动操作使用0持续时间,则它实际上与设置position属性相同。

So whatever problem you're observing, it's not because you can't generally change a node's position once it has a physicsBody. That's absolutely not the case.

所以无论你观察到什么问题,都不是因为一旦它有物理实体,你通常不能改变一个节点的位置。绝对不是这样的。

I'm guessing you may have run into one of the following problems:

我猜你可能遇到以下问题之一:

  • node is already running a different move action, overriding your position changes
  • 节点已在运行不同的移动操作,覆盖您的位置更改
  • you were looking at the wrong node (use logs to verify actual position of the node in question)
  • 你正在查看错误的节点(使用日志来验证相关节点的实际位置)
  • you change position elsewhere, for example setting the node's position every frame thus invalidating any other position change
  • 你在其他地方改变位置,例如每帧设置节点的位置,从而使任何其他位置变化无效
  • if it's not one of the above, then possibly something else I couldn't think of ...
  • 如果它不是上述之一,那么可能是我想不到的其他东西......

#3


3  

I had a problem like this where I tried to update position inside didBeginContact:, but it was not having any effect, I think because the physics simulation immediately clobbers the value.

我有一个这样的问题,我试图更新didBeginContact:中的位置,但它没有任何影响,我认为因为物理模拟立即破坏了价值。

My solution was to cache the new position in a property on my scene and then update the position of the node next time update: was called on my scene.

我的解决方案是在我的场景中的属性中缓存新位置,然后在我的场景上调用下次update:时更新节点的位置。

[SKAction moveTo:newPosition duration:0.0] worked for me, too, and there was no popping. I haven't decided yet which is more elegant.

[SKAction moveTo:newPosition duration:0.0]也适用于我,并且没有弹出。我还没有决定哪个更优雅。

#4


3  

I think the problem you are having is that in order for you to control a phsyics body, you need to set it to dynamic.

我认为你遇到的问题是,为了控制一个phsyics体,你需要将它设置为动态。

self.myStar.physicsBody.dynamic = NO;

self.myStar.physicsBody.dynamic = NO;

If the dynamic property is set to YES, then the physics engine is in control of it's movement.

如果动态属性设置为YES,则物理引擎控制它的移动。

As noted in the comments, setting dynamic to NO shouldn't restrict movement via SKAction or position property. However, if it is set to YES, it's possible that something in the physics engine is affecting your attempt to move the node.

如评论中所述,将动态设置为NO不应限制通过SKAction或位置属性的移动。但是,如果将其设置为YES,则物理引擎中的某些内容可能会影响您移动节点的尝试。

If you want the movement to not pop, then you need to set a duration higher than zero to your SKAction or it will pop as you have described. Setting duration to 0.0 is the same as just changing the position.

如果您希望移动不弹出,则需要为SKAction设置大于零的持续时间,否则它将按照您的描述弹出。将持续时间设置为0.0与仅更改位置相同。

For example :

例如 :

[self runAction:[SKAction moveTo:newPosition duration:1.0]];

[self runAction:[SKAction moveTo:newPosition duration:1.0]];

will move the node to the new position over 1 second.

将节点移动到1秒钟以上的新位置。

#5


0  

Seems similar to SKSPriteNode position changes to 0,0 for no reason

似乎类似于SKSPriteNode位置变为0,0无缘无故

As stated in answer and comments of this question, it seems you must either set the position before setting the physicsBody and/or set the physicsBody after adding the node to your scene.

正如在这个问题的答案和评论中所述,似乎你必须在设置physicsBody之前设置位置和/或在将节点添加到场景后设置physicsBody。

I've had this problem in several scenarios and I haven't found out what exactly causes it to fail sometimes.

我在几个场景中遇到过这个问题而且我还没有找到究竟是什么原因导致它有时失败。