Sprite kit 触摸*事件-SKScene vs.ViewController

Sprite kit 触摸*事件-SKScene vs.ViewController,sprite-kit,skscene,Sprite Kit,Skscene,我有一个经典的SKScene,其中有一些按钮都是通过编程方式制作的,还有该场景的ViewController。应在何处处理事件-在SKScene中或在ViewController中。我需要切换到另一个场景和另一个视图控制器时,通过按钮序列触摸不同的按钮。当我在视图控制器中处理触摸事件时,它为SKNode touched返回nil。以下是我在视图中的代码控制器场景是其属性: -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)even

我有一个经典的SKScene,其中有一些按钮都是通过编程方式制作的,还有该场景的ViewController。应在何处处理事件-在SKScene中或在ViewController中。我需要切换到另一个场景和另一个视图控制器时,通过按钮序列触摸不同的按钮。当我在视图控制器中处理触摸事件时,它为SKNode touched返回nil。以下是我在视图中的代码控制器场景是其属性:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   UITouch *touch = [touches anyObject];
   CGPoint location = [touch locationInNode:self.scene];
   SKNode *node = [self.scene nodeAtPoint:location];
   if ([node.name  isEqual: @"campaign"]) {
       CampaignViewController *levelViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"CampaignScene"];
       [self.navigationController pushViewController:levelViewController animated:NO];
   }
}

感谢您的解释。

在ViewController中实现触摸代理可能无法获取节点,因为正是SKScene管理这些节点。因此,为了能够使用nodeAtPoint:,您需要在场景本身中实现触摸代理

现在,您还需要一种方式让SKScene与UIViewController通信,并传递将触发segues或其他方法的消息。为此,您可以使用Delegation或NSNotificationCenter,其实现如本文所示

在实现了答案中的任一选项后,您的代码应如下所示:

//In ViewController.m

-(void) presentCampaignVieController
{
     CampaignViewController *levelViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"CampaignScene"];
     [self.navigationController pushViewController:levelViewController animated:NO];
}

//In SKScene.m (Using Delegation)

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   UITouch *touch = [touches anyObject];
   CGPoint location = [touch locationInNode:self.scene];
   SKNode *node = [self.scene nodeAtPoint:location];
   if ([node.name  isEqual: @"campaign"]) {
       [self.delegate presentCampaignVieController];
   }
}
要使用NSNotificationCenter在viewController中调用相同的方法,首先必须添加一个观察者:

//ViewController.m, under viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(presentCampaignVieController) name:@"gotoCampaign" object:nil];

//In SKScene.m (Using NSNotificationCenter)
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   UITouch *touch = [touches anyObject];
   CGPoint location = [touch locationInNode:self.scene];
   SKNode *node = [self.scene nodeAtPoint:location];
   if ([node.name  isEqual: @"campaign"])
   {
       [[NSNotificationCenter defaultCenter] postNotificationName:@"gotoCampaign" object:nil];
   }
}

在ViewController中实现触摸代理可能无法获得节点,因为正是SKScene管理这些节点。因此,为了能够使用nodeAtPoint:,您需要在场景本身中实现触摸代理

现在,您还需要一种方式让SKScene与UIViewController通信,并传递将触发segues或其他方法的消息。为此,您可以使用Delegation或NSNotificationCenter,其实现如本文所示

在实现了答案中的任一选项后,您的代码应如下所示:

//In ViewController.m

-(void) presentCampaignVieController
{
     CampaignViewController *levelViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"CampaignScene"];
     [self.navigationController pushViewController:levelViewController animated:NO];
}

//In SKScene.m (Using Delegation)

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   UITouch *touch = [touches anyObject];
   CGPoint location = [touch locationInNode:self.scene];
   SKNode *node = [self.scene nodeAtPoint:location];
   if ([node.name  isEqual: @"campaign"]) {
       [self.delegate presentCampaignVieController];
   }
}
要使用NSNotificationCenter在viewController中调用相同的方法,首先必须添加一个观察者:

//ViewController.m, under viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(presentCampaignVieController) name:@"gotoCampaign" object:nil];

//In SKScene.m (Using NSNotificationCenter)
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   UITouch *touch = [touches anyObject];
   CGPoint location = [touch locationInNode:self.scene];
   SKNode *node = [self.scene nodeAtPoint:location];
   if ([node.name  isEqual: @"campaign"])
   {
       [[NSNotificationCenter defaultCenter] postNotificationName:@"gotoCampaign" object:nil];
   }
}