2012-01-05 2 views
1

Я пытался нарисовать линию спрайта между двумя точками, сделанными спрайтами с событиями мыши на Xcode.Нарисуйте линию Sprite между двумя точками, сделанными Sprites в Cocos2d

Я следовал инструкциям, приведенным на форуме в этой ссылке: cocos2d forums

Но когда я запускаю код, я получаю линию, идущую весь путь тренажера. именно так.

snapshot1

Линия должна остановить второй спрайт мыши сгенерированный код, но это не так и продолжает идти весь путь.

My Scene - это что-то вроде этого.

Мой .h класс

#import <Foundation/Foundation.h> 
#import "cocos2d.h" 
#import "Constants.h" 
#import "SceneManager.h" 


@interface EscenaInfo : CCLayer{ 
    CGPoint lastTouchPoint;   
    CCSprite * background; 
} 

@property (nonatomic, assign) BOOL iPad; 

@end 

Мой .mm

#import "EscenaInfo.h" 

@implementation EscenaInfo 
@synthesize iPad; 


- (void)onBack: (id) sender { 
    /* 
    This is where you choose where clicking 'back' sends you. 
    */ 
    [SceneManager goMenuPrincipal]; 
} 

- (void)addBackButton { 

    if (self.iPad) { 
     // Create a menu image button for iPad 
     CCMenuItemImage *goBack = [CCMenuItemImage itemFromNormalImage:@"Arrow-Normal-iPad.png" 
                 selectedImage:@"Arrow-Selected-iPad.png" 
                   target:self 
                   selector:@selector(onBack:)]; 
     // Add menu image to menu 
     CCMenu *back = [CCMenu menuWithItems: goBack, nil]; 

     // position menu in the bottom left of the screen (0,0 starts bottom left) 
     back.position = ccp(64, 64); 

     // Add menu to this scene 
     [self addChild: back]; 
    } 
    else { 
     // Create a menu image button for iPhone/iPod Touch 
     CCMenuItemImage *goBack = [CCMenuItemImage itemFromNormalImage:@"Arrow-Normal-iPhone.png" 
                 selectedImage:@"Arrow-Selected-iPhone.png" 
                   target:self 
                   selector:@selector(onBack:)]; 
     // Add menu image to menu 
     CCMenu *back = [CCMenu menuWithItems: goBack, nil]; 

     // position menu in the bottom left of the screen (0,0 starts bottom left) 
     back.position = ccp(32, 32); 

     // Add menu to this scene 
     [self addChild: back];   
    } 
} 

- (id)init { 

    if((self=[super init])) { 

     // Determine Screen Size 
     CGSize screenSize = [CCDirector sharedDirector].winSize; 

     //Boton en la Interfaz del iPad 
     self.iPad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad; 

     // Put a 'back' button in the scene 
     [self addBackButton]; 

     /// 
     self.isTouchEnabled = YES; 
     lastTouchPoint = ccp(-1.0f,-1.0f);      
     /// 

     [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGB565]; 
     background = [CCSprite spriteWithFile:@"background.png"]; 
     background.anchorPoint = ccp(0,0); 
     [self addChild:background z:-1]; 
     [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_Default]; 

    } 
    return self; 
} 

- (void) dealloc 
{ 
    // in case you have something to dealloc, do it in this method 
    // in this particular example nothing needs to be released. 
    // cocos2d will automatically release all the children (Label) 

    // don't forget to call "super dealloc" 
    [super dealloc]; 
} 

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch *touch = [touches anyObject]; 
    if(touch) { 
     CGPoint location = [touch locationInView: [touch view]]; 
     location = [[CCDirector sharedDirector] convertToGL:location]; 
     CCLOG(@"location(%f,%f)", location.x, location.y); 

     if(CGPointEqualToPoint(lastTouchPoint, ccp(-1.0f,-1.0f))) 
     { 
      lastTouchPoint = ccp(location.x, location.y); 
      CCSprite *circle = [CCSprite spriteWithFile:@"circle.png"]; 
      [circle setPosition:lastTouchPoint]; 
      [self addChild:circle]; 
      CCLOG(@"initial touchpoint set. to (%f,%f)", lastTouchPoint.x, lastTouchPoint.y); 
     } 
     else { 
      CCLOG(@"lastTouchPoint is now(%f,%f), location is (%f,%f)", lastTouchPoint.x, lastTouchPoint.y, location.x, location.y); 
      CGPoint diff = ccpSub(location, lastTouchPoint); 
      float rads = atan2f(diff.y, diff.x); 
      float degs = -CC_RADIANS_TO_DEGREES(rads); 
      float dist = ccpDistance(lastTouchPoint, location); 
      CCSprite *line = [CCSprite spriteWithFile:@"line.png"]; 
      [line setAnchorPoint:ccp(0.0f, 0.5f)]; 
      [line setPosition:lastTouchPoint]; 
      [line setScaleX:dist]; 
      [line setRotation: degs]; 
      [self addChild:line]; 

      CCSprite *circle = [CCSprite spriteWithFile:@"circle.png"]; 
      [circle setPosition:location]; 
      [self addChild:circle]; 

      //   lastTouchPoint = ccp(location.x, location.y); 
      lastTouchPoint = ccp(-1.0f,-1.0f); 
     } 

    } 
} 
@end 

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

ответ

3

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

float dist = ccpDistance(lastTouchPoint, location); 
CCSprite *line = [CCSprite spriteWithFile:@"line.png"]; 
[line setAnchorPoint:ccp(0.0f, 0.5f)]; 
[line setPosition:lastTouchPoint]; 
[line setScaleX:dist]; 

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

Ваш вопрос:

Это не принимая во внимание начальные размеры изображения вы загружаете (line.png). Если это не размер 1x1 png, то setScale собирается сделать слишком большой спрайт - превышение, которое вы испытываете.

Решение

Сделать line.png 1 х 1 пиксель изображения. Ваш код будет работать отлично, хотя у вас будет очень тонкая линия, которая не является эстетически приятной.

Или, для получения лучших результатов, вычислить масштаб для спрайта с учетом ширины line.png. Таким образом, спрайт может быть более подробным и не будет переполняться.

Изменение setScaleX линии к этому:

[line setScaleX:dist/line.boundingBox.size.width]; 
+0

Вы были правы, я не могу поверить, что это было что-то подобное, я ценю вашу помощь davbryn. Поставить setScaleX в соответствии с ограничивающей рамкой работает отлично. Спасибо большое. – DanMeza

-1

Я думаю, что вы можете использовать графическое ядро ​​здесь:

- (void)drawRect:(CGRect)rect { 

    CGContextRef context = UIGraphicsGetCurrentContext(); 

    CGContextSetLineWidth(context,4); 
    CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor); 


    CGContextMoveToPoint(context,startPoint.x , startPoint.y); 
    CGContextAddLineToPoint(context, endPoint.x, endPoint.y); 
    CGContextStrokePath(context); 

} 
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event 
{ 
    UITouch* touchPoint = [touches anyObject]; 
    startPoint = [touchPoint locationInView:self]; 
    endPoint = [touchPoint locationInView:self]; 

    [self setNeedsDisplay]; 
} 

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch* touch = [touches anyObject]; 
    endPoint=[touch locationInView:self]; 
    [self setNeedsDisplay]; 
} 

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch* touch = [touches anyObject]; 
    endPoint = [touch locationInView:self]; 
    [self setNeedsDisplay]; 
} 

Я думаю, что это поможет.

+0

Он использует Cocos2D для этого проекта, который использует OpenGL для рендеринга. Я думаю, что было бы нецелесообразно пытаться объединить это с Core Graphics в этом случае. – davbryn

+0

Извините, но я использовал основную графику с cocos2d и нашел, что путь прост и основная графика также основана на openGL, а какая разница в использовании OpenGL или основной графики. Пожалуйста, объясните .. – Haroon

+1

Core Graphics основан на кварце, а не на OpenGL. Они не очень хорошо сотрудничают. – davbryn

0

Использование cocos2d v3.x это работает:

в -(void)update:(CCTime)delta{} вы это делаете:

[self.drawnode drawSegmentFrom:ccp(50,100) to:ccp(75, 25) radius:3 color:self.colorDraw]; 

self.drawnode и самостоятельно. Свойства colorDraw инициализируются следующим образом: возможно, внутри -(void)onEnter{} :

self.drawnode = [CCDrawNode node]; 
self.colorDraw = [CCColor colorWithCcColor3b:ccRED]; 
[self addChild:self.drawnode]; 
Смежные вопросы