0
votes

I am facing a problem yet again. So, I am making a game in corona. I want the object to move in a straight line to the touch coordinates. I know I can simple use the transition.to() function but physics engine doesn't work properly during transitions. I wrote the following code but of course, the circle doesn't move in a straight path.

function controls(event)
    if event.phase == "began" or event.phase == "moved" then
        follow = true
        touchX = event.x; touchY = event.y
    end

    if event.phase == "ended" then
        follow = false
    end
end

function playerMotion()
    if follow == true then
        if circle.y < touchY then
            circle.y = circle.y + 1
        elseif circle.y > touchY then
            circle.y = circle.y - 1
        end

        if circle.x < touchX then
            circle.x = circle.x + 1
        elseif circle.x > touchX then
            circle.x = circle.x - 1
        end
    end
end

Hope my question was clear enough.

3

3 Answers

0
votes

You are going need something more complicated than this function. What this does is simply "approach" the destination. It does not follow a straight path.

To accomplish what you want to do, you need to do a few things:

  1. Find the your position.
  2. Find the position of the destination.
  3. Calculate the horizontal distance from the start pos to end pos.
  4. Same, except for vertical.
  5. Now if you were to add this to your starting object, you would immediately be at the destination. How can we make it move slowly? Simply divide the vertical and horizontal distance by a "speed" variable. This is the rate that the object would move in one frame.
  6. For each frame, update the object by adding the x and y component you just found.
  7. Check if you have reached the destination. Repeat step 6 if necessary. (OR: keep track of how much horizontal and vertical distance you have traveled and compare that to the original result.)

There you have it!

0
votes

Try my sample app. You can use this or get an idea for your project.

You can also test this in a blank project to see how it works.

_W = display.contentWidth
_H = display.contentHeight

local physics = require("physics")

physics.start()
physics.setGravity(0,0)

local circle = display.newCircle(0,0,20)
circle.name = "circle"
circle.x = _W/2
circle.y = _H/2
circle.tx = 0
circle.ty = 0
physics.addBody(circle)
circle.linearDamping = 0
circle.enterFrame = function(self,event)
    print(self.x,self.tx)

    --This condition will stop the circle on touch coordinates
    --You can change the area value, this will detect if the circles's x and y is between the circles's tx and ty
    --If area is 0, it may not stop the circle, area = 5 is safe, change if you want to
    local area = 5
    if self.x <= self.tx + area and self.x >= self.tx - area and
       self.y <= self.ty + area and self.y >= self.ty - area then
        circle:setLinearVelocity(0,0) --set velocity to (0,0) to fully stop the circle
    end
end

--Add event listener for the monitoring the coordinates of the circle
Runtime:addEventListener("enterFrame",circle)


Runtime:addEventListener("touch",function(event)
    if event.phase == "began" or event.phase == "moved" then
        local x, y = event.x, event.y
        local tx, ty = x-circle.x, y-circle.y --compute for the toX and toY coordinates
        local sppedMultiplier = 1.5 --this will change the speed of the circle, 0 value will stop the circle

        --sets the future destination of the circle
        circle.tx = x 
        circle.ty = y

        circle:setLinearVelocity(tx*delay,ty*delay) --this will set the velocity of the circle towards the computed touch coordinates on a straight path.
    end
end)
0
votes

This is the math that will move the circle to the touch point:

    theta = atan2(touchY - circle.y,touchX - circle.x)
    velx = cos(theta)
    vely = sin(theta)
    circle.x += velx
    circle.y += vely

The velocity will approach 0 as the circle gets closer to the touch point.