Quick Links: Gideros Home | Download Gideros | Developer Guide
Dragging sprites along fixed path
  • 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.
  • antixantix +1 -1
    Member
    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 :)
    CircleMovement.zip
    3K
    Check out my DevBlog, my GitHub, and my games Falling Animals | Breaky Wall | Exetor
  • keszegh +1 -1
    Member
    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 +1 -1
    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.
    Check out my DevBlog, my GitHub, and my games Falling Animals | Breaky Wall | Exetor
  • antixantix +1 -1 (+4 / -0 )
    Member
    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 :)
    CircleMovement.zip
    5K

    Likes: pie, keszegh, hgy29, talis

    Check out my DevBlog, my GitHub, and my games Falling Animals | Breaky Wall | Exetor
  • 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 +1 -1
    Member 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
    Check out my DevBlog, my GitHub, and my games Falling Animals | Breaky Wall | Exetor
  • augustino_fp +1 -1 (+1 / -0 )
    Member
    Ok thanks alot for your help.

    Likes: antix

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Login with Facebook Sign In with OpenID

In this Discussion

Top Posters