Making object locked to a circle "follow" mouse - lua

I'm making a circle pong game (where there's only one paddle and you move in a circle with the ball spawning in the middle of the circle)
Currently, I've almost everything down but I feel like using the keyboard to move the paddle is too slow and I cannot find any "middle" value where it's not too fast or slow
I saw some other examples of this game using the mouse to control the paddle but I have no idea how to do such a thing.
This is my update function for the paddle (sorry if the way I handle updating is ugly):
pad:update(
function(dt,self)
local mouseX,mouseY=love.mouse.getPosition()
self.rot=math.atan2((400 - self.x), -(300 - self.y))
--self.rot=math.atan2((mouseX - self.x), -(mouseY - self.y))
self.x = circleRadius*math.cos(self.r) + self.orgX;
self.y = circleRadius*math.sin(self.r) + self.orgY;
if love.keyboard.isDown("a") then
self.r=self.r+4*dt
end
if love.keyboard.isDown("d") then
self.r=self.r-4*dt
end
end,
dt
)
The above code is inside love.update and sends a function as an argument to pads update function, which then calls that function, giving it the correct arguments like self and dt.
r is basically the position of the paddle on the circle

Got it by setting the current position on the circle (r) to the angle between mouse and the centre of the circle (which in my case is the centre of the window which is 800x600)
self.r=math.atan2((400-mouseX), -(300-mouseY))+math.rad(90)

Related

How to change the velocity in each frame in Love2D?

I'm trying to code a Pong game on Lua using the framework Love2D with some extra features. Among others, I want curves to occur. In order to do so, I'm trying to implement the trajectory of horizontally launched projectiles. I have a ball table with a position attribute for x (ball.x) and another for y (ball.y). I, also, have a an attribute for the x velocity (ball.dx) and another for the y velocity (ball.dy). Finally, I have an acceleration variable (gravity)
In my game, if the paddle moves and the ball hits it, the ball should follow and horizontal curve. In order to create my curves, I want to change the y-axis velocity on each frame in order to make my ball move in an arc across the screen. The main issue that I have is that I don't know how to change this velocity in each frame in order to create the expected arc. The most recent attempt that I made was to create a while loop like the following code. However, it creates an infinite loop. Can someone enlighten me please?
Clarification:
-Player.x and player.y are the player coordinate
-Player2.x and Player2.y are the opponent coordinate
-This piece of code is inside another if statement detecting a collision. It is inside the love.update(dt) function.
Thank you so much!
if love.keyboard.isDown("up") and distanceBetween(ball.x,ball.y,player.x,player.y)>30 then
ball.dy=0
while CollisionDetector(ball.x,player2.x,ball.y,player2.y, player2.width,player2.height,ball.size)==false or ball.x>0 or ball.y-20>0 or ball.y+20<love.graphics.getHeight() do
ball.dy=ball.dy+gravity*dt
ball.y=ball.y+ball.dy
end
end
I believe the snippet you've provided is a part of love.update function. (At least it should be.) That function is supposed to perform a single step of the game at a time and return. It is not supposed to handle the whole flight in a single call.
In your particular case, while loop expects the ball to move, but that is not something that will happen until the loop and encompassing function end.
In general, to simulate ongoing processes you'll have to store the information about such process. For example, if you want gravity be dependent on the paddle movement direction, then you'll have to modify the corresponding variable and store it between the call.
In your code, there are multiple other design flaws that make it do not what you think it should do. With some functions and code parts left to be implemented by yourself, the code outline would look as follows:
function collides(ball,player)
return (ball.x,player.x,ball.y,player.y, player.width,player.height,ball.size)
end
function love.update(dt)
handle_paddle_movements()
--handle the ball-paddle interaction
if collides(ball,player1) or collides(ball,player2) then
ball.dx=-ball.dx
if love.keyboard.isDown("up") then
--store the info you need to know about the interaction
ball.d2y = -gravity
else if love.keyboard.isDown("down")
ball.d2y = gravity
else
ball.d2y = 0
end
end
handle_the_wall_collision()
--ball movement code should be separate from collision handling
--concrete equations can be whatever you want
ball.x = ball.x+ball.dx*dt
ball.dy = ball.dy + ball.d2y * dt
ball.y = ball.y + ball.dy * dt
end

Gravity not working correctly

My code for physics in my game is this:
-- dt = time after each update
self.x = math.floor(self.x + math.sin(self.angle)*self.speed*dt)
self.y = math.floor(self.y - math.cos(self.angle)*self.speed*dt)
-- addVector(speed,angle,speed2,angle2)
self.speed,self.angle = addVector(self.speed,self.angle,g,math.pi)`
when it hits the ground, the code for it to bounce is :
self.angle = math.pi - self.angle
self.y = other.y - self.r`
the function addVector is defined here:
x = math.sin(angle)*speed + math.sin(angle2)*speed2
y = math.cos(angle)*speed + math.cos(angle2)*speed2
v = math.sqrt(x^2 + y^2)
a = math.pi/2 - math.atan(y,x)
return v,a
but when I place a single ball in the simulation without any drag or elasticity, the height of the ball after each bounce keeps getting higher. Any idea what may be causing the problem?
Edit: self.r is the radius, self.x and self.y are the position of the centre of the ball.
Your Y axis is increasing downward and decreasing upward.
Making self.y = math.floor(..) moves your ball a bit upward every frame.
The solution is to store your coordinates with maximal precision.
You could make new variable y_for_drawing = math.floor(y) to draw the ball at pixel with integer coordinates, but your main y value must have fractional part.
I’ve managed to get your code to run and reproduce the behavior you are seeing. I also find it difficult to figure out the issue. Here’s why: movement physics involves position, which is affected by a velocity vector, which in turn is affected by an acceleration vector. In your code these are all there, but are in no way clearly separated. There are trig functions and floor functions all interacting in a way that makes it difficult to see what role they are playing in the final position calculation.
By far the best and easiest-to-understand tutorial to help you implement basic physics lime this is The Nature of Code (free to read online, with interactive examples). As an exercise I ported most of the early exercises into Lua. I would suggest you see how he clearly separates the position, velocity and acceleration calculations.
As an experiemnt, increase g to a much higher number. When I did that, I noticed the ball would eventually settle to the ground, but of course the bouces were too fast and it didnt bounce in a way that seems natural.
Also, define other.y - it doesnt seem to affect the bouncing issue, but just to be clear on what that is.

Is it possible to change the x and y coordinates in a transition.to in Corona SDK

I'm having a hard time figuring this out. I want to make an object, in my case a ball,
local ball = display.newCircle(25,25,25)
ball.x = 160
ball.y = -80
to move from its starting coordinates to another spot, but then, after the action is completed I want it to immediately appear in another spot lets say x=90 and y= 120 and transition to another place. How can I do this with lua? Thank you in advance.
I am not sure if I understood you correctly.
Code below move ball from starting coordinates to destination coordinates. After ball reach its destination spot the x and y coordinate of ball are changed to x=90 and y= 120 and the second transition is called.
local function listener(self)
-- self== ball in this case
self.x = 90
self.y = 120
transition.to(self, {time=yourTime, x=newDestX, y=newDestY})
end
transition.to(ball, {time=yourTime, x=destX, y=destY, onComplete=listener})
For more information about transitions in Corona SDK read this.

CoronaSDK: display object static X (ignoring X impulses/forces) but changing Y

I am making a display object stay in one column on the screen in portrait mode with an anchor point such as
ball.anchorX = 0.5
ball is dynamic. Is there a way for it to stay in that X plane and so forces and impulses won't affect the ball.x value but do affect the ball.y value? If the ball hits a corner/ other object it will bounce off at an angle. I want the ball.x value to remain constant as I have obstacles approach the ball from the right and the ball must jump, thus I don't want to have to deal with X movement, only Y movement.
The easiest way is to re-assign your ball.x value in the enterFrame event (or your game loop).
For example to make it stay at the coordinate x = 500, do:
ball.x = 500

Corona SDK 'camera follow' stop at certain point?

I have all my display objects in a group called game. I also have this loop function so a 'camera' effect is created, so the camera follows the ball.
local function loop(x)
local targetx = 600 -ball.x
game.x = game.x + ((targetx - game.x) *0.05)
end
This setup gives a smooth follow of the ball, so the ball is not exactly in the middle of the screen all the time. My question is how to make the game stop following the ball after a certain point. I tried:
local function loop(x)
if ball.x < 600 and ball.x > 50 then
local targetx = 600 -ball.x
game.x = game.x + ((targetx - game.x) *0.05)
end
end
...but it gives a jerky return to following the ball after the ball exits, then returns into the 'following' area (x 50 to 600).
If your loop function is called in a timer, you could easily just cancel the timer / set x to the original x when your ball coordinates are under 50 or above 600.
You might check out Perspective - it's a library solely for virtual camera support for Corona that I wrote.

Resources