xcode 在 Cocos2d 中 Sprites 制作的两点之间画一条线 Sprite

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8749853/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 22:54:51  来源:igfitidea点击:

Draw a Line Sprite Between Two Points made by Sprites in Cocos2d

iosxcodecocos2d-iphonesprite

提问by DanMeza

I've been trying to draw a sprite line between 2 points made by sprites with mouse events on Xcode.

我一直试图在 Xcode 上用鼠标事件由精灵制作的 2 个点之间绘制精灵线。

I have been following the steps given on a forum in this link: cocos2d forums

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

But when i run the code, i get the line going all the way of the simulator. just like this.

但是当我运行代码时,我得到了模拟器的所有方式。像这样。

snapshot1

快照1

The line should stop by the second mouse sprite generated code, but it doesn't and keeps going all the way.

该行应该在第二个鼠标精灵生成的代码处停止,但它没有并且一直在继续。

My Scene is something like this.

我的场景是这样的。

My .h class

我的 .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

My .mm

我的.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

Does anyone knows how to work this out? i have been trying lots of things but nothing has worked for me, or maybe point out my mistake. i would really appreciate this.

有谁知道如何解决这个问题?我一直在尝试很多东西,但没有任何效果对我有用,或者指出我的错误。我真的很感激这一点。

回答by davbryn

I've not run the code but it looks fairly straightforward. The cause of the problem lies in this section:

我没有运行代码,但它看起来相当简单。问题的原因在于这部分:

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

This code calculates the distance between the two touch points in points (pixels), creates a new sprite (that will become the line) and sets the anchor point to the right hand side, centred vertically. It positions this at the point of the last touch and then sets the scale of the sprite's width based on the distance calculated earlier. This scaling factor will ensure the sprite is 'long' enough to reach between the two points.

此代码以点(像素)为单位计算两个触摸点之间的距离,创建一个新的精灵(将成为线)并将锚点设置在右侧,垂直居中。它将它定位在最后一次触摸的点上,然后根据之前计算的距离设置精灵宽度的比例。这个比例因子将确保精灵足够“长”以到达两点之间。

Your issue:

你的问题:

This isn't taking into account the initial dimensions of the image you are loading (line.png). If this isn't a 1x1 dimension png then the setScaleis going to make the resulting sprite too large - the overrun you are experiencing.

这没有考虑您正在加载的图像的初始尺寸 ( line.png)。如果这不是 1x1 尺寸的 png,则setScale会使生成的精灵过大 - 您遇到的溢出。

The Solution

解决方案

Make line.pnga 1 x 1 pixel image. Your code will work perfectly, though you will have a very thin line that is not aesthetically pleasing.

使line.png成为 1 x 1 像素图像。您的代码将完美运行,尽管您将有一条非常细的线条,不美观。

Or, for best results, calculate the scale for the sprite by taking into account the width of line.png. This way the sprite can be more detailed and won't overrun.

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

Change thesetScaleXline to this:

setScaleX行更改为:

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

回答by Jonny

Using Cocos2D v3.x this works:

使用 Cocos2D v3.x 这有效:

in -(void)update:(CCTime)delta{}you do this:

-(void)update:(CCTime)delta{}你这样做:

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

The self.drawnode and self.colorDraw properties are initialized like this, maybe inside -(void)onEnter{} :

self.drawnode 和 self.colorDraw 属性是这样初始化的,可能在里面 -(void)onEnter{} :

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

回答by Haroon

I think you can use core graphics here :

我认为您可以在这里使用核心图形:

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

I think this will help you.

我想这会对你有所帮助。