Rotating Image in a given time

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
neonoxd
Prole
Posts: 4
Joined: Thu Oct 17, 2013 9:20 pm

Rotating Image in a given time

Post by neonoxd »

Hello there.
I'm working on a game, and i'm trying to implement the basic mechanics. I implemented gravity, smooth movement using velocity, and changing the direction of gravity (which is the main feature of the game) and now i want to do the following:

When changing the direction of the gravity, i want the player to rotate to the given angle (the gravity direction can be the 4 directions: up down left right)
so i managed to instantly "flip" the player to the given angle, but i want "smooth" transition in a given time, eg. i want the player to "stabilize" according to the gravity direction in 1 second, but i am not too familiar with radians.

the gravity changing variable is world.gravitydir, if it equals to 1, then the gravity is normal, if it equals to 3 then the gravity is "upwards"
there are also "dev controls" for the gravity changing (keyboard up, down left right)

Here is my "attempt" of the smooth rotation from upside to down (yeah its not working.. :D)

Code: Select all

function rotatePlayer(dt)
deg1 = player.rot
step = 0

		deg2 = math.rad(0)
		
		step = (math.deg(deg1) - math.deg(deg2))*dt
		
			for i = deg1, deg2 do
				player.rot = player.rot - math.rad(step)
			end
end
löve file:
http://www.mediafire.com/download/3xto9 ... title.love
User avatar
Sheepolution
Party member
Posts: 264
Joined: Mon Mar 04, 2013 9:31 am
Location: The Netherlands
Contact:

Re: Rotating Image in a given time

Post by Sheepolution »

Code: Select all

function rotatePlayer(dt)

	if player.rot<math.rad(360) and player.rot>=math.rad(180) then
		player.rot = player.rot + 3 * dt -- Make 3 a higher number to turn faster
	end
	if player.rot>math.rad(0) and player.rot<=math.rad(180) then
		player.rot = player.rot - 3 * dt
	end

	if math.abs(player.rot-math.rad(0)) < 0.1 then
		player.rot = math.rad(0)
	end

end
Something like this. But instead of running the function when pressing down, you run the function when the gravity is down.

So

Code: Select all

	if love.keyboard.isDown("down") then
	setGravityDirection("down")
	--player.rot = math.rad(0)
	end

	if (world.gravitydir==1) then
		rotatePlayer(dt)
	end
And use dt for movement, to make sure your game is as fast on all devices. The player was out of screen in no time.

Code: Select all

player.x = player.x + player.xvel * dt
player.y = player.y + player.yvel * dt
User avatar
neonoxd
Prole
Posts: 4
Joined: Thu Oct 17, 2013 9:20 pm

Re: Rotating Image in a given time

Post by neonoxd »

Sheepolution wrote:Something like this. But instead of running the function when pressing down, you run the function when the gravity is down.
Aaah, thank you so much! it's working now, and now i kinda understood this thing.
I think I overcomplicated this in my head :D


And actually, player movement uses delta time, i just wanted to make the code a bit more dry-er:

this is the variable that will be substracted or added to player.x, or y
and player.speed can be adjusted :D

Code: Select all

	ydisplacePos = player.yvel + player.speed * dt
	ydisplaceNeg = player.yvel - player.speed * dt
	xdisplacePos = player.xvel + player.speed * dt
	xdisplaceNeg = player.xvel - player.speed * dt

oh btw, how can i give you karma? :D
User avatar
Sheepolution
Party member
Posts: 264
Joined: Mon Mar 04, 2013 9:31 am
Location: The Netherlands
Contact:

Re: Rotating Image in a given time

Post by Sheepolution »

I think they removed the karma from the website?

I haven't checked your code on that part, but it didn't work. If you can, try it on an other computer to see how fast it is.
User avatar
neonoxd
Prole
Posts: 4
Joined: Thu Oct 17, 2013 9:20 pm

Re: Rotating Image in a given time

Post by neonoxd »

Sheepolution wrote:I think they removed the karma from the website?

I haven't checked your code on that part, but it didn't work. If you can, try it on an other computer to see how fast it is.
oh okay ><

I will, but the player's speed will be adjusted anyway later, when i implement tiles and stuff

your code only works for rotating from upside to down, now i made it work in all 4 directions, but i had to manually "fix" the degree sometimes because its not too precise eg. sometimes i get 273,554654° instead of 270, so i made a "fix" that makes it "jump" from anything from >270 <275 to 270°

what can cause the "miscalculation" ?

code:

yeah well the code is not too 'dry' but it works >< :D

Code: Select all

function stabilizePlayer(dt)

	if world.gravitydir == 1 then
		if player.rot<math.rad(360) and player.rot>=math.rad(180) then
			player.rot = player.rot + 5 * dt -- Make 3 a higher number to turn faster
		end
		
		if player.rot>math.rad(0) and player.rot<=math.rad(180) then
				player.rot = player.rot - 5 * dt
		end
		
		
		if math.abs(player.rot-math.rad(0)) < 0.1 then
			player.rot = math.rad(0)
		end
		
		if player.rot > math.rad(360) then player.rot = math.rad(360) end
		if player.rot == math.rad(360) then player.rot = math.rad(0) end
		
	end
	
	if world.gravitydir == 3 then
		if player.rot>=math.rad(0) and player.rot<math.rad(180) then
			player.rot = player.rot + 5 * dt
		end
		if player.rot<=math.rad(360) and player.rot > math.rad(180) then
			player.rot = player.rot - 5 * dt
		end
		
		if math.abs(player.rot-math.rad(180)) < 0.1 then
			player.rot = math.rad(180)
		end
	end	
	
	if world.gravitydir == 2 then
		if player.rot>=math.rad(0) and player.rot< math.rad(90) then
			player.rot = player.rot + 5 *dt
		end
		if player.rot>math.rad(90) and player.rot<= math.rad(360) then
			player.rot = player.rot - 5 *dt
		end
		if player.rot > math.rad(85) and player.rot < math.rad(92) then
			if player.rot ~= 90 then player.rot = math.rad(90) end
		end
	end
	
	if world.gravitydir == 4 then
		if player.rot == math.rad(0) then player.rot = math.rad(360) end
	
		if player.rot <= math.rad(360) and player.rot > math.rad(270) then
			player.rot = player.rot - 5 *dt
		end
		if player.rot >= math.rad(180) and player.rot < math.rad(270) then
			player.rot = player.rot + 4 *dt
		end
		if player.rot >= math.rad(90) and player.rot < math.rad(270) then
			player.rot = player.rot + 5 *dt
		end
		
		if player.rot >= math.rad(270) and player.rot < math.rad(280) and player.rot~=math.rad(270) then
			player.rot = math.rad(270)
		end
		
	end
	
	
end
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Rotating Image in a given time

Post by micha »

neonoxd wrote:your code only works for rotating from upside to down, now i made it work in all 4 directions, but i had to manually "fix" the degree sometimes because its not too precise eg. sometimes i get 273,554654° instead of 270, so i made a "fix" that makes it "jump" from anything from >270 <275 to 270°

what can cause the "miscalculation" ?
Yes it can cause errors. If for some reason (like background activity) dt becomes very large, then it might happen that the angle increment is larger than 5 degrees. Then you could theoretically jump from 269.9 to 276.1 and you never reach the interval you check.

To make it safe, you need to know if you are currently increasing or decreasing the angle and then check only for one bound.
Let's say you change from 180 to 270 degrees. Then you do something like

Code: Select all

angle = angle + angularVelocity * dt
if angle > 270 then 
  angle = 270
  angleArrived = true
end
The variable angleArrived is then true which means that you don't need to update the angle anymore and you can skip the whole rotation thing (put an if-statement around everything):

Code: Select all

if not angleArrived then
-- stuff
end
Note: In the above code, it didn't you math.rad. Please add it, otherwise, it is incorrect.
User avatar
neonoxd
Prole
Posts: 4
Joined: Thu Oct 17, 2013 9:20 pm

Re: Rotating Image in a given time

Post by neonoxd »

micha wrote:
neonoxd wrote:your code only works for rotating from upside to down, now i made it work in all 4 directions, but i had to manually "fix" the degree sometimes because its not too precise eg. sometimes i get 273,554654° instead of 270, so i made a "fix" that makes it "jump" from anything from >270 <275 to 270°

what can cause the "miscalculation" ?
Yes it can cause errors. If for some reason (like background activity) dt becomes very large, then it might happen that the angle increment is larger than 5 degrees. Then you could theoretically jump from 269.9 to 276.1 and you never reach the interval you check.

To make it safe, you need to know if you are currently increasing or decreasing the angle and then check only for one bound.
Let's say you change from 180 to 270 degrees. Then you do something like

Code: Select all

angle = angle + angularVelocity * dt
if angle > 270 then 
  angle = 270
  angleArrived = true
end
The variable angleArrived is then true which means that you don't need to update the angle anymore and you can skip the whole rotation thing (put an if-statement around everything):

Code: Select all

if not angleArrived then
-- stuff
end
Note: In the above code, it didn't you math.rad. Please add it, otherwise, it is incorrect.
haha thanks, i did something similar, but i forgot to update this post :D
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 6 guests