【问题标题】:Splitting a view into 4 triangular areas and detecting touches (iOS and Cocos2d)将视图拆分为 4 个三角形区域并检测触摸(iOS 和 Cocos2d)
【发布时间】:2013-09-06 22:46:50
【问题描述】:

有没有简单的方法来做以下事情?

我想通过两条对角线将一个视图分成 4 个:

所以上面的三角形区域将对应“向上”。 其他3个分别对应“左”、“下”、“右”。

最简单或最有效的方法是什么? 我曾考虑过创建 4 个三角形并检测其中的触摸,但也许这没有必要?

上下文:用于在地图中移动精灵。

谢谢!

【问题讨论】:

  • 很遗憾,您无法创建三角形视图。您可以使用 CAShapeLayer,或者使用核心图形函数绘制三角形,然后计算触摸落在哪个三角形中。
  • 首先想到的是只计算从中心点到触摸点的角度,并用它来确定他们想要去的方向。 45-135 表示向上等
  • 谢谢马克,我最终使用了你的方法!非常简单,只需要几行代码。

标签: ios objective-c cocoa cocos2d-iphone touches


【解决方案1】:

在我发表评论之后,我想为自己模拟一个简单的实现,所以,这里有一个简单的全屏操纵杆,它将根据 相对于屏幕中心的触摸位置。

(全屏操纵杆)

我还在用 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

【讨论】:

  • 当我打印方向时,它只给我 1 和 4 个方向。有什么想法吗?
  • 我的视图宽度是200,高度是200
【解决方案2】:

只是一个想法:

创建一个与上面视图大小相同的图像(不要将其添加到任何视图中,只需将其存储在某处即可)。图像文件将包含您想要的四个三角形,但用不同的颜色为每个三角形着色(没有渐变!:))

当您点击视图时,获取触摸位置坐标(如果需要,将其转换为图像坐标)并在同一位置测试图像中的像素颜色。颜色会告诉你按下了哪个三角形。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    • 2011-08-03
    相关资源
    最近更新 更多