Author Topic: CLEAN camera transitions x,y to x,y  (Read 1274 times)

0 Members and 1 Guest are viewing this topic.

Tomfloria

  • Shrub
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 232
  • First iOS modder :D
CLEAN camera transitions x,y to x,y
« on: May 08, 2012, 06:11:43 PM »
Right, i've had a little chat with Alex and he's helped me quite a bit, he gave me this code which I changed a bit because it wasn't a function.

This is at the start of levellogic

Code: [Select]
 
    startTransition = true
    p = 0
    camX = GetCameraX()
    camY = GetCameraY()

    startX = camX
    startY = camY
    destX = 0
    destY = -3000

Code: [Select]
    while gamerunning() do

  if startTransition then
    p = p + 0.02
    if (p > 1) then
      p = 1
      startTransition = false

    end
    camX = startX + (destX - startX) * p
    camY = startY + (destY - startY) * p
    SetCameraPosition(camX, camY)
   
    end
   
    coroutine.yield()
    end
end

and then things get crazy... Whatdup. XD

Tomfloria

  • Shrub
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 232
  • First iOS modder :D
Re: CLEAN camera transitions x,y to x,y
« Reply #1 on: May 08, 2012, 06:12:27 PM »
I forgot to mention that the effect im going for is clean transitions from x,y to x,y, not just jumping from x,y to x,y

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 1,794
Re: CLEAN camera transitions x,y to x,y
« Reply #2 on: May 14, 2012, 03:49:56 PM »
Hmm.  I see what you are trying to do, and the code looks ok...


Lets work it out for some possible values.

Code: [Select]
   startTransition = true
    p = 0
    camX = GetCameraX()
    camY = GetCameraY()

    startX = camX
    startY = camY
    destX = 0
    destY = -3000

Lets use the following test values:

camX = 2000
camY = -3000
startX = 2000
startY = -3000
destX = 500
destY = 500


Then lets plug those into the code.

First we run this portion:
Code: [Select]
   while gamerunning() do

  if startTransition then
    p = p + 0.02
    if (p > 1) then
      p = 1
      startTransition = false
   end

startTransition is true, so on the first run through of this code, p (currently 0) will become 0.02.
P is not more than 1, so the If conditional is not triggered, and startTransition remains true.

p = 0.02
startTransition = true


Next we come to this part:
Code: [Select]
   camX = startX + (destX - startX) * p
    camY = startY + (destY - startY) * p
    SetCameraPosition(camX, camY)
  
    end

Lets focus only on the camX variable.
Remeber, startX = 2000 and destX = 500.

    camX = startX + (destX - startX) * p
becomes
    camX = 2000 + (500 - 2000) * 0.02
    camX = 2000 - 1500 * 0.02

Here there's a possible point where we could run into trouble...  it's not clear whether the sum should be (2000 - 1500) * 0.02 = 10, or if it should be 2000 - (1500 * 0.02) = 1970.

10 and 1970 are dramatically different results.  We want the X transition to start from 2000 and proceed toward 500.  So 1970 sounds more like it than 10!

I think the crazyness you are seeing is a result of Lua naturally choosing the wrong mathemathetical route, as per above, and ending up with stupid values like 10.

I think the calculation you should be doing is:

Code: [Select]
   camX = startX + ((destX - startX) * p)
    camY = startY + ((destY - startY) * p)

If you change those two lines to be like I have them there, I bet you it works. :>
« Last Edit: May 14, 2012, 06:41:42 PM by annikk.exe »

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 1,794
Re: CLEAN camera transitions x,y to x,y
« Reply #3 on: May 14, 2012, 06:05:57 PM »
You could also make this even better by smoothing the transition with a math.sin(p)


How would you do that?

You'd need to make a modification to this code:

Code: [Select]
   if (p > 1) then
      p = 1
      startTransition = false

    end

and to this code:

Code: [Select]
   camX = startX + ((destX - startX) * p)
    camY = startY + ((destY - startY) * p)


But first lets focus on the conceptual stuff.


What is it we want to do?  (in exacting detail..)

We want to move the camera from the current coordinates, to a new set of coordinates, with a smoothed motion.  At the beginning of the transition, the camera moves slowly, accelerating.  Halfway through the transition the camera has reached its maximum speed.  At the end of the transition the camera is slowing down, until it smoothly comes to a stop at the very end.

How do we implement that?

We can obtain the smooth motion by using a sine or cosine.


Consider this graph:



The good old up and down wavy motion.
Ok, here's what we're gonna do; the X-axis on this graph shall represent p, which is linearly increasing at a rate of 0.02 every game cycle, with there being 60 game cycles per second.

The y-axis shall represent a proportion of how much distance we move per cycle.

So to get a smooth transition, we start by hardly moving at all, then halfway through we're moving quite fast, then right at the end we slow down again to 0.
So it looks like the sine wave will work best for this:



It will work best because it starts at 0 on the vertical axis (no movement), then increases rapidly (accelerating), reaching its maximum speed at x = (math.pi() / 2), then slowing down, until at x = (math.pi()) it comes to a stop.
It perfectly describes the motion that we want for our transitions.  We just need to find a way to marry it to the amount of movement we want on any given transition.


In order to do that, we first need to know how many steps there will be in total.  Since we're proceeding at a rate of 0.02, and we need to reach the value of pi (3.14159265...), it will take us 157 game cycles to reach pi according to my calculator.

It's going to be annoying to recalculate this stuff later on if you decide to change the speed of the transition to something other than 0.02, so lets nip this in the bud right now and start expressing that value this way:


Code: [Select]
 
    startTransition = true
    p = 0
    speed = 0.02

    steps = math.pi() / speed

    camX = GetCameraX()
    camY = GetCameraY()

    startX = camX
    startY = camY
    destX = 0
    destY = -3000

Code: [Select]
   while gamerunning() do

  if startTransition then
    p = p + speed
    if (p > math.pi()) then
      p = math.pi()
      startTransition = false

    end
    camX = startX + ((destX - startX) * p)
    camY = startY + ((destY - startY) * p)
    SetCameraPosition(camX, camY)
  
    end
  
    coroutine.yield()
    end
end




During the transition we'll need to know how much to move by.  We'll split it into vertical movement and horizontal movement.

First we'll need to know the total distance to move.

We get that with:

Code: [Select]
(destX - startX)
Then, we can divide that by the number of steps to get the average amount moved per step:

Code: [Select]
((destX - startX) / steps)
This gives us an amount which we can multiply together with math.sin (which is going to be a value starting at 0, increasing to 1, then going back down to 0).

So how will that work?

If the value was always 1, then we'd just have steps number of cycles, each time the movement would be ((destX - startX) / steps) amount of movement.

Instead we have a value that starts on 0, increases to 1, then decreases again to 0.

So, hmm... how to solve that problem?
I'm not sure of it, but I would hazard a guess that if you multiply that math.sin by 2, you're going to end up with values ranging between 0 and 2, and that the average amount of movement per step will be the same as if the value was a constant of 1.

In other words, I think if you multiply your sine by 2, you're going to end up with the correct amount of movement in total.


I might be wrong about that, but lets try and put together an implementation anyway.  I'll leave you to troubleshoot it, if you wish.. :>


So we need to have:

Code: [Select]
(math.sin(p) * 2)
That should give us a value that ranges between 0 and 2 and 0 over the course of the transition.

Next we can put that together with the other stuff, to get this:


Code: [Select]
((destX - startX) / steps) * (math.sin(p) * 2)
That formula expresses how much we should move on each individual cycle, based on how far through the transition we are, what the start and destination coords are, and the number of steps (and thus the speed) in the transition.


So then we plug that into the code, and that gives us this:


Code: [Select]
   startTransition = true
    p = 0
    speed = 0.02

    steps = math.pi() / speed

    camX = GetCameraX()
    camY = GetCameraY()

    startX = camX
    startY = camY
    destX = 0
    destY = -3000


Code: [Select]
   while gamerunning() do

  if startTransition then
    p = p + speed
    if (p > math.pi()) then
      p = math.pi()
      startTransition = false

    end
    camX = startX + (((destX - startX) / steps) * (math.sin(p) * 2))
    camY = startY + (((destY - startY) / steps) * (math.sin(p) * 2))
    SetCameraPosition(camX, camY)
  
    end
  
    coroutine.yield()
    end
end



Hope you've been able to follow this ok.  Maybe you can see a little of my algorithm inventing process too...
I'd be interested to hear if it works.  :>

Please post any corrections below guys, I'll edit when I have time. :>
« Last Edit: May 15, 2012, 10:26:07 AM by annikk.exe »

Aino

  • Ent
  • ******
  • Thank You
  • -Given: 1
  • -Receive: 20
  • Posts: 1,483
  • They'll eat you next!
  • Eufloria: Yes
Re: CLEAN camera transitions x,y to x,y
« Reply #4 on: May 14, 2012, 08:23:16 PM »
Seems that you're talking about the Sine, not Cosine :)

Also, something I came up with just looking at your codes:

(It's just to show of an idea, it might not work!)
Code: [Select]

camX = startX + (destX - startX) * math.sin(GetCameraX()/destX*math.pi)
camY = startY + (destY - startY) * math.sin(GetCameraY()/destY*math.pi)


this should work immeadiatly when you allocate a new destination for X or Y, and it's give a smooth transition that Annikk was talking about. Though I don't know if the code works for the iOS version...

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 1,794
Re: CLEAN camera transitions x,y to x,y
« Reply #5 on: May 14, 2012, 08:26:08 PM »
Seems that you're talking about the Sine, not Cosine :)

You're right :>  I got the lines mixed up in the legend.
I'll edit. :>

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 1,794
Re: CLEAN camera transitions x,y to x,y
« Reply #6 on: May 15, 2012, 10:24:29 AM »
Also, something I came up with just looking at your codes:

(It's just to show of an idea, it might not work!)
Code: [Select]
camX = startX + (destX - startX) * math.sin(GetCameraX()/destX*math.pi)
camY = startY + (destY - startY) * math.sin(GetCameraY()/destY*math.pi)

Don't think that would work because it doesn't take the number of steps into account..  we need to know the average step length so that we can multiply it with the math.sin to get the smoothing.


I'm not sure mine will work either though.  Looking forward to hearing.. :>  I've done quite a bit of editing now so it's reasonably well explained, I think...

Aino

  • Ent
  • ******
  • Thank You
  • -Given: 1
  • -Receive: 20
  • Posts: 1,483
  • They'll eat you next!
  • Eufloria: Yes
Re: CLEAN camera transitions x,y to x,y
« Reply #7 on: May 15, 2012, 01:57:14 PM »

Don't think that would work because it doesn't take the number of steps into account..  we need to know the average step length so that we can multiply it with the math.sin to get the smoothing.


I'm not sure mine will work either though.  Looking forward to hearing.. :>  I've done quite a bit of editing now so it's reasonably well explained, I think...

I guess this one will:

Code: [Select]
time = 30
camX = startX + (destX - startX) * math.sin(GetCameraX()/destX*math.pi) / time
camY = startY + (destY - startY) * math.sin(GetCameraY()/destY*math.pi) / time

I should automatically adjust and us as long time as it needs :)

I'll test it out actually, just for fun :)

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 1,794
Re: CLEAN camera transitions x,y to x,y
« Reply #8 on: May 15, 2012, 02:51:18 PM »
You haven't defined Time...

annikk.exe

  • Achiever
  • Ent
  • ****
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 1,794
Re: CLEAN camera transitions x,y to x,y
« Reply #9 on: May 15, 2012, 02:52:54 PM »
See, here is where our strategies diverge, Aino.  I sit and think about the problem for ages, and use lots of diagrams and exercises and work out small bits of the puzzle, before finally using the conceptual understanding I've gained to piece all the parts of the puzzle together.... whereas you just come straight out with an attempt at a formula. :>

Aino

  • Ent
  • ******
  • Thank You
  • -Given: 1
  • -Receive: 20
  • Posts: 1,483
  • They'll eat you next!
  • Eufloria: Yes
Re: CLEAN camera transitions x,y to x,y
« Reply #10 on: May 15, 2012, 03:17:22 PM »
Well Annikk: my subconsciousness do a lot of math apparently, because suddenly I have a formula in my head which I don't know the origin of except some inspiration from other sources :)

Edit: And FYI: the formula works, but fails at some points... Going back to trigonometry! haha :)

Tomfloria

  • Shrub
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 232
  • First iOS modder :D
Re: CLEAN camera transitions x,y to x,y
« Reply #11 on: May 15, 2012, 04:00:22 PM »
Get you're codes right boys :D and who's code is right, and what am I adding haha

Tomfloria

  • Shrub
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 232
  • First iOS modder :D
Re: CLEAN camera transitions x,y to x,y
« Reply #12 on: May 15, 2012, 06:21:52 PM »
Right nerds :p going to try it!

Aino

  • Ent
  • ******
  • Thank You
  • -Given: 1
  • -Receive: 20
  • Posts: 1,483
  • They'll eat you next!
  • Eufloria: Yes
Re: CLEAN camera transitions x,y to x,y
« Reply #13 on: May 15, 2012, 06:30:35 PM »
Here you go

Tomfloria

  • Shrub
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 232
  • First iOS modder :D
Re: CLEAN camera transitions x,y to x,y
« Reply #14 on: May 15, 2012, 06:42:24 PM »
Right Have a look at this guys, This is what I've done....

Code: [Select]
function LevelLogic()
StartLevelLogic()

--CameraTest() --MAKE SURE THERE IS -- BEFORE ACTUAL RELEASE YOU IDIOT...
    startTransition = true
    p = 0
    camX = GetCameraX()
    camY = GetCameraY()

    startX = camX
    startY = camY
    destX = 0
    destY = -3000


foundAsteroid1 = false
foundAsteroid2 = false

--In the game there are messages and what not, but i've deleted them for this purpose

WaitReal(4)
    destX = 10000
    destY = 10000


WaitReal(4)
    destX = 20000
    destY = 20000



while GameRunning() do
if startTransition then
p = p + 0.02
if (p > 1) then
p = 1
startTransition = false
end
camX = startX + ((destX - startX) * p)
camY = startY + ((destY - startY) * p)
end
CheckConditions()
coroutine.yield()
end
end

I can safely say, nothing works haha, This is using Annikks first post. Havn't tried the others but Sin and Cos don't work.