在Cocos2d中由精灵制作的两点之间画一条线形精灵

时间:2012-01-05 21:09:32

标签: ios xcode cocos2d-iphone sprite

我一直在尝试在Xcode上用鼠标事件在sprite之间绘制两个点之间的精灵线。

我一直在关注此链接中论坛上给出的步骤: cocos2d forums

但是当我运行代码时,我会让线路一直走向模拟器。就像这样。

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 个答案:

答案 0 :(得分: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 x 1像素的图像。你的代码将完美地运行,尽管你会有一条非常细的线条,这在美学上并不令人愉悦。

或者,为了获得最佳效果,请考虑 line.png 的宽度来计算精灵的比例。这样精灵可以更加详细,不会溢出。

setScaleX行更改为:

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

答案 1 :(得分: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和self.colorDraw属性初始化如下,可能在-(void)onEnter{} :

self.drawnode = [CCDrawNode node];
self.colorDraw = [CCColor colorWithCcColor3b:ccRED];
[self addChild:self.drawnode];

答案 2 :(得分:-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];
}

我认为这会对你有帮助。