user2415313
user2415313

Reputation: 101

Sticking nodes to SkSpriteNode after enlargement

Problem

As of right now, I've just realised a pretty major design flaw in my application..

So, the problem is:

A rifle shot is fired, and lands based on no trajectory as of right now, I'm toying with the idea. However, the bullets land and their marks are left as nodes.

-(void)applyShot:(int) posX with:(int) posY {
    SKSpriteNode *impact = [[SKSpriteNode alloc] initWithColor:[UIColor grayColor] size:CGSizeMake(2, 2)];
    impact.zPosition = 1;
    impact.userInteractionEnabled = NO;
    impact.position = CGPointMake(posX , posY);
    [backgroundImage addChild:impact];
}

And posX / posY are sent this way.

//Find difference between centre and background moved distance.
CGPoint positionNow = CGPointMake(backgroundImage.position.x, backgroundImage.position.y);
CGPoint positionPrev = CGPointMake(0.5, 0.5);

float xdiff = positionNow.x - positionPrev.x;
float ydiff = positionNow.y - positionPrev.y;

//Calculate ydrop
int newYDrop = yDrop * 10;
//

CGPoint newPositionOne = CGPointMake(0.5 - xdiff, 0.5 - ydiff);
newPositionOne = CGPointMake((newPositionOne.x + [self myRandom:15 withFieldLower:-15]), (newPositionOne.y - newYDrop));

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(secondsDelay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^(void){
    [self applyShot:newPositionOne.x with:newPositionOne.y];
});

Which seems to work fine, until I started toying with zoom.

Now, this application basically is a 1080p image for the reticle, and the background enlarges to give the (zoom) effect, then the background is touch-dragged/inverted to give the reticle moving effect.

Then I managed to get it to fire exactly where the crosshair was, which was good.. Then I started toying with zoom and noticed this.

enter image description hereenter image description here

So if it's not too easy to notice, the (bullet hits) are the grey marks, however, when you enlarge the backgroundImage they aren't tied to it. so they remain the same spread.

Solution

Now what I need is to either,

But I'm pretty confused at how to achieve this.

Additional problem

When calibrating the drop, the drop will remain a burden no matter of the zoom as of right now. so if it's a 1 mil-dot drop on 6x zoom, it's also a 1 mil-dot drop at 10x zoom or 1x zoom ( I keep saying zoom when I mean enlargement )

How can I achieve a calibration for drop intensity no matter what enlargement the background image is at?

Thanks for reading and confusing yourself with my dire problems, it's appreciated!

What I've Tried

saving the children to a mutable array, then recreating them after a zoom change;

//recreate children
[backgroundImage removeAllChildren];
for (int i=0; i < [shotsHitX count]; i++) {

    double posX = ([shotsHitX[i] doubleValue] / 5) * rifleZoom;
    double posY = ([shotsHitY[i] doubleValue] / 5) * rifleZoom;

    SKSpriteNode *impact = [[SKSpriteNode alloc] initWithColor:[UIColor grayColor] size:CGSizeMake(2, 2)];
    impact.zPosition = 1;
    impact.userInteractionEnabled = NO;
    impact.position = CGPointMake(posX , posY);

    [shotsHitX addObject:[NSNumber numberWithDouble:posX]];
    [shotsHitY addObject:[NSNumber numberWithDouble:posY]];

    [backgroundImage addChild:impact];
}
//end recreate children

Crash with memory error.

not so good at this!

[backgroundImage removeAllChildren];
for (int i=0; i < [shotsHitX count]; i++) {

    double posX = ([shotsHitX[i] doubleValue] / 5) * rifleZoom;
    double posY = ([shotsHitY[i] doubleValue] / 5) * rifleZoom;

    SKSpriteNode *impact = [[SKSpriteNode alloc] initWithColor:[UIColor grayColor] size:CGSizeMake(2, 2)];
    impact.zPosition = 1;
    impact.userInteractionEnabled = NO;
    impact.position = CGPointMake(posX , posY);

    [backgroundImage addChild:impact];
}
//end recreate children

Works, however, now It doesn't just seem quite right..

I think the problem is when the initial zoom goes in it works, then when it reverts it's mixing zoom shots in the array with old shots.. Here we go again, MORE ARRAYS.

    //recreate children
    [backgroundImage removeAllChildren];
    for (int i=0; i < [shotsHitRem count]; i+= 2) {

        double posX = ([shotsHitRem[i] doubleValue] / 5) * rifleZoom;
        double posY = ([shotsHitRem[i+1] doubleValue] / 5) * rifleZoom;

        SKSpriteNode *impact = [[SKSpriteNode alloc] initWithColor:[UIColor grayColor] size:CGSizeMake(2, 2)];
        impact.zPosition = 1;
        impact.userInteractionEnabled = NO;
        impact.position = CGPointMake(posX , posY);
        [backgroundImage addChild:impact];

        //add olds m4
        if ([shotsHitM4 count] > 0) {
            posX = ([shotsHitM4[i] doubleValue] / 2) * rifleZoom;
            posY = ([shotsHitM4[i+1] doubleValue] / 2) * rifleZoom;
            impact.position = CGPointMake(posX, posY);
            [backgroundImage addChild:impact];
        }
    }
    //end recreate children

Now I crash attempting to add a sknode which already has a parent

Confusing as it should removeAllChildren before looping

Upvotes: 1

Views: 51

Answers (1)

user2415313
user2415313

Reputation: 101

Well after some major messing around

[backgroundImage setScale:rifleZoom];

Programming is my favourite, oh yeah.. Five hours, Oh yeah.. For one line, oh yeah!

I wasn't scaling before, I was creating a new cgsize. and that was my problem.

I now have the issue of scaling and trying to render a new centrepoint as it still remembers the centrepoint of scale = 1 and scale = 2, nightmare.

Upvotes: 1

Related Questions