2016-03-29 18 views
0

Ich versuche, eine einfache App zu machen, wo, wenn Sie auf den Bildschirm tippen, eine Box von schwebend auf die Schwerkraft beeinflusst wird. Ich kann keinen Weg finden, die Box in der Luft schweben zu lassen.Anti-Schwerkraft-Physik in SceneKit

Dieser Code kümmert sich um die Hälfte des Problems:

boxNode.physicsBody = [SCNPhysicsBody dynamicBody]; 

Dies bewirkt, dass die Box aus der Luft fallen zu lassen und einen Boden schlug ich erstellt. Gibt es etwas in SCNPhysicsBody, das das Gegenteil davon tun würde? Sagen Sie vielleicht, dass Objekte schweben oder einfach zur Decke segeln?

Außerdem habe ich diesen Code geschrieben:

- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer { 

    if (myBool == false) { 
     myBool = true; 
     NSLog(@"true"); 
    } else { 
     myBool = false; 
     NSLog(@"false"); 
    } 


} 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

// touch recognizer 
    UITapGestureRecognizer *screenTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]; 
    [self.view addGestureRecognizer:screenTap]; 

    // create box 
    SCNBox *myBox = [SCNBox boxWithWidth:1.0 height:1.0 length:1.0 chamferRadius:0.1]; 
    SCNNode *boxNode = [SCNNode nodeWithGeometry:myBox]; 
    boxNode.position = SCNVector3Make(0.0, 0.0, 4.0); 
    [myScene.rootNode addChildNode:boxNode]; 



    while (myBool == true) { 

    boxNode.physicsBody = [SCNPhysicsBody dynamicBody]; 

    } 


} 

Ich bin nicht sicher, warum die while-Schleife allerdings nicht funktioniert. Ich dachte, es würde erkennen, dass myBool geändert wurde und ändern Sie die Physik des BoxNode, aber es tut es nicht.

Antwort

1

Die Methode viewDidLoad wird nur einmal aufgerufen, wenn die Ansicht geladen wird. Wenn Ihre App mit myBool = false initialisiert wird, wird die while-Schleife nie ausgeführt. In diesem Fall jedoch, wenn myBool wahr ist, würde die while-Schleife niemals aufhören zu arbeiten, was das Laden der Ansicht verhindert und somit verhindert, dass der Benutzer auf die Ansicht tippt, um Ihre Gestenerkennung auszulösen.

Ich habe das unten nicht getestet, aber es sollte Ihnen zumindest einen Ausgangspunkt geben. Die Szene wird in der viewDidLoad nach Ihrem Code erstellt, wichtig ist die physicsWorld der Szene hat seine Schwerkraft auf Null gesetzt (das ist -9.8 standardmäßig). Später, wenn der Benutzer auf die Ansicht tippt, setzen wir die Schwerkraft auf ihren Standardwert zurück, was dazu führen sollte, dass die Box fällt.

Die Header-Datei GameViewController.h

#import <UIKit/UIKit.h> 
#import <SceneKit/SceneKit.h> 

@interface GameViewController : UIViewController { 
    SCNScene *myScene; 
} 

@end 

und GameViewController.m

#import "GameViewController.h" 

@implementation GameViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // create a new scene 
    myScene = [SCNScene scene]; 

    // create box 
    SCNBox *myBox = [SCNBox boxWithWidth:1.0 height:1.0 length:1.0 chamferRadius:0.1]; 
    SCNNode *boxNode = [SCNNode nodeWithGeometry:myBox]; 
    boxNode.position = SCNVector3Make(0.0, 0.0, 4.0); 
    [myScene.rootNode addChildNode:boxNode]; 

    boxNode.physicsBody = [SCNPhysicsBody dynamicBody]; 

    //'disable' scene gravity 
    myScene.physicsWorld.gravity = SCNVector3Make(0, 0, 0); 

    SCNView *scnView = (SCNView *)self.view; 
    scnView.scene = myScene; 
    scnView.allowsCameraControl = YES; 
    scnView.autoenablesDefaultLighting = YES; 
    scnView.backgroundColor = [UIColor blackColor]; 

    // add a tap gesture recognizer 
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]; 
    NSMutableArray *gestureRecognizers = [NSMutableArray array]; 
    [gestureRecognizers addObject:tapGesture]; 
    [gestureRecognizers addObjectsFromArray:scnView.gestureRecognizers]; 
    scnView.gestureRecognizers = gestureRecognizers; 
} 

- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer { 
    myScene.physicsWorld.gravity = SCNVector3Make(0, -9.8, 0); 
} 

@end 
+0

Thank you! Das hilft definitiv. Auf myScene kann nicht über handleSingleTap zugegriffen werden: obwohl myScene in der viewDidLoad deklariert ist. Kann ich es irgendwo anders deklarieren? Entschuldigung, ziemlich neu hier. –

+0

Ach ja, tut mir leid, ich nahm an, du hättest schon 'myScene' als Instanzvariable deklariert. Aktualisiere das obige ... mein Code-Snippet brauchte sowieso ein bisschen Arbeit. – lock

+0

Hinweis: In der bearbeiteten Version deklarieren wir 'myScene' als Instanzvariable in der Klassenschnittstellendefinition. Dann ordnen wir in der 'viewDidLoad'-Methode unsere Szene dieser Variablen zu, so dass sie für alle Funktionen innerhalb der Klasse (und auch anderer Klassen) zugänglich ist. FWIW Wenn ich gerade erst angefangen hätte, würde ich wahrscheinlich direkt zu Swift gehen. – lock