Reputation: 57
I'm making a little game. It's a 2D game, and the main feature is to change the direction of gravity. I managed to change the direction, so now the player "falls" to the direction fo the gravity. But now i want the player to "stabilize" in eg. 2 seconds. I implemented basic rotation but that instantly changes the angle of the player, and i want it to "slice" the steps to smaller pieces so the rotation will be "smoother". eg. i want to change from 180° to 0° in small steps calculated from the delta time, in relation with a number I input which will be the "duration"
Im not quite familiar with radians and thats why i cant use it.
The gravity direction can be set using world.gravitydir variable, it can be 1,2,3,4. 1 is normal gravity "down" 2,4 is "left" and "right", and 3 is "up" I also have some "dev commands" to change the gravity direction manually using arrow keys
This is my attempt on rotating the player from upside down to normal smoothly.
function rotatePlayer(dt)
deg1 = player.rot -- player's current rotation
step = 0
deg2 = math.rad(0) -- desired rotation
step = (math.deg(deg1) - math.deg(deg2))*dt
for i = deg1, deg2 do
player.rot = player.rot - math.rad(step)
step = step - dt
end
end
playerrotation function is in gravity.lua , and the dev controller, and the player drawing function is in player.lua
Source: http://www.mediafire.com/download/3xto995yz638n0n/notitle.love
Upvotes: 2
Views: 956
Reputation: 8000
I've noticed a couple issues with your code.
deg2 = math.rad(0) -- desired rotation
0 radians is equivalent to 0 degrees, so it would seem deg2
is always zero, thus
for i = deg1, deg2 do
would only run when deg1
is equal to or less than zero, which likely means it isn't running as you intended.
Secondly, any variables that don't need to leave their scope should be localized. This is a Lua best practice. Your function could be rewritten with locals, for example:
function rotatePlayer(dt)
local deg1 = player.rot -- player's current rotation
local step = 0 -- ! Any reference to a "step" variable within the scope of this function will always refer to this particular variable.
local deg2 = 0 -- desired rotation
step = (math.deg(deg1) - math.deg(deg2))*dt
for i = deg1, deg2 do
player.rot = player.rot - math.rad(step)
step = step - dt
end
end
The following line is equivalent to multiplying the degrees of the player's rotation by the delta dt
, due to the previously established fact that deg2
is always zero.
step = (math.deg(deg1) - math.deg(deg2))*dt
The following lines are equivalent to taking the player's original rotation in degrees multiplied by the delta (step
) and subtracting the radians version of that off of the player's current rotation, then subtracting the delta dt
from the step
value, inside of a loop which is executed within a single game frame I might add. I wasn't sure if you were aware that loop is run within one frame.
player.rot = player.rot - math.rad(step)
step = step - dt
I'm not sure what your intention was with those operations, but maybe you can tell me more.
As for achieving a smoother animation, you'll need to scale down your rate and adjust how the rotation is carried out. I've rewritten your function as follows and hope that it, as an example, clarifies how this could be written better:
function rotatePlayer(dt) -- dt is seconds since last update
local current = player.rot -- player's current rotation in radians
local target = 0 -- desired angle in radians
local difference = target - current
if difference == 0 then -- nothing to be done here
return
end
local rate = math.pi / 4 -- radians turned per second (adjust as necessary)
local change = rate * dt -- r/s * delta(change in time)
if difference < 0 then
-- make change negative, since difference is as well
change = change * -1
-- If (current + change > target), settle for the lesser difference.
-- This keeps us from "overshooting" the player's rotation
-- towards a particular target.
change = math.max(change, difference)
else
change = math.min(change, difference)
end
player.rot = current + change
end
Please let me know if this resolves your problem and if you have any more questions.
Upvotes: 1
Reputation: 1017
I've put a change to player.lua on pastebin Stackoverflow Love2d game . It rotates the player at a fixed rate rather than a fixed time. To do the latter just make rottime constant.
Upvotes: 0