Ios 精灵套件物理碰撞问题
我遇到了一些碰撞问题。我有两个大小和质量相等的物体。当一个碰撞到另一个静止的物体时,我得到了正确的行为(图像中的灰色区域)。当我有两个相邻的对象时,行为不太正确。在左侧显示Spritekit结果。右侧显示预期/需要的结果 我想我知道发生了什么,但不知道该怎么办。如果对象是一个质量为两倍的对象,则spritekit行为是正确的,但它们是单独的对象,最上面的一个对象应采用传入粒子的速度。它似乎把它们当作一个物体 我曾经尝试过欺骗和缩小两人接触后的半径,以留出一个小间隙,但后来事情就搞砸了。有人知道我在这里能做什么吗?谢谢Ios 精灵套件物理碰撞问题,ios,collision-detection,sprite-kit,skphysicsbody,Ios,Collision Detection,Sprite Kit,Skphysicsbody,我遇到了一些碰撞问题。我有两个大小和质量相等的物体。当一个碰撞到另一个静止的物体时,我得到了正确的行为(图像中的灰色区域)。当我有两个相邻的对象时,行为不太正确。在左侧显示Spritekit结果。右侧显示预期/需要的结果 我想我知道发生了什么,但不知道该怎么办。如果对象是一个质量为两倍的对象,则spritekit行为是正确的,但它们是单独的对象,最上面的一个对象应采用传入粒子的速度。它似乎把它们当作一个物体 我曾经尝试过欺骗和缩小两人接触后的半径,以留出一个小间隙,但后来事情就搞砸了。有人知道我
你能做的,只是理论上,因为我自己还没有尝试过,是在碰撞回调检查中,如果其中一个碰撞器与第三个对象相交/碰撞,并手动计算其速度 我怀疑你不会对2个堆叠的球进行碰撞检测(因为它们从该位置开始),因此手动检查并将适当的速度应用于相邻的物体可能会达到目的 可能必须跟踪哪些“身体对”已经计算了它们的新速度,以避免计算周期(可能是无限的)。简介 这是绝对可以做到的,而且不需要复杂的计算。SpriteKit完全有能力处理这次碰撞。我想你误解了这里的物理原理。在物理学中,有一条简单的规则需要记住,那就是你正在打破它。在这里用现实生活的话来说: 没有两个对象可以占据空间中的同一点。这也适用于对象的部分任何两个物体的任何部分都不能占据空间中的同一点。记住这一点,我们可以说,无论两个物体多么接近,它们之间总是有一定的空间 换句话说,相邻两个对象之间的空间量必须大于零。无论该空间有多小,它仍然必须存在 问题 你潜在的问题是你在蓝色圆圈之间留下了零空间。假设圆的半径为30,顶圆的y位置为400 您定位中间圆的数学可能是
topCircle.position.y-(topCircle.height+middleCircle.height)/2
。由于您的圆都是相同的半径(在我们的示例中为30),您可能会将其简化为topcirle.y-CIRCLE\u DIAMETER
。如果你绝对定位了这些圆,这可能就是你在头脑中进行的计算
无论使用哪一个等式,当你插入数字时,第二个球的y位置都是340
第一个方程式:400-(60+60)/2=340
第二个等式:
400-60=340
(注意:第一个公式更灵活,允许您处理任意大小的圆,而不是统一大小的圆) 问题就在这里。现在应该很清楚,顶部圆圈的底部与中间圆圈顶部的顶部在空间中占据同一点 顶部圆圈:
400-30=370
中间圆圈:
340+30=370
间距:
| 370-370 |=0
两个物理体试图占据空间中的同一点,因此合并成一个物理体,给你你看到的行为
解决方案
综上所述,如果你只需在圆圈之间增加一点(或更少)空间,你就会得到你想要的行为。(注意:还要确保将每个圆的物理体的恢复设置为1) 这适用于任意数量的圆。下面是一个简单的示例场景,其中1个圆圈与4个其他圆圈接触,展示了这种行为。我在iPhone 6上运行了这个:
#import "GameScene.h"
@interface GameScene()
@property (strong, nonatomic) NSArray *nodes;
@end
@implementation GameScene
#pragma mark - View Lifecycle
-(void)didMoveToView:(SKView *)view
{
self.backgroundColor = [SKColor blackColor];
[self createNodes];
[self positionNodes];
[self addNodes];
}
#pragma mark - Setup
- (void)createNodes
{
// You could use SKShapeNode as well
self.nodes = @[[SKSpriteNode spriteNodeWithImageNamed:@"circle"],
[SKSpriteNode spriteNodeWithImageNamed:@"circle"],
[SKSpriteNode spriteNodeWithImageNamed:@"circle"],
[SKSpriteNode spriteNodeWithImageNamed:@"circle"],
[SKSpriteNode spriteNodeWithImageNamed:@"circle"]];
// Use this if you don't have a 30-radius circle image at hand
// self.nodes = @[[SKSpriteNode spriteNodeWithColor:[UIColor blueColor] size:CGSizeMake(60, 60)],
// [SKSpriteNode spriteNodeWithColor:[UIColor blueColor] size:CGSizeMake(60, 60)],
// [SKSpriteNode spriteNodeWithColor:[UIColor blueColor] size:CGSizeMake(60, 60)],
// [SKSpriteNode spriteNodeWithColor:[UIColor blueColor] size:CGSizeMake(60, 60)],
// [SKSpriteNode spriteNodeWithColor:[UIColor blueColor] size:CGSizeMake(60, 60)]];
for(SKSpriteNode *node in self.nodes)
{
node.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:30];
node.physicsBody.affectedByGravity = NO;
node.physicsBody.restitution = 1;
}
}
- (void)positionNodes
{
SKSpriteNode *node = self.nodes.firstObject;
node.position = CGPointMake(300, 400);
for(NSInteger i = 1; i < self.nodes.count - 1; i++)
{
SKSpriteNode *prevNode = node;
node = self.nodes[i];
node.position = CGPointMake(300, prevNode.position.y - (prevNode.frame.size.height + node.frame.size.height) / 2 - 1);
}
node = self.nodes.lastObject;
node.position = CGPointMake(300, 100);
// Above created nodes at these positions:
// (300, 400);
// (300, 339);
// (300, 278);
// (300, 217);
// (300, 100);
}
- (void)addNodes
{
for(SKSpriteNode *node in self.nodes)
{
[self addChild:node];
}
}
#pragma mark - Touch Events
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
SKSpriteNode *node = self.nodes.lastObject;
[node.physicsBody applyImpulse:CGVectorMake(0, 20)];
}
@end
#导入“GameScene.h”
@界面游戏场景()
@属性(强、非原子)NSArray*节点;
@结束
@实现游戏场景
#pragma标记-视图生命周期
-(void)didMoveToView:(SKView*)视图
{
self.backgroundColor=[SKColor blackColor];
[自创建节点];
[自我定位节点];
[自添加节点];
}
#pragma标记-设置
-(void)创建节点
{
//您也可以使用SKShapeNode
self.nodes=@[[SKSpriteNode SPRITENODEWITHIMAGENAME:@“圆圈”],
[SKSpriteNode SPRITENODEWITHIMAGENAME:@“圆圈”],
[SKSpriteNode SPRITENODEWITHIMAGENAME:@“圆圈”],
[SKSpriteNode SPRITENODEWITHIMAGENAME:@“圆圈”],
[SKSpriteNode SPRITENODEWITHIMAGENAME:@“圆圈”];
//如果手边没有半径为30的圆形图像,请使用此选项
//self.nodes=@[[SKSpriteNode spriteNodeWithColor:[UIColor blueColor]大小:CGSizeMake(60,60)],
//[SKSpriteNode spriteNodeWithColor:[UIColor blueColor]尺寸:CGSizeMake(60,60)],
//[SKSpriteNode spriteNodeWithColor:[UIColor blueColor]尺寸:CGSizeMake(60,60)],
//[SKSpriteNode spriteNodeWithColor:[UIColor blueColor]尺寸:CGSizeMake(60,60)],
//[SKSpriteNode spriteNodeWithColor:[UIColor blueColor]尺寸:CGSizeMake(60,60)];
for(self.nodes中的SKSpriteNode*节点)
{
node.physicsBody=[SKPhysicsBody-withcircleofradius:30];
node.physicsBody.affectedByGravity=NO;
node.physicsBody.restitution=1;
}
}
-(void)位置节点
{
SKSpriteNode*node=self.nodes.firstObject;
node.position=CGPointMake(300400);
对于(NSInteger i=1;i