我有一个使用自定义SKSpriteNode类添加到场景的精灵。
我想做这个效果:假设我有3个精灵并排。我希望精灵在触摸时或手指触摸它时稍微缩放一下,一旦手指没有接触它,它就应该缩小回原来的大小。
我的意思是:假设用户从左到右滑动一个大手指,从第一个精灵开始,到最后一个精灵结束。当手指滑动时,我希望第一个精灵在手指进入其框架时立即向上扩展。当手指继续向右滑动并到达第二个精灵时,我希望第一个手指检测到手指不在其区域上并缩小到原始大小。与此同时,第二个精灵会向上扩展,因为现在手指在其区域内。在滑动过程中手指离开表面的任何时候,在通过最后一个精灵之后。
我的问题是我想在sprite类中使用逻辑但是当我在sprite的类上实现touchesBegan,touchesMoved等时,它不起作用,因为touchesMoved继续报告手指,即使它不在里面它的区域。
这是我在sprite类中的触摸逻辑:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
SKAction *scaleUp = [SKAction scaleTo:1.2 duration:0.2];
[self runAction:scaleUp];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self];
// CGPoint convertPT = [self convertPoint:touchLocation fromNode:self.parent];
NSLog(@"%@", NSStringFromCGPoint(touchLocation));
// if (CGRectContainsPoint(self.frame, touchLocation)) {
// NSLog(@"this is never fired?");
// }
}
即使手指在图层之外,NSLog行也将始终打印一个位置...
我希望TouchesMoved在手指在精灵之外时停止射击。
我该怎么做?
答案 0 :(得分:1)
我把它放在子类中并取得了很好的效果。
当你从游戏场景类中的rect之外开始时,你仍然需要一些逻辑。
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
SKAction *scaleUp = [SKAction scaleTo:1.2 duration:0.2];
[self runAction:scaleUp withKey:@"action"];
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches) {
UITouch* touch = [touches anyObject];
CGPoint loc = [touch locationInNode:self.parent];
if (![self containsPoint:loc]) {
SKAction *scaleDown = [SKAction scaleTo:1.0 duration:0.1];
[self runAction:scaleDown];
}
else if ([self containsPoint:loc]) {
SKAction *scaleUp = [SKAction scaleTo:1.2 duration:0.1];
[self runAction:scaleUp];
}
}
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self removeActionForKey:@"action"];
SKAction *scaleDown = [SKAction scaleTo:1.0 duration:0.1];
[self runAction:scaleDown];
}
我没有根据自己的喜好运行子类方法,但我确实从主场景中得到了很好的工作 - 一堆if statements
...但是工作 < / p>
// add a ivar to scene enforce one zoom spite at a time, SKSpriteNode *_currentZoomRect;
- (void) addSomeBlocks
{
for (int i = 1; i <= 3; i++) {
SKSpriteNode *rect = [SKSpriteNode spriteNodeWithColor:[UIColor whiteColor] size:CGSizeMake(70, 70)];
rect.position = CGPointMake(100 * i , 160);
rect.name = @"inner";
[self addChild:rect];
}
}
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches) {
UITouch* touch = [touches anyObject];
CGPoint loc = [touch locationInNode:self];
NSArray *nodes = [self nodesAtPoint:loc];
for (SKNode *n in nodes) {
if ([n.name isEqualToString:@"inner"]) {
_currentZoomRect = (SKSpriteNode *) n;
SKAction *scaleUp = [SKAction scaleTo:2.0 duration:0.05];
[n runAction:scaleUp withKey:@"action"];
}
}
}
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches) {
UITouch* touch = [touches anyObject];
CGPoint loc = [touch locationInNode:self];
NSArray *nodes = [self nodesAtPoint:loc];
for (SKNode *n in nodes) {
if ([n.name isEqualToString:@"inner"]) {
if (_currentZoomRect) {
// can only allow one zoom at a time
if (n == _currentZoomRect && !n.hasActions) {
SKAction *scaleUp = [SKAction scaleTo:2.0 duration:0.05];
[n runAction:scaleUp];
}
else if (n != _currentZoomRect) {
SKAction *scaleDown = [SKAction scaleTo:1.0 duration:0.05];
[_currentZoomRect runAction:scaleDown];
SKAction *scaleUp = [SKAction scaleTo:2.0 duration:0.05];
[n runAction:scaleUp];
_currentZoomRect = (SKSpriteNode *) n;
}
}
else {
SKAction *scaleUp = [SKAction scaleTo:2.0 duration:0.05];
[n runAction:scaleUp];
_currentZoomRect = (SKSpriteNode *) n;
}
}
}
if (![nodes count] && _currentZoomRect) {
SKAction *scaleDown = [SKAction scaleTo:1.0 duration:0.05];
[_currentZoomRect runAction:scaleDown];
_currentZoomRect = nil;
}
}
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (_currentZoomRect) {
SKAction *scaleDown = [SKAction scaleTo:1.0 duration:0.05];
[_currentZoomRect runAction:scaleDown];
_currentZoomRect = nil;
}
}