2016-03-29 43 views
0

我正在尝试制作一个简单的应用程序,如果您点击屏幕,则会将一个框从浮动状态切换到受重力影响。我似乎无法找到使盒子在空中漂浮的方法。SceneKit中的反重力物理学

这个代码在这里需要半照顾的问题:

boxNode.physicsBody = [SCNPhysicsBody dynamicBody]; 

这将导致框砸出来的空气,撞上了地面,我创建。 SCNPhysicsBody中有没有什么可以做与此相反的事情?也许是说,导致物体漂浮或只是朝着天花板航行?

而且,我已经写了这个代码:

- (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]; 

    } 


} 

我不知道为什么while循环没有工作,虽然。我认为它会检测到myBool已经改变并改变了boxNode的物理,但它不会。

回答

1

viewDidLoad方法仅在视图加载时调用一次。如果您的应用使用myBool = false进行初始化,那么while循环将永远不会运行。然而,在这种情况下,如果myBool为真,则while循环永远不会停止执行,从而阻止加载视图,并因此阻止用户点击视图以触发您的手势识别器。

我还没有测试下面,但它应该至少给你一个出发点。场景根据您的代码在viewDidLoad中创建,重要的是场景的physicsWorld将其重力设置为零(默认情况下为-9.8)。稍后当用户点击视图时,我们将重力重置为其默认值,这会导致框落下。

头文件GameViewController.h

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

@interface GameViewController : UIViewController { 
    SCNScene *myScene; 
} 

@end 

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

谢谢!这绝对有帮助。不能从handleSingleTap访问myScene:尽管myScene是在viewDidLoad中声明的。我可以在别的地方宣布吗?对不起,这里很新。 –

+0

啊,是的,对不起,我只是假设你已经把'myScene'声明为一个实例变量。将更新以上...无论如何,我的代码片段需要一点工作。 – lock

+0

注意:在编辑的版本中,我们在类接口定义中声明'myScene'作为实例变量。然后在'viewDidLoad'方法中,我们将场景赋给这个变量,使其可以访问类中的所有函数(以及其他类)。 FWIW如果我刚开始,我可能会直奔Swift。 – lock