2015-01-21 114 views
0

當我更新變量時,我無法獲取要更改的變量。當我觸摸按鈕並且變量「self.hasYawCenterPointBeenSet」在方法內被更新時,但是當「updateCycle」方法回到變量周圍時,「reCenterYaw」方法觸發並未顯示它已被更新。 updateCycle是我的CADisplaylink驅動的方法。我試着將變量更新爲原子,用「_」和「self」作爲它們的實例變量引用它們。不知道發生了什麼事。使用時不更新的變量CADisplayLink

#import "GameViewController.h" 
#import <CoreMotion/CoreMotion.h> 
#import <SpriteKit/SpriteKit.h> 
#import "HUDOverlay.h" 

@interface GameViewController() 
@property (strong, nonatomic) CMMotionManager *motionManager; 
@property (strong, nonatomic) CMAttitude *currentAttitude; 
@property (strong, nonatomic) SCNNode *cameraNode; 
@property (strong, nonatomic) SCNScene *scene; 
@property (nonatomic) float roll; 
@property (nonatomic) float yaw; 
@property (nonatomic) float pitch; 

@property (atomic) float yawCenterPoint; 
@property (atomic) BOOL hasYawCenterPointBeenSet; 

@end 

GameViewController* sharedGameViewController = nil; 


@implementation GameViewController 

+(GameViewController*)sharedController{ 
    if (sharedGameViewController == nil) { 
     sharedGameViewController = [[GameViewController alloc] init]; 
    } 
    return sharedGameViewController; 
} 


- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // create a new scene 
    //SCNScene *scene = [SCNScene sceneNamed:@"art.scnassets/ship.dae"]; 
    _scene = [SCNScene new]; 
    self.hasYawCenterPointBeenSet = NO; 

    // create and add a camera to the scene 
    _cameraNode = [SCNNode node]; 
    _cameraNode.camera = [SCNCamera camera]; 
    [_scene.rootNode addChildNode:_cameraNode]; 

    // place the camera 
    _cameraNode.position = SCNVector3Make(0, 0, 0); 

    // create and add a light to the scene 
    SCNNode *lightNode = [SCNNode node]; 
    lightNode.light = [SCNLight light]; 
    lightNode.light.type = SCNLightTypeOmni; 
    lightNode.position = SCNVector3Make(0, 10, 10); 
    [_scene.rootNode addChildNode:lightNode]; 

    // create and add an ambient light to the scene 
    SCNNode *ambientLightNode = [SCNNode node]; 
    ambientLightNode.light = [SCNLight light]; 
    ambientLightNode.light.type = SCNLightTypeAmbient; 
    ambientLightNode.light.color = [UIColor whiteColor]; 
    [_scene.rootNode addChildNode:ambientLightNode]; 


    // retrieve the SCNView 
    SCNView *scnView = (SCNView *)self.view; 
    scnView.delegate = self; 
    scnView.playing = YES; 


    // set the scene to the view 
    scnView.scene = _scene; 

    scnView.overlaySKScene = [HUDOverlay sceneWithSize:scnView.frame.size]; 
    // allows the user to manipulate the camera 
    scnView.allowsCameraControl = NO; 

    // show statistics such as fps and timing information 
    scnView.showsStatistics = YES; 

    // configure the view 
    scnView.backgroundColor = [UIColor blueColor]; 

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

    SCNNode *sampleNode = [SCNNode new]; 
    SCNPlane *samplePlane = [SCNPlane planeWithWidth:3 height:5]; 
    SCNMaterial *angryFrontMaterial = [SCNMaterial material]; 
    angryFrontMaterial.diffuse.contents = [UIImage imageNamed:@"angryfront110.png"]; 

    sampleNode.geometry = samplePlane; 
    sampleNode.geometry.firstMaterial = angryFrontMaterial; 
    sampleNode.position = SCNVector3Make(0, 0, -10); 

    [_scene.rootNode addChildNode:sampleNode]; 
// SCNAction *moveToCamera = [SCNAction moveTo:SCNVector3Make(0, 0, -10) duration:10]; 
// [sampleNode runAction:moveToCamera]; 


    [self setupRotationGrid]; 
    [self setupMotionCapture]; 

    displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateCycle)]; 
    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
} 

//This is the update loop for the sceneView. When the view updates per frame this is where the logic goes 
-(void)renderer:(id<SCNSceneRenderer>)aRenderer updateAtTime:(NSTimeInterval)time{ 

} 

-(void)updateCycle{ 

    _currentAttitude = _motionManager.deviceMotion.attitude; 
    _roll = _currentAttitude.roll + (.5 * M_PI); 
    _yaw = _currentAttitude.yaw; 
    _pitch = _currentAttitude.pitch; 

    _cameraNode.eulerAngles = SCNVector3Make(-_roll, _yaw, _pitch); 
    //NSLog(@"yawCenterPoint = %d", _hasYawCenterPointBeenSet); 

    if (self.hasYawCenterPointBeenSet == NO) { 
     _yawCenterPoint = _yaw; 
     self.hasYawCenterPointBeenSet = YES; 
     NSLog(@"Yawcenter point set to %f", _yawCenterPoint); 
    } 
    //NSLog(@"Roll: %f Yaw: %f Pitch: %f", _roll, _yaw, _pitch); 

} 

-(void)setupRotationGrid { 
    double radius = 30; 
    double numberOfItems = 8; 
    SCNGeometry *geometry = [SCNBox boxWithWidth:4.5 height:8 length:3.25 chamferRadius:0.5]; 

    double x = 0.0; 
    double z = radius; 
    double theta = (M_PI)/(numberOfItems/2); 
    double incrementalY = (M_PI)/(numberOfItems*2); 

    SCNNode *nodeCollection = [SCNNode node]; 
    nodeCollection.position = SCNVector3Make(0, 4, 0); 

    for (int index = 1; index <= numberOfItems; index++) { 
     x = radius * sin(index*theta); 
     z = radius * cos(index*theta); 
     SCNNode *node = [SCNNode node]; 
     node.geometry = geometry; 
     node.position = SCNVector3Make(x, 0, z); 
     float rotation = incrementalY * index; 
     node.rotation = SCNVector4Make(0, 1, 0, rotation); 
     [nodeCollection addChildNode:node]; 
    } 

    [_scene.rootNode addChildNode:nodeCollection]; 
} 

- (void) handleTap:(UIGestureRecognizer*)gestureRecognize 
{ 
    // retrieve the SCNView 
    SCNView *scnView = (SCNView *)self.view; 

    // check what nodes are tapped 
    CGPoint p = [gestureRecognize locationInView:scnView]; 
    NSArray *hitResults = [scnView hitTest:p options:nil]; 

    // check that we clicked on at least one object 
    if([hitResults count] > 0){ 
     // retrieved the first clicked object 
     SCNHitTestResult *result = [hitResults objectAtIndex:0]; 

     // get its material 
     SCNMaterial *material = result.node.geometry.firstMaterial; 

     // highlight it 
     [SCNTransaction begin]; 
     [SCNTransaction setAnimationDuration:0.5]; 

     // on completion - unhighlight 
     [SCNTransaction setCompletionBlock:^{ 
      [SCNTransaction begin]; 
      [SCNTransaction setAnimationDuration:0.5]; 

      material.emission.contents = [UIColor blackColor]; 

      [SCNTransaction commit]; 
     }]; 

     material.emission.contents = [UIColor redColor]; 

     [SCNTransaction commit]; 
    } 
} 

-(void)reCenterYaw{ 
    self.hasYawCenterPointBeenSet = NO; 
    NSLog(@"Tapped recenter"); 
} 


-(void)setupMotionCapture{ 

    _motionManager = [[CMMotionManager alloc] init]; 
    _motionManager.deviceMotionUpdateInterval = 1.0/60.0; 
    if (_motionManager.isDeviceMotionAvailable) { 
     [_motionManager startDeviceMotionUpdates]; 
     _currentAttitude = _motionManager.deviceMotion.attitude; 
    } 

// if (!_hasYawCenterPointBeenSet) { 
//  _yawCenterPoint = _currentAttitude.yaw; 
//  _hasYawCenterPointBeenSet = YES; 
// } 



} 


- (BOOL)shouldAutorotate 
{ 
    return YES; 
} 

- (BOOL)prefersStatusBarHidden { 
    return YES; 
} 

- (NSUInteger)supportedInterfaceOrientations 
{ 
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { 
     return UIInterfaceOrientationMaskLandscape; 
    } else { 
     return UIInterfaceOrientationMaskAll; 
    } 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Release any cached data, images, etc that aren't in use. 
} 



@end 

回答

1

我想通了。我創建了一個單例,以便可以從sprite套件hud類引用視圖控制器。問題是,我從故事板加載視圖控制器,然後從hud類的init中,我實例化一個新的視圖控制器,因爲「sharedViewController」從未由故事板加載啓動。所以,我只是在hud類上創建了一個視圖控制器屬性,並將其從視圖控制器的負載代碼中設置爲self。