SpriteKit Objective-C: programming directional pad controls

江枫思渺然 提交于 2019-12-25 18:16:49

问题


so let me get this straight: what I'm trying to implement is controls for my SpriteKit game in the form of a directional pad. I want it to work the way so that you, for instance, can hold a button, then slide your finger to another button, so that the first button gets released, and the other button gets pressed (just like it would on a physical game controller, for example). I saw that this was implemented on many existing games (Carmageddon, Minecraft PE), so it is possible for sure.

What I've been trying to use is simple touchesBegan and touchesEnded, but the issue here is that once you move the finger away from the first button to the second, the second button WILL NOT get pressed, while the first one keeps it's "pressed" status until you stop touching the screen. What I also tried to use is touchesMoved to detect whether or not touch location has changed, but it caused lots of various bugs.

Please push me in the right direction. I hope what I requested is possible (I'm using objective-c).


回答1:


It's really only about setting a true/false state for your controls. Just as you would with a real controller. You would first check for a contact touch in the touchesBegan method and set the 4 controller BOOL variables accordingly. In the did touchesMoved method, the user's touch is again checked for making contact with any of the controller nodes and the BOOL variables are set accordingly.

In your update method you can then check the state of the 4 BOOL variables and execute your code accordingly.

(I used landscape orientation for the code below)

#import "GameScene.h"

@implementation GameScene {

    SKSpriteNode *node0;
    SKSpriteNode *node1;
    SKSpriteNode *node2;
    SKSpriteNode *node3;

    BOOL node0touch;
    BOOL node1touch;
    BOOL node2touch;
    BOOL node3touch;
}

-(void)didMoveToView:(SKView *)view {
    self.backgroundColor = [SKColor blackColor];

    node0 = [SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(50, 50)];
    node0.name = @"node0";
    node0.position = CGPointMake(200, 200);
    [self addChild:node0];

    node1 = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(50, 50)];
    node1.name = @"node1";
    node1.position = CGPointMake(200, 400);
    [self addChild:node1];

    node2 = [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:CGSizeMake(50, 50)];
    node2.name = @"node2";
    node2.position = CGPointMake(100, 300);
    [self addChild:node2];

    node3 = [SKSpriteNode spriteNodeWithColor:[SKColor grayColor] size:CGSizeMake(50, 50)];
    node3.name = @"node3";
    node3.position = CGPointMake(300, 300);
    [self addChild:node3]; 
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    for (UITouch *touch in touches) {
        CGPoint touchLocation = [touch locationInNode:self];

        SKNode *node = [self nodeAtPoint:touchLocation];
        if(node.name != nil) {
            if([node.name isEqualToString:@"node0"]) {
                node0touch = true;
                node1touch = false;
                node2touch = false;
                node3touch = false;
            }
            if([node.name isEqualToString:@"node1"]) {
                node0touch = false;
                node1touch = true;
                node2touch = false;
                node3touch = false;
            }
            if([node.name isEqualToString:@"node2"]) {
                node0touch = false;
                node1touch = false;
                node2touch = true;
                node3touch = false;
            }
            if([node.name isEqualToString:@"node3"]) {
                node0touch = false;
                node1touch = false;
                node2touch = false;
                node3touch = true;
            }
        } else {
            node0touch = false;
            node1touch = false;
            node2touch = false;
            node3touch = false;
        }
    }
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    for (UITouch *touch in touches) {
        CGPoint touchLocation = [touch locationInNode:self];

        SKNode *node = [self nodeAtPoint:touchLocation];
        if(node.name != nil) {
            if([node.name isEqualToString:@"node0"]) {
                node0touch = true;
                node1touch = false;
                node2touch = false;
                node3touch = false;
            }
            if([node.name isEqualToString:@"node1"]) {
                node0touch = false;
                node1touch = true;
                node2touch = false;
                node3touch = false;
            }
            if([node.name isEqualToString:@"node2"]) {
                node0touch = false;
                node1touch = false;
                node2touch = true;
                node3touch = false;
            }
            if([node.name isEqualToString:@"node3"]) {
                node0touch = false;
                node1touch = false;
                node2touch = false;
                node3touch = true;
            }
        } else {
            node0touch = false;
            node1touch = false;
            node2touch = false;
            node3touch = false;
        }
    }
}


来源:https://stackoverflow.com/questions/29212397/spritekit-objective-c-programming-directional-pad-controls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!