Нарисуйте спрайт между двумя точками, созданными спрайтами в Cocos2d - PullRequest
1 голос
/ 06 января 2012

Я пытался нарисовать линию спрайта между двумя точками, созданными спрайтами с событиями мыши в XCode.

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

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

snapshot1

Строка должна останавливаться с помощью кода, созданного вторым спрайтом мыши, но это не так и продолжается до конца.

Моя сцена примерно такая.

Мой .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 ]

3 голосов
/ 06 января 2012

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

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 ).Если это не px размера 1x1, то setScale сделает результирующий спрайт слишком большим - переполнение, которое вы испытываете.

Решение

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

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

Измените строку setScaleX на эту:

[line setScaleX:dist / line.boundingBox.size.width];
0 голосов
/ 21 августа 2014

Используя Cocos2D v3.x это работает:

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

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

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

self.drawnode = [CCDrawNode node];
self.colorDraw = [CCColor colorWithCcColor3b:ccRED];
[self addChild:self.drawnode];
0 голосов
/ 06 января 2012

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

- (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];
}

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

...