cocos2d for iPhone

A fast, easy to use, free, and community supported 2D game engine

Register or log in - lost password?
  • Blog
  • Store
  • Games
  • Documentation
  • Download
  • About

cocos2d for iPhone » Programming » cocos2d 3rd party extensions

100% working solution for the pinch-zoom & pan-move with boundaries control??

(256 posts) (44 voices)
  • Started 10 months ago by FJ
  • Latest reply from mobilebros

Tags:

  • angry birds
  • boundary
  • Box2D
  • camera
  • CCDirector
  • CCLayerPanZoom
  • CCPanZoom
  • CCPanZoomController
  • CCParallaxNode
  • CCScene
  • CCTouchDispatcher
  • centeronpoint
  • cocos2d
  • controller
  • director
  • gesture recognizers
  • Layer
  • move
  • pan
  • pan zoom CCPanZoomController
  • pinch
  • pinchzoom
  • rootViewController
  • scrolling
  • swallowsTouches
  • touch dispatcher
  • touch-related crashing
  • zoom
« Previous1…6789Next »
  1. goodeats2009
    Member

    ok, by accident i got it working. i did not realize that the other touch dispatcher that i specified in another layer is taking priority over it, i have this in my GameHudLayer

    [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];

    if I change the priority, it works now. BUT now i cannot use the GameHudLayer. is there a way to prioritize these? thanks

    Posted 4 months ago #
  2. wololo
    Member

    Is it not recommended to use UIScrollView with Cocos2D? Because UIScrollView does everything the OP is asking for. I am also working on getting UIScrollView integrated with Cocos2D, but I'm having lots of trouble with it. The code on Stack Overflow, and 2 other blogs are not at all helpful because they only show code fragments.

    The idea of the ScrollView is that it has to contain subView(s). In our case, this would be the EAGLView from [CCDirector SharedDirector] OpenGLView]. The scrolling works, as well as the touches being delegated to the Cocos2D layer.

    However: Since the GLView is added as a subview, that entire view is moved around, and if you select a specific layer to move around, then it creates a mess because of moving the GL View and the CCLayer at the same time. If there was some way to keep the GLView static, this method would be golden.

    Sorry to hijack this thread, but I feel like we're reinventing the wheel when apple has a perfect solution for exactly the use case the OP has described.

    Posted 4 months ago #
  3. Jeff
    Member

    @wololo Well the problem with UIScrollView, is it is not integrated into cocos2d making it harder to implement. From what I heard, it sounds like you are having trouble with it. The point of ccPanZoomController is to eliminate that struggle.

    @gooddeats2009 What is the priority of the hud layer?

    Posted 4 months ago #
  4. goodeats2009
    Member

    The priority of the HUD is 0.

    Posted 4 months ago #
  5. Jeff
    Member

    Sorry if I am bothering you with questions, but can I see some code of how you initialize your HUD?
    Have you seen this tutorial: http://www.raywenderlich.com/4666/how-to-create-a-hud-layer-with-cocos2d?

    Posted 4 months ago #
  6. goodeats2009
    Member

    hi Jeff, i did see that. i figured it out a portion of my problem, its the CCTouchDispatcher.

    -(void) registerWithTouchDispatcher {
        [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
    }

    i can touch the GameHUD and the gameplayLayer but the scrolling does not respond. i tried using the ccpanzoomcontroller which is in one of the other posts. but i cannot activate it at the same time with the gameplayLayer since the ccpanzoomcontroller needs to take priority to the touches and disabling the gameplayLayer in the process. its either one or the other and not both. I'm sure there is a way to do it i just don't know it :) thanks

    Posted 4 months ago #
  7. Jeff
    Member

    Do you initialize your ccpanzoomcontroller in the gameplayLayer or the GameHUD?

    Posted 4 months ago #
  8. goodeats2009
    Member

    i do it in the gamePlayLayer since this is the layer i want to have panning. in my Init method

    CGRect boundingRect = CGRectMake(0,0,480,640);
            _controller = [[CCPanZoomController controllerWithNode:self]retain];
            _controller.boundingRect = boundingRect;
            [_controller enableWithTouchPriority:0 swallowsTouches:YES];

    works ok if you set the priority to say -1. having them both at 0 does not work.

    Posted 4 months ago #
  9. Krithik B
    Member

    Hello
    http://mobile-bros.com/source/CCPanZoomController/
    This control works very well in most of the cases . However if you try to zoom in corner it suddenly jumps to middle .
    But CCLayerPanZoom which is in cocos2d-Extensions don't have this problem and also it has pan more smoother , However this CCPanZoomController has great functions like zoomToPoint ,centerOnPoint etc .
    Is it not possible to merge both :) ?

    Posted 4 months ago #
  10. Jeff
    Member

    Yes it is possible, and it is probable that someone is doing that, but you could check. You could always help in doing that.

    Posted 4 months ago #
  11. breskit
    Member

    It wouldn't be too tricky to create your own zoom/pan method within your layer. I've done a very brash version in an app I'm currently working on and it works ok when zoomed in. Needs tuning if already zoomed out to simply pan. It's on my to-do list.

    My plan is a double-tap in any corner will zoom to that corner, double-tap in the center will zoom to center.
    With a toggle on the zoom. So if zoomed in, will zoom out & vice versa.

    Actually, may try and get that done tonight before the footy starts.

    Posted 4 months ago #
  12. Jeff
    Member

    I have made a way to pan really well. It is very customizable and realistic, but it only works with box2d and I haven't cleaned up the code yet.
    I have the process here: http://www.cocos2d-iphone.org/forum/topic/23884

    Posted 4 months ago #
  13. Krithik B
    Member

    Yupie , i guess i fixed that jumping issue when zooming in corners , i just took code from cocos2d-Extensions CCZoomController.

    Add this Function

    -(void)moveNodeForZoomFromCurPos:(CGPoint)curPos andPrevPos:(CGPoint)prevPos
    {
        // If scale was changed -> set new scale and fix position with new scale
        if (self.node.scale != prevScale)
        {
            CGPoint realCurPosLayer = [self.node convertToNodeSpace: curPos];
            CGFloat deltaX = (realCurPosLayer.x - self.node.anchorPoint.x * self.node.contentSize.width) * (self.node.scale - prevScale);
            CGFloat deltaY = (realCurPosLayer.y - self.node.anchorPoint.y * self.node.contentSize.height) * (self.node.scale - prevScale);
            CGPoint tempPos = ccp(self.node.position.x - deltaX, self.node.position.y - deltaY);
            self.node.position = [self boundPos:tempPos];
        }
        // If current and previous position of the multitouch's center aren't equal -> change position of the layer
        if (!CGPointEqualToPoint(prevPos, curPos))
        {
            CGPoint tempPos = ccp(self.node.position.x + curPos.x - prevPos.x,
                                  self.node.position.y + curPos.y - prevPos.y);
            self.node.position = [self boundPos:tempPos];
        }
    }

    And replace this moveZoom func with this

    - (void) moveZoom:(CGPoint)pt otherPt:(CGPoint)pt2
    {
        //what's the difference in length
    	float length = ccpDistance(pt, pt2);
    	float diff = (length-_firstLength);
    
        //ignore small movements
        if (fabs(diff) < _pinchDistanceThreshold)
            return;
    
        prevScale = _node.scale;
    
    	//calculate new scale
    	float factor = diff * _zoomRate * _pinchDamping;
    	float newScale = _oldScale + factor;
    
        //bound scale
    	if (newScale > _zoomInLimit)
    		newScale = _zoomInLimit;
    	else if (newScale < _zoomOutLimit)
    		newScale = _zoomOutLimit;
    
        //set the new scale
    	_node.scale = newScale;
    
        if(_centerOnPinch == NO)
        {
             [self updatePosition:_node.position];
        }
    }

    And add this lines after [self moveZoom:pt otherPt:pt2]; in touchesMoved

    CGPoint curPosTouch1 = [[CCDirector sharedDirector] convertToGL: [touch1 locationInView: [touch1 view]]];
    		CGPoint curPosTouch2 = [[CCDirector sharedDirector] convertToGL: [touch2 locationInView: [touch2 view]]];
    		CGPoint prevPosTouch1 = [[CCDirector sharedDirector] convertToGL: [touch1 previousLocationInView: [touch1 view]]];
    		CGPoint prevPosTouch2 = [[CCDirector sharedDirector] convertToGL: [touch2 previousLocationInView: [touch2 view]]];
    
            // Calculate current and previous positions of the layer relative the anchor point
    		CGPoint curPosLayer = ccpMidpoint(curPosTouch1, curPosTouch2);
    		CGPoint prevPosLayer = ccpMidpoint(prevPosTouch1, prevPosTouch2);
    
            [self moveNodeForZoomFromCurPos:curPosLayer andPrevPos:prevPosLayer];

    :)

    Posted 4 months ago #
  14. Stepan Generalov
    Moderator

    @krithik_b007
    It's possible to merge them.
    If you can add new features to CCLayerPanZoom, and make a Pull Request with Tests - i would love to merge it (And of course add you to Authors file).

    Posted 4 months ago #
  15. mobilebros
    Moderator

    @krithik_b007 - Thanks for this, I'll check it out and see if I can understand the issue. I'd like to get CCPanZoomController as close to perfect as possible and weed out the weirdnesses.

    Posted 4 months ago #
  16. mobilebros
    Moderator

    @goodeats2009 - Why don't you just have your HUD take higher priority and if the user didn't touch within the HUD bounds on touchBegan, return false; cocos will then pass the touch on to whoever has next priority, in your case it would be the CCPanZoomController.

    Posted 4 months ago #
  17. goodeats2009
    Member

    Hi, I did that approach between the Gamehud and the gameplayLayer. The problem now is between the gameplayLayer and the ccpanzoomcontroller. All of the sprites are added to the gameplayLayer which they also do touch activities. What I want to do is when a sprite is touched then it responds to the sprite, otherwise the ccpanzoomcontroller will respond to panning. Tnx

    Posted 4 months ago #
  18. mobilebros
    Moderator

    @goodeats2009 - Then it will be a similar approach, if there are no touches in any of the sprites return false in touchBegan and the touch will be passed on.

    @krithik_b007 - The actual problem was actually in "beginZoom". "_firstTouch" needs to be set like this:

    _firstTouch = [_node convertToNodeSpace:[[CCDirector sharedDirector] convertToGL:ccpMidpoint(pt, pt2)]];

    It was in the wrong coordinates before, as it was missing the convertToGL.

    Posted 4 months ago #
  19. goodeats2009
    Member

    Yes that's true, I will try it tonight and give feedback. Tnx

    Posted 4 months ago #
  20. mobilebros
    Moderator

    I've finally created a github account. The controller can now be found here:

    https://github.com/robertblackwood/CCPanZoomController

    Posted 4 months ago #
  21. muzzammil
    Member

    hi all ,

    i am using this CCPanZoomController .. The problem lies that i at an instance of time i want to change the view point of my map.

    I have the tileId as well as the coordinates of that tile ..

    But i guess the map coordinates that need to be given to -(void) updatePosition:(CGPoint)pos method are different.. It always take negetive values as input..

    How do i do that ??

    Posted 4 months ago #
  22. AppTinker
    Member

    @muzzammil - You could use the "centerOn" functions. updatePosition generally takes a negative position because it literally does a bounds check against the pt and then sets the node's position to it; if you think about it, negative values is what would most make sense. For example you want to move a huge "map" to it's center point, you'd have to move the map down (negative y) and left (negative x) to achieve this.

    Posted 4 months ago #
  23. xmawiel
    Member

    Is anybody else experiencing flickering while scheduling centeronpoint for an moving object?

    Posted 4 months ago #
  24. muzzammil
    Member

    @AppTinker:That still doesnt point to the correct location .. I am giving tile center to this method as input .. But still it zooms somewhere else ...

    Posted 4 months ago #
  25. elsevero
    Member

    @mobilebros: Thanks for sharing your controller! I've tested it for a parallaxNode and it works smoothly but I'd like to ask you about some improvements :)

    The improvements will be:
    - When trying to zoom (pinch) to a certain area of the screen to zoom there (not bottom-left zooming)
    - Vertical scrolling to be normal (when scroll your finger downwards the node follow the same direction)
    As I said you before I'm using for a CCParallaxNode and I've added the layers with their sprites to it, when I'm zooming in I'm able to see the bounds of the front layer (because the front layer is less in width than the back one); How to avoid that?
    maybe these ones are already implemented and I'm not using this controller correctly...

    Thanks again! ;)

    Posted 4 months ago #
  26. Krithik B
    Member

    @mobilebros

    Thanks for the quick fix and coming back to this thread:) .
    I am using the controller with parallax node having 3 to 4 layers and it works so well with zooming and scrolling :)

    Posted 4 months ago #
  27. elsevero
    Member

    @Krithik B: Could you please share some code? I'd love to see your example in action :)

    Posted 4 months ago #
  28. mobilebros
    Moderator

    @elsevero - I believe you described the "centerOnPinch" property which defaults to true so I'm not sure why you'd be having any issue with it. It'd be nice to invert the scrolling behavior like that so sure I'll add it soon. I'm not positive about the parallaxing, I'll have to look at it, but it seems like Krithik might have a solution.

    Posted 4 months ago #
  29. Krithik B
    Member

    @elsevero
    Hope u got the solution check your PM.

    @mobilebros
    Yup its working fine with parallax if possible i will attach one test soon :)
    again thanks .

    Posted 4 months ago #
  30. muzzammil
    Member

    i want to set my center view to a particular tile .I have tile Coordinates as well as tile's center point .How do i can my view point to that location

    I have used ccpanzoomcontroller in my code.

    Earlier i was told to use "centerOnPoint:" method but i didnt worked.

    Thanks

    Posted 4 months ago #

RSS feed for this topic

« Previous1…6789Next »

Reply »

You must log in to post.

cocos2d for iPhone is proudly powered by bbPress.