Question

Is there an easy way to do the following?

I want to split a view into 4 via two diagonal lines:

enter image description here

So the upper triangle area will correspond to "up". The other 3 will correspond to "left", "down", "right" respectively.

What would be the easiest or the most efficient way of doing this? I had considered creating 4 triangle shapes and detecting touches inside them, but maybe this will be unnecessary?

Context: For moving a sprite in a map.

Thanks!

Was it helpful?

Solution

After my comment, I wanted to mock up a simple implementation for myself, so, here's a simple full screen joystick that will determine cardinal-like directions based on touch position relative to the center of the screen.

(FullScreenJoystick)

I'm still using cocos2d-iphone 1.1 , so.. I'm not sure if there are any mods necessary for v2

FSJoy.h

#import "cocos2d.h"

// Up, Down, Left, Right - directions
typedef enum
{
    DIR_NONE = 0,
    DIR_UP,
    DIR_LEFT,
    DIR_DOWN,
    DIR_RIGHT
} ULDR;

// UpLeft, UpRight, DownLeft, DownRight - boundaries
typedef enum
{
    UL = 135,
    UR = 45,
    DL = 225,
    DR = 315
} ULDR_BOUNDS;


@interface FSJoy : CCLayer
{
    CGPoint origin;
    float angleCurrent;
    BOOL isActive;
}

@property CGPoint origin;
@property float angleCurrent;
@property BOOL isActive;
@end

FSJoy.m

#import "FSJoy.h"

@implementation FSJoy

@synthesize origin, angleCurrent, isActive;

-(id) init
{
    if( (self = [super init]) )
    {
        self.isTouchEnabled = YES;
        CGSize screenSize = [[CCDirector sharedDirector] winSize];
        angleCurrent = 0.0f;
        origin = ccp(screenSize.width / 2.0f, screenSize.height / 2.0f);
        isActive = NO;
    }
    return self;
}

-(void) registerWithTouchDispatcher
{
    [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:(INT_MIN - 4) swallowsTouches:YES];
}

-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
    CGPoint touchCurrent = [touch locationInView:[touch view]];
    touchCurrent = [[CCDirector sharedDirector] convertToGL:touchCurrent];    
    angleCurrent = [self determineAngleFromPoint:origin toPoint:touchCurrent];
    [self determineDirectionFromAngle: angleCurrent];
    isActive = YES;
    return YES; // full screen controller, so always return YES
}

-(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
    CGPoint touchCurrent = [touch locationInView:[touch view]];
    touchCurrent = [[CCDirector sharedDirector] convertToGL:touchCurrent];
    angleCurrent = [self determineAngleFromPoint:origin toPoint:touchCurrent];
    [self determineDirectionFromAngle: angleCurrent];
}

-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
    isActive = NO;
}

-(void) ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event
{
    [self ccTouchEnded:touch withEvent:event];
}

-(float) determineAngleFromPoint:(CGPoint)from toPoint:(CGPoint)to
{
    float angle = ccpToAngle(ccpSub(to, from));
    if (angle <= 0.0f)
    {
        angle += M_PI * 2.0f;
    }

    angle = CC_RADIANS_TO_DEGREES(angle);

//    NSLog(@"angle is %f", angle);
    return angle;
}

-(ULDR) determineDirectionFromAngle:(float) angle
{
    ULDR dir = DIR_NONE;
    dir = ((angle >= UR) && (angle <= UL)) ? DIR_UP     : dir;
    dir = ((angle >= DL) && (angle <= DR)) ? DIR_DOWN   : dir;
    dir = ((angle >  UL) && (angle <  DL)) ? DIR_LEFT   : dir;
    dir = ((angle >  DR) || (angle <  UR)) ? DIR_RIGHT  : dir;
    NSLog(@"direction is %d", dir);
    return dir;
}

@end

Usage is simply to add the Joystick to the scene/layer:

FSJoyTest.h

#import "cocos2d.h"
@interface FSJoyTest : CCLayer
@end

FSJoyTest.m

#import "FSJoyTest.h"
#import "FSJoy.h"

@implementation FSJoyTest

-(id) init
{
    if( (self=[super init]) )
    {
        [self addChild: [FSJoy node]];
    }
    return self;
}

@end

OTHER TIPS

Just an idea :

Create an image in the size of the view above (don't add it to any view just store it somewhere). The image file will contain the four triangles like you desire but color each triangle with a different color (no gradients ! :))

When you tap the view take the touch location coordinates (convert it to image coordinates if needed) and test the pixel color in the image in that same location. The color will tell you which triangle was pressed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top