SpriteKit Weird 'PKPhysicsBody' Crash

I am trying to implement a simple category for SKPhysicsBody that will allow me to apply “perfect bounce” to my physical body.

What this will do when perfectBouncing = YES following happens:

restitution = 1.0

linearDamping = 0.0

friction = 0.0

However, when I try to use my implementation as shown below, I get a weird crash telling me that I cannot send PKPhysicsBody messages to PKPhysicsBody , which is a class that I never access, t in my project or, as far as I known in the SpriteKit SDK.

And yes, catagory is imported.

Alarm message

 -[PKPhysicsBody setPerfectBouncing:]: unrecognized selector sent to instance 0x7fa828f84610 *** First throw call stack: ( 0 CoreFoundation 0x000000010882b3f5 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x0000000107dbfbb7 objc_exception_throw + 45 2 CoreFoundation 0x000000010883250d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205 3 CoreFoundation 0x000000010878a7fc ___forwarding___ + 988 4 CoreFoundation 0x000000010878a398 _CF_forwarding_prep_0 + 120 5 Squash The Dot 0x000000010785662c -[gameNode viewDidAnimateIn] + 1116 6 Squash The Dot 0x000000010783e709 -[lzyViewHandler initViewChild:] + 3305 7 Squash The Dot 0x000000010783d93d -[lzyViewHandler initViewChildren:] + 573 8 Squash The Dot 0x000000010785d3e0 __28-[splashVC viewDidAnimateIn]_block_invoke + 256 9 SpriteKit 0x000000010933837e _ZN9SKCAction25didFinishWithTargetAtTimeEP9SKCSprited + 44 10 SpriteKit 0x0000000109399638 _ZN9SKCSprite6updateEd + 170 11 SpriteKit 0x0000000109352dd4 -[SKScene _update:] + 119 12 SpriteKit 0x000000010936d299 -[SKView(Private) _update:] + 563 13 SpriteKit 0x000000010936ac2f -[SKView renderCallback:] + 829 14 SpriteKit 0x0000000109367cec __29-[SKView setUpRenderCallback]_block_invoke + 54 15 SpriteKit 0x0000000109394744 -[SKDisplayLink _callbackForNextFrame:] + 256 16 QuartzCore 0x00000001091f88f7 _ZN2CA7Display15DisplayLinkItem8dispatchEv + 37 17 QuartzCore 0x00000001091f87bf _ZN2CA7Display11DisplayLink14dispatch_itemsEyyy + 315 18 CoreFoundation 0x00000001087934e4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20 19 CoreFoundation 0x00000001087930a5 __CFRunLoopDoTimer + 1045 20 CoreFoundation 0x00000001087563dd __CFRunLoopRun + 1901 21 CoreFoundation 0x0000000108755a06 CFRunLoopRunSpecific + 470 22 GraphicsServices 0x000000010be319f0 GSEventRunModal + 161 23 UIKit 0x000000010953f550 UIApplicationMain + 1282 24 Squash The Dot 0x00000001078550a3 main + 115 25 libdyld.dylib 0x000000010b6cb145 start + 1 ) 

Category Implementation

 #import <SpriteKit/SpriteKit.h> @interface SKPhysicsBody (lzySKPhysics) // Enables perfect boucing by setting friction = 0, linearDamping = 0 and restitution = 1. @property (nonatomic) BOOL perfectBouncing; @end @implementation SKPhysicsBody (lzySKPhysics) -(BOOL) perfectBouncing { return (self.restitution == 1 && self.linearDamping == 0 && self.friction == 0); } -(void) setPerfectBouncing:(BOOL)perfectBouncing { self.restitution = perfectBouncing; self.linearDamping = !perfectBouncing; self.friction = !perfectBouncing; } @end 

Usage example

 hero = [[SKSpriteNode alloc] initWithColor:[SKColor blueColor] size:CGSizeMake(heroRadius*2, heroRadius*2)]; hero.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:heroRadius]; hero.physicsBody.perfectBouncing = YES; 

Any ideas what the elusive PKPhysicsBody is and why I came across this crash?

+5
source share
1 answer

Inside, the Sprite Kit has custom classes for many public classes. In this case, SKPhysicsBody actually creates an instance of the PKPhysicsBody inner class. PK supposedly means “physical kit”.

That is why your category will not work, and if I remember correctly, casting will not do the trick either because SKPhysicsBody is not inherited from PKPhysicsBody, but in case I am mistaken, you can try it like this:

 ((SKPhysicsBody)hero.physicsBody).perfectBouncing = YES; 

In any case, the category is not needed here. Instead, you can achieve the same effect using the helper class and class methods, for example:

 @implementation SKPhysicsHelper +(BOOL) perfectBouncingWithBody:(SKPhysicsBody*)body { return (body.restitution == 1 && body.linearDamping == 0 && body.friction == 0); } +(void) setPerfectBouncing:(BOOL)perfectBouncing body:(SKPhysicsBody*)body { body.restitution = perfectBouncing; body.linearDamping = !perfectBouncing; body.friction = !perfectBouncing; } @end 
+4
source

Source: https://habr.com/ru/post/1205209/


All Articles