Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
Dragging sprites along fixed path — Gideros Forum

Dragging sprites along fixed path

augustino_fpaugustino_fp Member
edited July 2017 in General questions
Hi all,

I am currently developing a game and have a question regarding dragging sprites. I am fairly confident with how to use the touch events to drag a sprite according to the touch x,y coordinates, however I need to be able to constrain the possible motion of the sprite to a fixed path. More specifically I am looking to implement game mechanics in which the user can drag a sprite, but only in a circular motion (like turning a wheel). Is anyone aware of how I might implement this? Thanks for any information you can provide.

Comments

  • antixantix Member
    edited July 2017
    Here is a small example (attached) I made..

    When you drag your finger on the display it just increments/decrements an angle variable (from 0 to 360). It then uses that angle to draw the ball at the angle and radius from the balls origin (if that makes sense) ;)
    local touchX -- where the display was last touched
     
    local ball = Bitmap.new( Texture.new("ball.png") )
    ball:setAnchorPoint(0.5, 0.5)
    ball.angle = 0 -- current angle
    ball.radii = {x = 80, y = 80} -- separate values so we can have ellipses (not just circles)
    ball.origin = {x = 160, y = 240} -- origin on screen
    ball.position = {x = 0, y = 0}
    stage:addChild(ball)
     
    function ball:update() -- update balls position on screen
      local cos, sin, degToRad = math.cos, math.sin, math.pi/180
     
      local a, o, r, p = self.angle, self.origin, self.radii, self.position
     
      local x = r.x * sin(a * degToRad) + o.x -- calculate new position
      local y = -r.y * cos(a * degToRad) + o.y
     
      self:setPosition(x, y) -- update on display
     
      p.x, p.y = x, y
    end
     
    local function onTouch(e) -- handle touch
      e:stopPropagation()
      touchX = e.touch.x -- only need to save x touch position
    end
     
    local function onDrag(e) -- handle drag
      e:stopPropagation()
      local tX = e.touch.x
      local dX = touchX - tX -- how much we moved our finger since last time
      touchX = tX  
     
      ball.angle = (ball.angle - dX) % 360 -- update ball
      ball:update()
    end
     
    stage:addEventListener(Event.TOUCHES_BEGIN, onTouch) -- touch event listeners
    stage:addEventListener(Event.TOUCHES_MOVE, onDrag)
     
    ball:update() -- start ball in correct position on display
    That should be enough to steer you in the right direction :)
    zip
    zip
    CircleMovement.zip
    3K
  • perhaps it would be even more intuitive if you'd need to rotate your finger around the center of the wheel.
    for this you can check the angle defined by these 3 points: where touch begins, the center of the wheel and where touch move is currently registered. and then simply rotate your wheel with the same angle.
  • antixantix Member
    @keszegh I thought @augustino_fp wanted something you just dragged, not rotated. I think rotation would be pretty easy also, it's just a matter of determining what angle your finger is inside the circle in relation to the center if the circle, hmm.
  • antixantix Member
    edited July 2017
    So I thought about it a bit more and made another example. there are now two classes, Dial and Ball.

    The dial is just a simple dial that you can twirl about as @keszegh suggested. It just uses setRotation() to do that but shows you how to find the touch angle inside a circle at least.

    The Ball class is a little more complex and a ball can be either a "drag" ball which behaves like the first example, or a "dial" ball which behaves like @keszegh originally meant (I hope)

    The code isn't too commented so yell out if you don't get anything in there :)
    zip
    zip
    CircleMovement.zip
    5K

    Likes: pie, keszegh, hgy29, talis

    +1 -1 (+4 / -0 )Share on Facebook
  • Thank you both for your answers! I am currently at work but will take a detailed look at all these when I can. I may not have explained myself properly but essentially I am moving angular blocks around in a circle, so I wouldn't be rotating the sprite itself, but rather rotating/dragging it around a fixed path at a certain radius from the "origin" of the circle, if that makes sense.
  • antixantix Member
    edited August 2017 Accepted Answer
    @augustino_fp if you will be dragging these blocks using a left/right drag of your finger on the device then the first example does that. If you want to rotate the block as it moves in it's circular path then change the update function to...
    function ball:update() -- update balls position on screen
      local cos, sin, degToRad = math.cos, math.sin, math.pi/180
     
      local a, o, r, p = self.angle, self.origin, self.radii, self.position
     
      local x = r.x * sin(a * degToRad) + o.x -- calculate new position
      local y = -r.y * cos(a * degToRad) + o.y
     
      self:setPosition(x, y) -- update on display
     
      self:setRotation(a) -- <<< this makes it rotate
     
      p.x, p.y = x, y
    end
  • Ok thanks alot for your help.

    Likes: antix

    +1 -1 (+1 / -0 )Share on Facebook
Sign In or Register to comment.