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
12…9Next »
  1. FJ
    Member

    Hi everybody,

    I decide to create this thread because after going through a lot of threads I'm still stuck with this problem:
    I want to be able to pinch and zoom in/out (anywhere on the screen) and pan-move my layer (bigger than the screen size: 960x640) but keeping it within the limits, thus is no showing any "black background".
    I would like to achieve this using gesture recognizers.

    Anybody has a 100% working code? So far I couldn't find a solution that works 100%.
    Just to be sure that we have the same image about what I would like to achieve, think about the "angry birds" interface and how it works.

    Thanks to everybody in advance! :)

    Posted 10 months ago #
  2. asymptote
    Member

    *100% working code* there you go! and yes you are welcome!

    Posted 10 months ago #
  3. FJ
    Member

    Hi asymptote,
    if you really know the solution it would be great you can share with the cocos2d community.

    Because, as I said, I read al lot of threads about this "problem", I remember I read yours as well:

    http://www.cocos2d-iphone.org/forum/topic/13406

    It doesn't seem you get any help at that time but maybe it was because nobody knew how to help you. :S

    Posted 10 months ago #
  4. Verisutha
    Member

    The best thing for you to do is post the code you are attempting. There are tons of threads on this specific topic. When I was initially working on the pinch and zoom I had a ton of issues. I tried a lot of posted code and nothing worked, or it "kind" of worked.

    I eventually sat down and wrote a custom routine for my specific app. You'll find that you'll probably have to customize things to meet your specs.

    If you are having a specific problem I would suggest post the code you are trying and a sample project. People will help, if you just say "give me code for <x> because I can't find it somewhere" you will find you won't get much assistance. People prefer to see you make an attempt and fail, than just ask for code.

    Mine works 100% for me, but it certainly isn't in a plug and play form since it's designed to use a base class, but if you post something I might be able to help set you in the right direction.

    Posted 10 months ago #
  5. FJ
    Member

    I see your point Verisutha, but you maybe misunderstood me because I wasn't that clear explaining the reason for this thread.

    When you use the UKit you have the UIViewScroller that works as a standard class for everybody and that it already have all the functionality that I'm asking for. Because I miss this kind of class in Cocos2D I would like to ask for that generic thing that you can "plug" into cocos2d and works for everybody.

    I saw sooooo many threads and nobody has decide to show/post a 100% working class despite I'm sure that many people already achieved this.

    I don't know wether I expressed better myself now, this thread is more like a "give me your code" thread, it's a call to finally have one single thread with this problem generically solve for everybody's sake and reference. Therefore, if you think you can collaborate with your "specific" solution for the problem I guess that it could be the beginning of finding/coding something generic.

    Posted 10 months ago #
  6. mobilebros
    Moderator

    @FJ - I understand your frustration actually; I was in the same boat and decided to code something up that would solve all these issues. I believe it had a few limitations or rather preconditions such as the anchorPoint of the layer had to be (0,0) and it was based on actually positioning/scaling the layer itself vs. the moving/zooming camera approach that others seem to take.... give me hour or so and I'll dredge it up.

    Posted 10 months ago #
  7. Angry Panda
    Member

    I am working on this very solution at the moment. I have my world which is about 2000px by 800px. I can pan left and right and zoom in/out.

    I use CCBigImage because I have a large game world. At the moment it is not perfect but I am improving CCBigImage to make it work.

    If I get it to work 100% I will post the code. (although the code is a bit convaluted at the moment)

    Posted 10 months ago #
  8. Angry Panda
    Member

    @mobilebros

    If you can find your code that would be much apreciated.

    Posted 10 months ago #
  9. Angry Panda
    Member

    @mobilebros if you have a the fully working code to do this I will love you forever

    Posted 10 months ago #
  10. mobilebros
    Moderator

    Found it! An unfinished game called Bombzore lol. Tested it real quick, it seems to all check out.

    I posted the code up here: http://mobile-bros.com/source/CCPanZoomController/

    Simple usage is as follows

    _controller = [ViewControl controllerWithScrollNode:self];
       _controller.touchPriority = kScrollZoomPriority;
       [self addChild:_controller];
    
       CGSize scrollSize = CGSizeMake(965, 700);
       [_controller setScrollableSize:scrollSize];
       [_controller enable];

    It doesn't really matter that you add the controller as a child to anything, I only did it so it would clean up in the right spot.

    The final call to enable is what actually "turns it on" and allows touching; make sure you turn on multiple touches in the view otherwise only panning will work.

    There are a ton of properties to play with: setting zoom limits, swipe motion controls, dampening the scrolling, etc.

    Let me know if there are any questions.

    p.s. A good cleanup rule (in dealloc or wherever) is to call [_controller disable]; otherwise I think the touch dispatcher will hang onto a reference.

    Posted 10 months ago #
  11. mobilebros
    Moderator

    And yes, the anchor point of the node you are panning/zooming must be (0,0)

    Posted 10 months ago #
  12. Angry Panda
    Member

    how do u use it? if I have my layer with the background on, how do I connect it to your method?

    Posted 10 months ago #
  13. Angry Panda
    Member

    Sorry stupid question
    _controller = [ViewControl controllerWithScrollNode:DING];

    DING is the layer to control

    Posted 10 months ago #
  14. mobilebros
    Moderator

    yep, you got it

    Posted 10 months ago #
  15. FJ
    Member

    @mobilebros
    I made a trial with a simple (960x480) layer and it works 100%.
    When panning it even has a kind of feeling of the UIViewScroller.
    It's awesome!!

    Do you think this (or something similar) could be include in future Cocos2D releases or at least to become part of the code snippets section. There are tooooo many people looking for this and it would be nice to have it available as a cocos2d feature or as a reference.

    @Angry Panda
    I guess that from now on you will love mobilebros forever. ;)

    Posted 10 months ago #
  16. mobilebros
    Moderator

    @FJ - Thanks, glad you like it. I guess including it, or something like it, somewhere wouldn't be a bad idea (maybe the extensions project).

    It could use a few extras such as zooming in to center on the midpoint of your pinch and better swipe detection.

    Posted 10 months ago #
  17. Angry Panda
    Member

    +1 for adding this to extentions

    Posted 10 months ago #
  18. hsuntn
    Member

    I noticed that when the scrollable size is smaller than the _zoomOutLimit implies (i.e. _maxScr < _(actScr/_zoomOutLimit)) caused jittering on panning. I added this to the end of setScrollableSize:

    float zoomX = _actScr.x/_maxScr.x;
    float zoomY = _actScr.y/_maxScr.y;
    _zoomOutLimit = MAX(zoomX, zoomY);

    and that fixed the jittering. Hope this helps someone.

    Posted 10 months ago #
  19. mobilebros
    Moderator

    @hsuntn - Thanks! that's great to know; I'll add the fix soon and update. This would be a good time for me to remind people that this code has been very minimally tested...

    Posted 10 months ago #
  20. FJ
    Member

    @mobilebros
    It would be great to see this in the extensions. :)

    And I agree, it could use more extras but it's good to have a common base to begin.
    Now anybody can use your class and add more methods to make it more complete, therefore, I would suggest that if someone using this class as a base achieve some other extra features, he/she could post it here. Again, if someone fix something like hsuntn did (thank you btw), posting it here would help everybody.

    For example, I will try to implement a method that taking a zoom amount and a layer point, can focus at that layer point with that zoom level. Maybe, also taking a time parameter to do the focus&zoom action gradually it would be interesting to consider.
    (I don't know wether CCMoveTo can already make the trick).

    Then, I'm thinking about changing all the touch events to gesture recognizers for having both options.

    I'm not a skilled programmer but if I achieve something, I will post it here. :)

    Posted 10 months ago #
  21. mobilebros
    Moderator

    Ok, I'll send a PM to @Stepan Generalov about all this and see what he thinks.

    Posted 10 months ago #
  22. Daniel López
    Member

    I have it, but it's a mesh of code xD

    Posted 10 months ago #
  23. Stepan Generalov
    Moderator

    @mobilebros I'm really interested in such feature for extensions repo.
    I would like to look later into the code and maybe do some refactoring - use CC namespace and maybe rename something to make it easier to understand.

    For this I need from you only MIT License.

    But you can help me even more by providing test application for it.
    Also it will be cool to fix anchor point limitations, maybe boundingBox and examples how fixPosition methods implemented in CCAdvancedMenu and CCBigImageTestLayer will help.

    Moving this to the extensions forum.

    Thanks a lot for PM.

    Posted 9 months ago #
  24. mobilebros
    Moderator

    Ok I'll put the MIT license in; I'll have to think a bit about the anchor point solution... it actually might be as simple as just using a CGRect instead of a CGSize and basically defining the boundaries as relative to the anchorPoint. I'll put an example together too at some point and report back here.

    CCPanZoomController perhaps? I also feel like the enabling and disabling of touches is a bit weird, anybody have suggestions?

    Posted 9 months ago #
  25. Chris.A
    Member

    @mobilebros
    I'm happy to see something like this being added in cocos. Thanks mobilebros for sharing.

    Got a couple of questions:

    1.When talking about "fixing anchor point limitations", allowing to center on the midpoint of your pinch when zooming will be fixed as well?

    2.This class has a specific implementation to control the touches but in the case that someone needs to include some other touch behavior, like for example dragging and item, how it can be extended?
    Is it possible to create a separate code or we are forced to go inside this class and write what we need inside the ccTouchBegan, ccTouchMoved and so on?

    I might be talking nonsense (I began to use cocos a few days ago) but maybe using UIGestureRecognizers could be better and it might solve your enabling/disabling problem as well.

    Posted 9 months ago #
  26. Stepan Generalov
    Moderator

    If it's a CCNode subclass - than probably it should be named CCPanZoomNode or CCGesturesNode.

    If you prefer controller or more isolated from node approach - than maybe it can be done as an extension to CCTouchDispatcher?
    Maybe another singleton, that will register itself in touch dispatcher and provide it's own delegate protocol for callbacks?
    CCGesturesDispatcher?

    Posted 9 months ago #
  27. mobilebros
    Moderator

    @Chris.A

    1. Well not exactly, but I could look at that as well.
    2. This is why touchPriority is exposed, together with the whole swallowsTouches concept in cocos will allow whatever behavior you want without having rip anything apart.

    This bit of code has no UIGestureRecognizers in it; they might have advantages, but that's a whole other can of worms.

    @Stepan Generalov - That's the thing, it actually doesn't need to be a CCNode (that was particular to my situation); and if it doesn't need to be then it probably shouldn't be. I'll change that too.

    Along the same lines, it really doesn't need to be a Singleton and I think that would just limit you ultimately. I don't really see a specific need for 2 at a time but why limit it right?

    Posted 9 months ago #
  28. Chris.A
    Member

    @mobilebros - Thank you very much for your reply.

    >>1. Well not exactly, but I could look at that as well.

    It could be awesome to see that fixed. If you happen to fix it, please post the code here or update the class and make an announcement here.

    >>2. This is why touchPriority is exposed, together with the whole swallowsTouches concept in cocos will allow whatever behavior you want without having rip anything apart.

    I don't really understand how to control that. Can you help me with this example (it's your touch code from the AB-SpaceManager tutorial):

    -(BOOL) ccTouchBegan:(UITouch*)touch withEvent:(UIEvent *)event
    {
    CGPoint pt = [self convertTouchToNodeSpace:touch];
    float radiusSQ = 25*25;
     
    //Get the vector of the touch
    CGPoint vector = ccpSub(ccp(60,157, pt);
     
    //Are we close enough to the slingshot?
    if (ccpLengthSQ(vector) < radiusSQ)
    return YES;
    else
    return NO;
    }

    -(void) ccTouchMoved:(UITouch*)touch withEvent:(UIEvent *)event
    {
    CGPoint pt = [self convertTouchToNodeSpace:touch];
    CGPoint bombPt = ccp(60,166);
     
    //Get the vector, angle, length, and normal vector of the touch
    CGPoint vector = ccpSub(pt, bombPt);
    CGPoint normalVector = ccpNormalize(vector);
    float angleRads = ccpToAngle(normalVector);
    int angleDegs = (int)CC_RADIANS_TO_DEGREES(angleRads) % 360;
    float length = ccpLength(vector);
     
    //Correct the Angle; we want a positive one
    while (angleDegs < 0)
    angleDegs += 360;
     
    //Limit the length
    if (length > 25)
    length = 25;
     
    //Limit the angle
    if (angleDegs > 245)
    normalVector = ccpForAngle(CC_DEGREES_TO_RADIANS(245));
    else if (angleDegs < 110)
    normalVector = ccpForAngle(CC_DEGREES_TO_RADIANS(110));
     
    //Set the position
    _curBomb.position = ccpAdd(bombPt, ccpMult(normalVector, length));
    }

    -(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
    {
    CGPoint vector = ccpSub(ccp(60,166), _curBomb.position);
     
    if (_curBomb)
    [smgr morphShapeToActive:_curBomb.shape mass:30];
     
    [_curBomb applyImpulse:cpvmult(vector, 240)];
     
    [self setupNextBomb];
    }

    /////////////////////////////////////

    When I use this and the pan-zoom class, if I touch the bomb the layer underneath also moves. How can I stop that and have either the bomb or the layer moving separately?

    Posted 9 months ago #
  29. mobilebros
    Moderator

    @Chris.A

    It's actually this line in the init method you want to change:

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

    Change that to swallowsTouches:YES and give it a priority value that's less than the value you give to ViewControl.

    Dev update:

    I'm thinking now that the touchPriority property probably shouldn't exist; that information should be passed to enable along with the swallowsTouches information.

    Posted 9 months ago #
  30. mobilebros
    Moderator

    Dev update:

    I think you should be able to specify the window rect too, I can see cases where a side panel is visible and you'd want it to be handled correctly.

    Posted 9 months ago #

RSS feed for this topic

12…9Next »

Reply »

You must log in to post.

cocos2d for iPhone is proudly powered by bbPress.