Search code examples
cocos2d-x

cocos2d-x Actor does not move to touch location


I am trying to make an actor follow the player's finger (long touch). I'm positive I have the math right, but the actor fails to move exactly to where the player touched.

Here is an illustration of my problem:

enter image description here

When the touch is near the top, the actor goes beyond the visible scene at the top. When the touch is near the bottom, the actor goes out of the visible scene at the bottom. Same goes for the left and right.

When the touch is performed in the middle of the scene the actor moves perfectly to the touch. In short, the further the touch is away from the middle the more pronounced the distance between the actor and the touch is. In other words; the closer the touch is to the middle, the closer the actor moves towards the touch.

Please note that when the touch was near the bottom or the top the distance between the touch and the actor was more pronounced then when the touch was on the right or the left; as the top/bottom are further from the mid point.

Here is the code used to follow the actor towards the touch:

Lang: Lua Lib: Cocosd2-x 3.1

local velocity = 1.4
local x, y = self.sprite:getPosition()
-- self.dest[X/Y] are cached coordinates to where the actor should move next.
local angle = math.atan2(touch.y - y, touch.x - x)
local deltaX = velocity * math.cos(angle)
local deltaY = velocity * math.sin(angle)
local newX = x + deltaX
local newY = y + deltaY
self.sprite:setPositionX(newX)
self.sprite:setPositionY(newY)

Things I've tried:

  • Changed the scale of background layer and sprites. No change
  • Changed the algorithm used to compute the angle. No change.
  • Created a red dot and set its position to the exact touch x/y to determine if there was some weird transformation issue when determining the actor's point. The red dot was always perfectly under the touch.

Solution

  • Discovered the issue. When I created the Actor sprite I set its z-index to 100. When I uncommented out the call that set the z-index, everything worked perfectly. In my situation, this particular sprite must always be above all other sprites. What I did to fix the issue is set the z-index much lower than what I had originally set it to; which ended up being 15.

    sprite:setPositionZ(15)
    

    From my observation it appears that the sprite is having some type of scale applied to its position the larger the z-index is of the sprite.

    Update 1

    Using :setPositionZ(int) will unnecessarily scale your sprite bigger in some cases. I now use :setGlobalZOrder(int) with much better success:

    sprite:setGlobalZOrder(15)