Hit the ball with touch (swipe)

Hi guys,
 
I have code in witch you can hit the ball with a swipe and it works nice when you swipe on a straight line and with a good speed, otherwise it’s not work nice at all. If you hit it on a curved line it goes not on the desire direction, if you hit it slow it will go slow, you can even stop the ball. 

Desirable result is simple to hit the ball and have it going on expected direction. And have the speed of the hit ball of a speed of swipe with a set minimum speed to prevent it from going to slow if it’s possible, otherwise just a constant speed. What is the ways to make it work nicely?

[lua]
local physics = require(“physics”)
physics.start()

local ball = display.newCircle(150, 10, 30)
physics.addBody(ball)
ball.gravityScale = 0

local function swipe(event)
local phase=event.phase
if phase == “began” then
elseif phase == “moved” then
local eventXMove = (event.xStart - event.x)*-6
local eventYMove = (event.yStart - event.y)*-6
ball:setLinearVelocity(eventXMove, eventYMove)
transition.cancel()
elseif phase == “cancelled” or phase == “ended” then
end
return true
end
ball:addEventListener(“touch”, swipe)

transition.to(ball, {time=3000, x=40, y=400})[/lua]

You need to normalise the swipe based on the start and end to work out the straight line velocity of the swipe.  Store the start point in “began” and then the end point in “ended”.  This should give you the straight path of the swipe.

The problem with storing end point in “ended” phase is that the object will not react to swipe till touch will be not released (ended). 

That is because you need to claim touch events outside the scope of the ball.  In “began” you need to set focus to your ball and then the “ended” event can happen off your object. Like Angry Birds.

The straight line doesn’t fix here anything. In example if a touch starts in the right of screen goes to the bottom and hits ball from the bottom by going up, ball will not go up, it will go somewhere on the left. If it just possible to get “start” point just before swipe (touch event) gets in contact with the object and end “point” after it was in contact for a short time, it should made process of ball hitting look realistically. 

If you want the swipe to start off the ball and end on the ball - like kicking a football - then you need a runtime event handler and not an object one.

If the user can swipe in any pattern before hitting the ball then you will need to calculate the swipe velocity (i.e. speed AND direction) in the “moved” phase and look at the last few stored touch points to extrapolate the current velocity.

Yes, but a runtime event makes object move even it haven’t been touched. I’m not quite sure how it need to be done to work properly. Any example?

If I can get coordinates when touch event collides with an object and use it instead of event.x(y)Start. I think using that point together with event.target.x(y) can solve the problem. Any?

Hi @gudrutis1,

If you want the touch to (in theory) start somewhere outside the ball, but only start calculating the swipe when the touch first intersects with the ball, you should not set focus on the ball and then listen for the first “moved” phase… that will occur when the touch slides over the region of the ball. Once you get the first “moved” phase, you can store that as a sort of pseudo-“began” point, then set focus on the ball so that, when the touch is released somewhere outside it, you still get the “ended” phase which you can use to calculate your swipe (using the pseudo-“began” along with the “ended” phase). Hopefully that makes sense. :slight_smile:

Best regards,

Brent

Hi Brent,

Thanks for an answer.

I’m looking here how to get and store both points in “moved” phase as I want object to start move before “ended” phase occur. First “moved” phase and last "moved phase points (where interaction with the ball happening) would be ideal. Or first “moved” phase point and point of coordinates after 1 second where moved phase occur. I see just those 3 points to make ball hitting look like ball hitting.

Hi @gudrutis1,

For case #1, you could detect the first “moved” phase as the starting point, and the “ended” phase as the ending point. In this case, you would not want to set focus on the ball, because that would look for touch points outside of its boundaries, and the “ended” might not fire until the touch was far outside the ball (I doubt you would want that to be used for the calculation).

For case #2, you could detect the first “moved” phase (using focus in this case), store that as point as your starting point, and then start a 1 second timer. Once the timer triggers, you would just check where the touch currently is and do your calculation from the starting point.

Hope that helps,

Brent

You need to normalise the swipe based on the start and end to work out the straight line velocity of the swipe.  Store the start point in “began” and then the end point in “ended”.  This should give you the straight path of the swipe.

The problem with storing end point in “ended” phase is that the object will not react to swipe till touch will be not released (ended). 

That is because you need to claim touch events outside the scope of the ball.  In “began” you need to set focus to your ball and then the “ended” event can happen off your object. Like Angry Birds.

The straight line doesn’t fix here anything. In example if a touch starts in the right of screen goes to the bottom and hits ball from the bottom by going up, ball will not go up, it will go somewhere on the left. If it just possible to get “start” point just before swipe (touch event) gets in contact with the object and end “point” after it was in contact for a short time, it should made process of ball hitting look realistically. 

If you want the swipe to start off the ball and end on the ball - like kicking a football - then you need a runtime event handler and not an object one.

If the user can swipe in any pattern before hitting the ball then you will need to calculate the swipe velocity (i.e. speed AND direction) in the “moved” phase and look at the last few stored touch points to extrapolate the current velocity.

Yes, but a runtime event makes object move even it haven’t been touched. I’m not quite sure how it need to be done to work properly. Any example?

If I can get coordinates when touch event collides with an object and use it instead of event.x(y)Start. I think using that point together with event.target.x(y) can solve the problem. Any?

Hi @gudrutis1,

If you want the touch to (in theory) start somewhere outside the ball, but only start calculating the swipe when the touch first intersects with the ball, you should not set focus on the ball and then listen for the first “moved” phase… that will occur when the touch slides over the region of the ball. Once you get the first “moved” phase, you can store that as a sort of pseudo-“began” point, then set focus on the ball so that, when the touch is released somewhere outside it, you still get the “ended” phase which you can use to calculate your swipe (using the pseudo-“began” along with the “ended” phase). Hopefully that makes sense. :slight_smile:

Best regards,

Brent

Hi Brent,

Thanks for an answer.

I’m looking here how to get and store both points in “moved” phase as I want object to start move before “ended” phase occur. First “moved” phase and last "moved phase points (where interaction with the ball happening) would be ideal. Or first “moved” phase point and point of coordinates after 1 second where moved phase occur. I see just those 3 points to make ball hitting look like ball hitting.