2

我正在尝试制作一个游戏,其中我有一些 SKSpriteNodes 并且用户可以用手指移动来击打它们,我正在使用苹果的新 Sprite Kit。

为此,我尝试了一个技巧 - 将 Sprite - “X”(SKSpriteNode)放置在手指所在的位置,当用户移动手指时 - 更改此 X sprite 的位置,

问题是它只会在它不运动的情况下撞击其他精灵,我希望其他精灵对移动手指的当前速度做出响应 - 手指移动越快 - 碰撞应该越强。

你能帮帮我吗?

  • 虽然我觉得这个技巧不是正确的方法,但我也在发布代码。

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        if([touches count]==1)
        {
            self.X= [[SKSpriteNode alloc]initWithImageNamed:@"X"];
            self.X.name= @"X";
            UITouch *t= touches.allObjects[0];          
    
            self.X.position= [t locationInNode:self.GameNode];
            self.X.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:20];
            self.X.physicsBody.dynamic=YES; // Tried NO too...
            self.X.zPosition=1;
    
            [self.GameNode addChild:self.X];
        }
    }
    -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {
        UITouch *t = touches.allObjects[0];
        self.X.position = [t locationInNode:self.GameNode];
    }
    -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [self.X removeFromParent];
    }
    
4

3 回答 3

8

经过搜索和大量实验,我终于有了答案!

解决方案的第一步由AyatollahAndy提供- 找到影响点:

SKNode *node = [self nodeAtPoint:location];

这一行获取我们在指定位置命中的节点,如果它返回 nil 我们没有命中任何东西。

其次,我们要“击中”对象,因此我们需要 ApplyImpulse:

[node.physicsBody applyImpulse:CGVectorMake(thrustV.x, thrustV.y) atPoint:location];

在这里你可以看到我用我在撞击点创建的一些矢量应用了脉冲,就是这样 - 非常简单,我希望这对其他人有帮助。

分享是关怀,感谢您花时间阅读我的帖子。

于 2013-10-25T09:21:02.337 回答
0

还没有时间实际运行它,但是这样的事情怎么样:不要像上面描述的那样放置节点 X,而是:

在 touchesBegan 中,跟踪触摸的时间和位置

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];

    //store location of first touch
    self.firstTouch = location;

    //get time
    self.startTouch = [NSDate date];
}

在 touchesMoved 中,检查您是否触摸了任何节点,如果是,则根据触摸的开始和结束位置计算出角度和速度,然后将速度应用于受影响的节点?

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    SKNode *node = [self nodeAtPoint:location];

    //if you've touched one of your nodes
    if ([node.name isEqualToString:@"whateverNode"]) {
     //work out time between touches
     NSTimeInterval timeBetween = [[NSDate date] timeIntervalSinceDate:self.startTouch];

     //work out angle between touches (if you want to send the impacted node in that direction)
     float angle = atan2f (location.y - self.firstTouch.y, location.x - self.firstTouch.y) ;

     //apply to node
     CGFloat thrust = 0.01/timeBetween; 

     CGPoint thrustVector = CGPointMake(thrust*cosf(angle),
               thrust*sinf(angle));
     [node.physicsBody applyTorque:thrustVector];
    }
}

请注意,最后的物理位可能(完全)不正确。

于 2013-10-10T20:43:34.733 回答
0

你可以做这样的事情。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    touchOn=YES;
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self.parent];
    touchPos =location;
    [self.physicsBody setVelocity:CGVectorMake(0, 0)];

}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    touchOn=YES;
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self.parent];
    touchPos =location;
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    touchOn=NO;
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    touchOn=NO;
}
-(void)update:(NSTimeInterval)dt {
    if (touchOn) {
        CGVector vector = CGVectorMake((touchPos.x-self.position.x)/dt, (touchPos.y-self.position.y)/dt);
        self.physicsBody.velocity=vector;
    }
}

子类化一个节点并创建一个名为 update 的方法,该方法接收来自场景的更新以及时间变化。还添加了触摸方法并跟踪当前的触摸位置。

于 2013-11-20T20:56:52.797 回答