SceneKit中的反重力物理

时间:2016-03-29 00:10:43

标签: ios objective-c cocoa-touch scenekit scnnode

我正在尝试创建一个简单的应用程序,如果你点击屏幕,一个盒子从浮动切换到受重力影响。我似乎找不到让盒子漂浮在空中的方法。

此代码解决了问题的一半:

    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 个答案:

答案 0 :(得分: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