Isometric layer moving inside map
- by gronzzz
i'm created isometric map and now trying to limit layer moving. Main idea, that i have left bottom, right bottom, left top, right top points, that camera can not move outside, so player will not see map out of bounds. But i can not understand algorithm of how to do that.
It's my layer scale/moving code.
- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
    _isTouchBegin = YES;
}
- (void)touchMoved:(UITouch *)touch withEvent:(UIEvent *)event {
    NSArray *allTouches = [[event allTouches] allObjects];
    UITouch *touchOne = [allTouches objectAtIndex:0];
    CGPoint touchLocationOne = [touchOne locationInView: [touchOne view]];
    CGPoint previousLocationOne = [touchOne previousLocationInView: [touchOne view]];
    // Scaling
    if ([allTouches count] == 2) {
        _isDragging = NO;
        UITouch *touchTwo = [allTouches objectAtIndex:1];
        CGPoint touchLocationTwo = [touchTwo locationInView: [touchTwo view]];
        CGPoint previousLocationTwo = [touchTwo previousLocationInView: [touchTwo view]];
        CGFloat currentDistance = sqrt(
                                       pow(touchLocationOne.x - touchLocationTwo.x, 2.0f) +
                                       pow(touchLocationOne.y - touchLocationTwo.y, 2.0f));
        CGFloat previousDistance = sqrt(
                                        pow(previousLocationOne.x - previousLocationTwo.x, 2.0f) +
                                        pow(previousLocationOne.y - previousLocationTwo.y, 2.0f));
        CGFloat distanceDelta = currentDistance - previousDistance;
        CGPoint pinchCenter = ccpMidpoint(touchLocationOne, touchLocationTwo);
        pinchCenter = [self convertToNodeSpace:pinchCenter];
        CGFloat predictionScale = self.scale + (distanceDelta * PINCH_ZOOM_MULTIPLIER);
        if([self predictionScaleInBounds:predictionScale]) {
            [self scale:predictionScale scaleCenter:pinchCenter];
        }
    } else {
        // Dragging
        _isDragging = YES;
        CGPoint previous = [[CCDirector sharedDirector] convertToGL:previousLocationOne];
        CGPoint current = [[CCDirector sharedDirector] convertToGL:touchLocationOne];
        CGPoint delta = ccpSub(current, previous);
        self.position = ccpAdd(self.position, delta);
    }
}
- (void)touchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
    _isDragging = NO;
    _isTouchBegin = NO;
    // Check if i need to bounce
    _touchLoc = [touch locationInNode:self];
}
#pragma mark - Update
- (void)update:(CCTime)delta {
    CGPoint position = self.position;
    float scale = self.scale;
    static float friction = 0.92f; //0.96f;
    if(_isDragging && !_isScaleBounce) {
        _velocity = ccp((position.x - _lastPos.x)/2, (position.y - _lastPos.y)/2);
        _lastPos = position;
    } else {
        _velocity = ccp(_velocity.x * friction, _velocity.y *friction);
        position = ccpAdd(position, _velocity);
        self.position = position;
    }
    if (_isScaleBounce && !_isTouchBegin) {
        float min = fabsf(self.scale - MIN_SCALE);
        float max = fabsf(self.scale - MAX_SCALE);
        int dif = max > min ? 1 : -1;
        if ((scale > MAX_SCALE - SCALE_BOUNCE_AREA) ||
            (scale < MIN_SCALE + SCALE_BOUNCE_AREA)) {
            CGFloat newSscale = scale + dif * (delta * friction);
            [self scale:newSscale scaleCenter:_touchLoc];
        } else {
            _isScaleBounce = NO;
        }
    }
}