2013-09-06 4 views
4

Есть ли простой способ сделать следующее?Разделение вида на четыре треугольные области и обнаружение касаний (iOS и Cocos2d)

Я хочу разделить представление в 4 с помощью двух диагональных линий:

enter image description here

Так верхняя область треугольника будет соответствовать «вверх». Остальные 3 будут соответствовать «слева», «вниз», «справа» соответственно.

Какой был бы самый простой или эффективный способ сделать это? Я подумал о создании четырех треугольных фигур и обнаружении прикосновений внутри них, но, возможно, это будет лишним?

Контекст: Для перемещения спрайта на карте.

Спасибо!

+0

К сожалению, вы можете» t создать треугольные виды. Вы можете использовать CAShapeLayer или рисовать треугольники с помощью основных графических функций, а затем вычислять, в каком треугольнике прикосновение падает. –

+3

Первой мыслью было просто вычислить угол от центральной точки до касания и использовать это, чтобы определить, в каком направлении они хотели идти.45-135 означает, и т. Д. – Mark

+0

Спасибо, Марк, я закончил тем, что использовал ваш метод! Очень просто и требуется всего несколько строк кода. – Michael

ответ

1

После моего комментария я хотел создать для себя простую реализацию, так что вот простой полноэкранный джойстик, который определит кардинальные направления на основе касания по отношению к центру экрана.

(FullScreenJoystick)

Я до сих пор с помощью cocos2d-Iphone 1.1, так что .. Я не уверен, если есть какой-либо моды, необходимые для 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 

Использование просто добавить джойстик сцены/слой:

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 
+0

Когда я печатаю направление, оно дает мне только 1 и 4 направления. Есть идеи? – lazyCoder

+0

мой вид ширина 200 и высота 200 – lazyCoder

0

Просто идея:

Создание образа в размере зрения выше (не добавляйте его в любом виде просто хранить его где-нибудь). Файл изображения будет содержать четыре треугольника, как вы хотите, но покрасьте каждый треугольник с другим цветом (без градиентов! :))

Когда вы нажимаете на вид, берете координаты места касания (при необходимости конвертируйте их в координаты изображения) и проверьте цвет пикселя на изображении в том же месте. Цвет скажет вам, какой треугольник был нажат.