Short Version:

I am trying to move a player around on a tilemap, keeping it centered on its tile, while smoothly controlling it with SneakyInput virtual Joystick. My movement is jumpy and hard to control. What's a good way to implement this?

Long Version:

I'm trying to get a tilemap based RPG "layer" working on top of cocos2d-iphone. I'm using SneakyInput as the input right now, but I've run into a bit of a snag.

Initially, I followed Steffen Itterheim's book and Ray Wenderlich's tutorial, and I got jumpy movement working. My player now moves from tile to tile, without any animation whatsoever.

So, I took it a step further. I changed my player.position to a CCMoveTo action. Combined with CCfollow, my player moves pretty smoothly. Here's the problem, though: Between each CCMoveTo, the movement stops, so there's a bit of a jumpiness introduced between movements.

To deal with that, I changed my CCmoveTo into a CCMoveBy, and instead of running it once, I decided to have it CCRepeatForever. My plan was to stop the repeating action whenever the player changed directions or released the d-pad.

However, when the movement stops, the player is not necessarily centered along the tiles, as it should be. To correctly position the player, I use a CCMoveTo and get the closest position that would put the player back into the proper position. This reintroduces an earlier problem of jumpiness between actions.

What is the correct way to implement a smooth joystick while smoothly animating the player and keeping it on the "grid" of tiles?


It turns out that this was caused by a "Bug Fix" in the cocos2d engine.

  • \$\begingroup\$ Please add a tag "sneakyinput". \$\endgroup\$
    – Moshe
    Commented May 29, 2011 at 13:26
  • 1
    \$\begingroup\$ Sneakyinput is kind of irrelivant to this question. \$\endgroup\$ Commented May 29, 2011 at 20:15
  • \$\begingroup\$ @AttackingHobo Kind of irrelevant? He doesn't mention it a single time in his question. \$\endgroup\$ Commented Jun 28, 2011 at 20:33
  • \$\begingroup\$ I do mention it, read the long version again. \$\endgroup\$
    – Moshe
    Commented Jun 28, 2011 at 20:53
  • \$\begingroup\$ @Moshe No, no you did not... -1 for making me waste my time. \$\endgroup\$ Commented Jun 28, 2011 at 21:20

1 Answer 1


There are three ways to solve this problem :

  1. you can just implement update function for your player class and move it in that update function, this approch will eliminate use of CCMoveBy or CCMoveTo classes and you can easily control how you want the movement be applied, for example just wait until x or y is just in center of tile and then stop moving.
  2. The second approch is to just eliminate CCRepeatForever when you want to stop our player and then add CCMoveBy Directly to the player action list, this way you'll be sure that CCMoveBy will finish what all the movement you requested.
  3. And the last choice is to Implement your code to do what CCRepeatForever does, this is how CCRepeat for ever is implemented in c++, and I also added another if to make sure you have to repeat CCMoveBy just one more time.(sorry for c++ code I hope you can convert it to objective-c)

    void myCCRepeatForever::step(ccTime dt)
        if (direction is still the same)
            if (CCMoveByInstance->isDone())
                ccTime diff = dt + CCMoveByInstance->getDuration() - CCMoveByInstance->getElapsed();

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .