Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SpriteKit Generate Random Curl Line

I am working on a project and what I need to accomplish is to generate random curl line. At this point I have already have a line which is randomly generated but it is not curl. I am spawning points at different x positions on every 0.5 seconds and connect this points with bezier. Everything works perfectly except that it is not curl. On the picture below is shown on 1) How I have it now and on 2) How I suppose to make it. Any ideas how I can do that ? I am using SpriteKit - Objective C enter image description here

like image 881
Viktor Todorov Avatar asked Aug 31 '15 07:08

Viktor Todorov


1 Answers

Basically what you need to make and randomize a A Bézier (parametric) curve are control points.

After you read that great answer and get familiar with terms, you can try this example (I assume that your scene and view size are set correctly):

GameScene.m

#import "GameScene.h"

@implementation GameScene

-(void)didMoveToView:(SKView *)view {

}

-(NSInteger)randomNumberBetween:(NSInteger)from to:(NSInteger)to {

    return (int)from + arc4random() % (to-from+1);
}


- (CGMutablePathRef)generatePath
{
    CGMutablePathRef path = CGPathCreateMutable();

    CGPoint p0 =  CGPointMake(CGRectGetMidX(self.frame),self.scene.size.height-20.0f); //starting point just little below the upper edge of the screen

    CGPathMoveToPoint(path, nil, p0.x, p0.y);

    CGPoint p1 =
    CGPointMake([self randomNumberBetween:150 to:300], self.scene.size.height- [self randomNumberBetween:150 to:300]);

     CGPoint p2 = CGPointMake([self randomNumberBetween:150 to:300],[self randomNumberBetween:150 to:300]);

    CGPoint p3 = CGPointMake(CGRectGetMidX(self.frame),0 + 20.0f); //ending point, just little above the bottom edge of the screen

    CGFloat v = 0.3;

    CGFloat cp1x = p1.x+v * (p1.x-p0.x);
    CGFloat cp1y = p1.y+v *  (p1.y-p0.y);
    CGFloat cp2x = p2.x-v *  (p3.x-p2.x);
    CGFloat cp2y = p2.y-v *  (p3.y-p2.y);




    CGPathAddCurveToPoint(path,nil,cp1x,cp1y,cp2x,cp2y,p3.x,p3.y);



    /*Debug - not needed*/


    SKSpriteNode *sp0 = [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:CGSizeMake(5.0f,5.0f)];
    sp0.zPosition = 5;
    sp0.position = p0;
    SKLabelNode *lp0 = [SKLabelNode labelNodeWithFontNamed:@"ArialMT"];
    lp0.fontColor = [SKColor whiteColor];
    lp0.fontSize = 20.0f;
    lp0.text = @"p0";
    lp0.position = CGPointMake(0.0f,-20.0f);
    [sp0 addChild:lp0];
    [self addChild:sp0];


    SKSpriteNode *sp1 = [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:CGSizeMake(5.0f,5.0f)];
    sp1.zPosition = 5;
    sp1.position = p1;
    SKLabelNode *lp1 = [SKLabelNode labelNodeWithFontNamed:@"ArialMT"];
    lp1.fontColor = [SKColor whiteColor];
    lp1.fontSize = 20.0f;
    lp1.position = CGPointMake(0.0f,15.0f);
    lp1.text = @"p1";
    [sp1 addChild:lp1];
    [self addChild:sp1];

    SKSpriteNode *sp2 = [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:CGSizeMake(5.0f,5.0f)];
    sp2.zPosition = 5;
    sp2.position = p2;
    SKLabelNode *lp2 = [SKLabelNode labelNodeWithFontNamed:@"ArialMT"];
    lp2.fontColor = [SKColor whiteColor];
    lp2.fontSize = 20.0f;
    lp2.position = CGPointMake(0.0f,15.0f);
    lp2.text = @"p2";
    [sp2 addChild:lp2];
    [self addChild:sp2];


    SKSpriteNode *sp3 = [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:CGSizeMake(5.0f,5.0f)];
    sp3.zPosition = 5;
    sp3.position = p3;
    SKLabelNode *lp3 = [SKLabelNode labelNodeWithFontNamed:@"ArialMT"];
    lp3.fontColor = [SKColor whiteColor];
    lp3.fontSize = 20.0f;
    lp3.position = CGPointMake(0.0f,15.0f);
    lp3.text = @"p3";
    [sp3 addChild:lp3];
    [self addChild:sp3];



    SKShapeNode *p0p1 = [SKShapeNode node];
    p0p1.zPosition = 2;
    CGMutablePathRef path1 = CGPathCreateMutable();
    CGPathMoveToPoint(path1, NULL, p0.x, p0.y);
    CGPathAddLineToPoint(path1, NULL, p1.x, p1.y);
    p0p1.path = path1;
    [p0p1 setStrokeColor:[UIColor greenColor]];
    [self addChild:p0p1];

    SKShapeNode *p2p3 = [SKShapeNode node];
    p2p3.zPosition = 2;
    CGMutablePathRef path2 = CGPathCreateMutable();
    CGPathMoveToPoint(path2, NULL, p2.x, p2.y);
    CGPathAddLineToPoint(path2, NULL, p3.x, p3.y);
    p2p3.path = path2;
    [p2p3 setStrokeColor:[UIColor greenColor]];
    [self addChild:p2p3];

    return path;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    [self removeAllChildren];

    SKShapeNode *yourline = [SKShapeNode node];
    yourline.zPosition = 1;

    yourline.path = [self generatePath];

    [yourline setLineWidth:5];

    [yourline setStrokeColor:[SKColor redColor]];

    [self addChild:yourline];

}

Most of this code is used for visual debugging and its not needed in order to randomize the curve. The important part is the first part of the method generatePath. Here is the result:

enter image description here

like image 77
Whirlwind Avatar answered Nov 19 '22 03:11

Whirlwind