문제

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

도움이 되었습니까?

해결책

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.

다른 팁

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top