我正在尝试使用Sprite Kit设置一些弹性碰撞.正如我在Sprite Kit Physics Collision Issue中提到的那样,多个物体彼此靠近的情况存在问题
我对碰撞情况的时机感到困惑.
我试着设置dynamic
到NO
在-didBeginContact:
委托方法,计算最终速度,然后在-didEndContact:
设定的dynamic
到YES
,然后正确设置速度.
我希望它在碰撞之外是动态的原因是因为我想要摩擦/重力等.订单/逻辑有什么问题?我看了一下-didSimulatePhysics
方法,但它似乎不是要走的路.
我的场景有一堆矩形,物理体与矩形大小相同.我喜欢将我的所有物体锚定到CGPointZero,但是我注意到当我这样做时,物理体仍然固定在中间.换句话说,我的物理体的位置就像是视觉表示的左下方100像素.
这是一段简单的代码:
SKSpriteNode* square = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(width, height)];
square.anchorPoint = CGPointZero; //position based on bottom-left corner
square.position = CGPointMake(x, y);
square.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(width, height)];
Run Code Online (Sandbox Code Playgroud)
任何想法或建议解决这个问题将不胜感激.例如,如果我可以想象物理机构,这可能有所帮助,但我不知道如何.
更新:所以我通过简单地设置锚点并重新定位我的矩形来解决问题.所以这个问题仍然存在,但我已经有了解决方案并且工作正常.
据我所知,物理体的默认值是当它们相互碰撞时相互反弹,直到你将collisionBitMask设置为相等的数字.
但是,我有一个很大的问题,因为碰撞我认为看起来应该非常简单.
let RedBallCategory : UInt32 = 0x1 << 1
let GreenBallCategory: UInt32 = 0x1 << 2
let RedBarCategory : UInt32 = 0x1 << 3
let GreenBarCategory : UInt32 = 0x1 << 4
let WallCategory : UInt32 = 0x1 << 5
greenBall.physicsBody?.categoryBitMask = GreenBallCategory
greenBall.physicsBody?.contactTestBitMask = RedBarCategory
greenBall.physicsBody?.collisionBitMask = GreenHealthCategory
redBall.physicsBody?.categoryBitMask = RedBallCategory
redBall.physicsBody?.contactTestBitMask = GreenBarCategory
redBall.physicsBody?.collisionBitMask = RedHealthCategory
let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsBody = borderBody
self.physicsBody?.friction = 0
borderBody.contactTestBitMask = RedBallCategory | GreenBallCategory
borderBody.categoryBitMask = WallCategory
Run Code Online (Sandbox Code Playgroud)
所以这里我有2个球和我的边界.我可以得到我想要的碰撞检测,但是当我添加边框体的类别位掩码时,它允许球穿过和离开屏幕,这是我不想要的.
我也希望球能够相互反弹,但只有当我注意到球的类别之一时,他们才能反弹.否则他们会互相通过. …
所以我有一个物体有物理体,重力影响它.它也是动态的.
目前,当用户触摸屏幕时,我运行代码:
applyForce(0,400)
物体向上移动大约200,然后由于重力下降.这只会在某些时候发生.其他时候,它导致物体仅在Y方向上移动50个单位.
我找不到一个模式......我把我的项目放在Dropbox上,这样如果有人愿意看它就可以打开它.
https://www.dropbox.com/sh/z0nt79pd0l5psfg/bJTbaS2JpY
编辑:这似乎发生在玩家在撞击后稍微从地面反弹一段时间后.有没有办法让玩家不会反弹?
编辑2:我尝试使用摩擦参数解决这个问题,并且只允许玩家在摩擦力为0时"跳跃"(你会认为这将是玩家空降的所有情况)但是摩擦似乎大于0每时每刻.如果玩家正在触摸一个物体(除了使用y位置),我怎么能检测到?
谢谢
我试图在Swift中使用碰撞位掩码和接触测试位掩码,我希望两个对象不要碰撞在一起,所以我在做:
firstNode.physicsBody?.collisionBitMask = 0b01
secondNode?.collisionBitMask = 0b10
Run Code Online (Sandbox Code Playgroud)
由于SpriteKit不上这两个数字与操作,应该没有结果是00
因为10 & 01 = 00
?
那么为什么碰撞会发生呢?
谢谢.
假设我有一个代表车轮的SKSpriteNode,圆形SKPhysicsBody成功连接到它上面.显然,该类型将横向滚动2d汽车驾驶游戏/模拟器.
我想要的是自己计算所有的电机内物理,而不必使用SpriteKit物理引擎.我想完全控制如何计算电机,离合器,变速箱等的机械装置,一直到驱动轮的转速.
从那时起,我很乐意控制SpriteKit物理引擎,然后计算当旋转驱动轮接触道路表面时会发生什么.无论情况如何,汽车前进,减速,加速和/或车轮打滑.
计算获得车轮转速的机制是没有问题的.我只是不确定如何从那里继续.
我可以通过在update:方法中应用zRotation来旋转方向盘,如下所示:
self.rearWheelInstance.zRotation += (self.theCar.wheelRPS/6.283 * timeSinceLastUpdate); // revolutions / 2pi = radians
Run Code Online (Sandbox Code Playgroud)
这样我就可以应用我之前计算过的精确RPM.明显的缺点是,SpriteKit的物理引擎完全没有注意到这种旋转.对于它所知道的一切,轮子从一个相位传送到下一个相位,因此它不会产生与路面的摩擦或与其他SpriteKit物理实体的任何其他交互.
另一方面,我可以在车轮上施加扭矩:
[self.rearWheelInstance.physicsBody applyTorque: someTorque];
Run Code Online (Sandbox Code Playgroud)
或角度冲动:
[self.rearWheelInstance.physicsBody applyAngularImpulse: someAngularImpulse];
Run Code Online (Sandbox Code Playgroud)
这确实以SpriteKit物理引擎理解的方式旋转轮子,从而使其与周围环境正确交互.
但除非我遗漏了一些明显的东西,否则它会将车轮视为一个独立于曲轴,传动装置或驱动轴转速的"自由滚动物体".但实际上,车轮没有"选择"在任何其他转速下滚动,而不是通过动力传动系统传递到轴上(除非变速器处于空档,离合器踏板踩下或离合器打滑,但这些都是另一个故事).
所以:1)我能以某种方式操纵zRotation,使SpriteKit物理引擎"理解"为旋转运动吗?
要么
2)我的逻辑中是否有明显的缺陷表明这不是我应该首先尝试的?如果是这样,你能不能指出我的缺陷,以便我可以采取更好的做法?
我想在两个SKPhysicsBodies之间创建简单的关节.但是,他们表现得非常奇怪.我很清楚锚点应该在场景坐标上.请查看附带的源代码.
例如,这是在矩形上附加小方块后如何生成固定关节.
-(void)createFixedJointOnScene:(SKScene*)scene
Run Code Online (Sandbox Code Playgroud)
{
//Adding Rectangle
SKSpriteNode* backBone = [[SKSpriteNode alloc] initWithColor:[UIColor whiteColor] size:CGSizeMake(20, 200)];
backBone.position = CGPointMake(CGRectGetWidth(self.frame)/2.0, CGRectGetHeight(self.frame)/2.0);
backBone.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:backBone.size];
backBone.physicsBody.categoryBitMask = GFPhysicsCategoryRectangle;
backBone.physicsBody.collisionBitMask = GFPhysicsCategoryWorld;
[scene addChild:backBone];
//Adding Square
SKSpriteNode* head = [[SKSpriteNode alloc] initWithColor:[SKColor grayColor] size:CGSizeMake(40, 40)];
head.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:head.size];
head.position = CGPointMake(backBone.position.x, backBone.position.y-40);
head.physicsBody.categoryBitMask = GFPhysicsCategorySquare;
head.physicsBody.collisionBitMask = GFPhysicsCategoryWorld;
[scene addChild:head];
//Pinning Rectangle and Square
NSLog(@"Head position %@", NSStringFromCGPoint(head.position));
SKPhysicsJointFixed* pin =[SKPhysicsJointFixed jointWithBodyA:backBone.physicsBody bodyB:head.physicsBody anchor:head.position];
[self.physicsWorld addJoint:pin];
Run Code Online (Sandbox Code Playgroud)
}
https://dl.dropboxusercontent.com/u/62559842/PhysicsTest.zip
谢谢.
当我移植使用SpriteKit到iPad的iPhone应用程序时,我已经能够使用iPhone 5到iPad屏幕的高度比来缩放所有屏幕元素和字体大小.
一切都看起来是成比例的,除了物理,因为有更多的区域.
所以问题是,如何使用该高度比率将物理学与屏幕一起缩放?
也许改变所有节点的密度或质量?我怎么做,数学上使用比率,这是完美的?
在创建具有自定义形状的Sprite Kit物理主体时,我有一个奇怪的内存泄漏.这就是我的实现的样子:
CGFloat offsetX = self.frame.size.width * self.anchorPoint.x;
CGFloat offsetY = self.frame.size.height * self.anchorPoint.y;
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 4 - offsetX, 3 - offsetY);
CGPathAddLineToPoint(path, NULL, 66 - offsetX, 3 - offsetY);
CGPathAddLineToPoint(path, NULL, 35 - offsetX, 57 - offsetY);
CGPathCloseSubpath(path);
self.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:path];
CGPathRelease(path);
Run Code Online (Sandbox Code Playgroud)
内部SKSpriteNode
方法一切都在进行中.在创建这样的实体后,Instruments会告诉我几个内存泄漏:
Leaked object:
Malloc 32 Bytes
Size:
32 Bytes
Responsible Library:
PhysicsKit
Responsible Frame:
std::__1::__split_buffer<PKPoint, std::__1::allocator<PKPoint>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<PKPoint>&)
Run Code Online (Sandbox Code Playgroud)
这CGPathRelease(path);
条线是必要的 - 没有它我会得到更多的内存泄漏,CGPath
这是可以理解的.当我使用此实现时(用于测试目的):
CGFloat radius = …
Run Code Online (Sandbox Code Playgroud) memory-leaks objective-c game-physics sprite-kit skphysicsbody
我使用SKNode的xScale属性来水平翻转我的精灵.现在,在将iOS更新到版本7.1之后,水平翻转会导致我的对象沉入地下.(见下面的动画).只有xScale属性才会出现此问题.垂直翻转工作正常.
// Init
{
SKSpriteNode* ground = [SKSpriteNode spriteNodeWithColor:[UIColor blackColor] size:CGSizeMake(winSize.width, 150)];
ground.position = CGPointMake(winSize.width/2, ground.size.height/2);
ground.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:ground.size center:CGPointZero];
ground.physicsBody.dynamic = NO;
ground.physicsBody.categoryBitMask = 0x01;
ground.physicsBody.collisionBitMask = 0x02;
ground.physicsBody.contactTestBitMask = 0x02;
[self.world addChild:ground];
SKSpriteNode* turtle = [SKSpriteNode spriteNodeWithImageNamed:@"turtle.png"];
turtle.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:turtle.size.width/2];
turtle.physicsBody.categoryBitMask = 0x02;
turtle.physicsBody.collisionBitMask = 0x01;
turtle.physicsBody.contactTestBitMask = 0x01;
turtle.position = CGPointMake(winSize.width/2, winSize.height/2);
[self.world addChild:turtle];
self.turtle = turtle;
}
// Somewhere else
{
self.turtle.xScale *= -1;
}
Run Code Online (Sandbox Code Playgroud)
skphysicsbody ×10
sprite-kit ×10
ios ×4
objective-c ×4
game-physics ×2
physics ×2
swift ×2
ios7 ×1
ios7.1 ×1
ipad ×1
iphone ×1
memory-leaks ×1
xscale ×1