2014-10-21 3 views
4

Я пытаюсь реализовать простую категорию для SKPhysicsBody, которая позволит мне применить «идеальное подпрыгивание» к физическому телу.SpriteKit Weird 'PKPhysicsBody' Crash

Что это будет просто сделать, это когда perfectBouncing = YES произойдет следующее:

restitution = 1.0

linearDamping = 0.0

friction = 0.0

Однако, когда я пытаюсь использовать мою реализацию, как показано ниже, я получить странный крах, рассказывающий мне, что я не могу отправить perfectBouncing сообщениям PKPhysicsBody, который является классом, который я когда-либо упоминаются и не существуют в моем проекте или, насколько мне известно, в SDK SpriteKit.

И да, страна импортируется.

Краш Сообщение

-[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 
) 

Категория Реализация

#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 

Пример использования

hero = [[SKSpriteNode alloc] initWithColor:[SKColor blueColor] size:CGSizeMake(heroRadius*2, heroRadius*2)]; 

hero.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:heroRadius]; 
hero.physicsBody.perfectBouncing = YES; 

Любой я деас, что это неуловимо PKPhysicsBody и почему у меня этот крах?

ответ

4

Внутренний комплект Sprite имеет пользовательские классы для многих публичных классов. В этом случае SKPhysicsBody фактически создает экземпляр внутреннего класса PKPhysicsBody. Предположительно, PK означает «Комплект физики».

Вот почему ваша категория не будет работать, и если я помню правильно литья не будет делать трюк либо потому, что SKPhysicsBody не наследуется от PKPhysicsBody, но в случае, если я ошибаюсь, вы можете попробовать это так:

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

В любом случае, категория не нужна здесь. Вместо этого вы можете добиться такого же эффекта с помощью класса-помощника и классных методов, например:

@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 
+0

Ах, спасибо, и да, вы правы в том, что кастинг не работает. Фактически, я только что обнаружил, что использование категории «SKSpriteNode» для достижения одной цели работает, хотя это будет раздражать меня, поскольку не все узлы спрайтов используют физику. Я нахожу помощников немного неуклюжими, когда дело доходит до использования, я, вероятно, в конечном итоге воспользуюсь функцией для этого. Тем не менее, спасибо за ваш быстрый и лаконичный ответ! – Hamish

Смежные вопросы