Imagine a list on your smartphone. If you scroll down and you stop scrolling the list will continue scrolling until the momentum is gone.
How would you implement something like that in love2d using the mouse. I have an object and I can grab the object and rotate it around its x,y and z axis. Depending on how fast I dragged it I want it to keep rotating until the momentum is gone when I release the mouse.
Kinetic scrolling
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Kinetic scrolling
Last edited by adge on Tue May 03, 2016 11:15 am, edited 1 time in total.
Re: Move after mousereleased
I would think to use a rotational velocity... I see 2 ways to go about this:
Either drag the mouse to adjust the velocity...
Or keep a table of mouse update positions, then when you release the mouse figure the average velocity over the last few frames.
Then after the fact, reduce the velocity incrementally per frame.
Either drag the mouse to adjust the velocity...
Or keep a table of mouse update positions, then when you release the mouse figure the average velocity over the last few frames.
Then after the fact, reduce the velocity incrementally per frame.
Re: Move after mousereleased
How would you do that in code. I really don't know how I would add data to a table every frame.
This obviously wouldn't work.
for i = 0, 100, 1 do
table = velocity
end
This obviously wouldn't work.
for i = 0, 100, 1 do
table = velocity
end
Re: Move after mousereleased
Maybe something like this could help.
- Attachments
-
- Scroll test.love
- (10.7 KiB) Downloaded 141 times
Re: Move after mousereleased
adge wrote:How would you do that in code. I really don't know how I would add data to a table every frame.
This obviously wouldn't work.
for i = 0, 100, 1 do
table = velocity
end
Code: Select all
-- First, declare the table:
_mousePos = {}
-- Then every update:
function love.update(dt)
local mx, my = love.mouse.getPosition()
-- Regulate size of table to say 10 frames:
if #_mousePos == 10 then table.remove(_mousePos, 1) end
_mousePos[#_mousePos+1] = {mx, my, dt}
end
Then when you release the mouse, check the average distance between all the table entries.
Re: Move after mousereleased
Ok but now the problem is that I don't know how to decrease the momentum over a couple frames.
I have this function:
Mousereleased is only called when the mouse is actually released so this code is only executed in one frame. How do I write this so that it keeps on for 1-2 seconds? I can't put mousereleased into love.update(). I thought about a timer but I think there is a much easier and better way.
In general I don't know how you would move an object without input from one point to another without just teleporting it to the end. A while or a for loop? But what if you wanted the object to move slower? You can't just do a for loop from 1 to 1000000000. That would be very power hungry.
I have this function:
Code: Select all
function love.mousemoved(x, y, dx, dy)
if mouseIsDown == true then
moveY3D = (x + dx - x) * 0.01
moveX3D = (y + dy - y) * 0.01
rotateY3D((x+dx-x) * 0.01)--* math.pi/36)
rotateX3D((y+dy-y) * 0.01)--* math.pi/36)
end
end
function love.mousereleased(x, y)
moveY3D = moveY3D - 0.00000001
moveX3D = moveX3D - 0.00000001
rotateY3D(moveY3D)
rotateX3D(moveX3D)
end
In general I don't know how you would move an object without input from one point to another without just teleporting it to the end. A while or a for loop? But what if you wanted the object to move slower? You can't just do a for loop from 1 to 1000000000. That would be very power hungry.
Re: Move after mousereleased
I think you need to learn about tweening. These are basically timers that make a variable go from a given value A to another given value B in a set time, with a certain progression curve. Look for example http://hump.readthedocs.org/en/latest/timer.html or viewtopic.php?f=5&t=77904
Re: Move after mousereleased
Yeah I will look into that. However I got it to work.
I just did this:
I thought it just had to work that way since it makes sense. If the mouse is released it stores the last direction vector of the mouses movement. Then in the update function it decrements these two values till they are 0.
Kinda strange is that if do:
It speeds up the whole thing and keeps spinning till it vanishes. Probably has to do something with the calculation because the values become 10^24 after some time if I use the wrong dampening factor.
There has to be some kind of end value implemented because moveY3D always gets divided and goes to 0 but never really reaches it. So this is a endless calculation.
For sure there is an more elegant way to solve this problem but I'm not smart enough
Feel free to play around. It's actually a bit funny.
Like always I have to zip up the .love to be able to post it.
I just did this:
Code: Select all
function love.update()
if mousereleased == true then
moveY3D = moveY3D / 1.05
moveX3D = moveX3D / 1.05
rotateY3D(moveY3D)
rotateX3D(moveX3D)
end
end
function love.mousemoved(x, y, dx, dy)
if mouseIsDown == true then
moveY3D = (x + dx - x)
moveX3D = (y + dy - y)
rotateY3D(moveY3D)--* math.pi/36)
rotateX3D(moveX3D)--* math.pi/36)
end
end
function love.mousereleased(x, y)
mousereleased = true
end
Kinda strange is that if do:
Code: Select all
moveY3D = moveY3D / 0.5
moveX3D = moveX3D / 0.5
There has to be some kind of end value implemented because moveY3D always gets divided and goes to 0 but never really reaches it. So this is a endless calculation.
For sure there is an more elegant way to solve this problem but I'm not smart enough
Feel free to play around. It's actually a bit funny.
Like always I have to zip up the .love to be able to post it.
- Attachments
-
- kinetic rotation.love.zip
- (4.17 KiB) Downloaded 103 times
Re: Kinetic scrolling
Doesn't work for me:
Anyway, yes, what you've implemented is an iterative exponential function. An exponential decay never reaches zero in theory (in practice it may, due to reaching the limit of the precision of floating-point numbers). See https://en.wikipedia.org/wiki/File:Plot ... -decay.svg - that's the shape of the function you've implemented.
Imagine you divide by 10 every iteration, and the starting speed is 1. In the next frame, it will be 1 / 10 = 0.1; in the next, 0.1 / 10 = 0.01, then 0.001, then 0.0001, then 0.00001 and so on. It's easy to see that it will never reach zero (in theory).
Note that dividing by 0.5 is the same as multiplying by two. If you double the number every iteration, it will grow and grow exponentially, and it's quite likely to cause overflows pretty soon. For the value to be reduced every frame, you have to multiply by some number less than 1 (or equivalently, divide by some number greater than 1). For the value to grow every frame, you have to multiply by some number greater than 1 (or equivalently, divide by some number less than 1). If you multiply or divide by 1, the value obviously won't change.
The iterative approach has the problem that it's frame-rate-dependent, unlike the tweening approach that I suggested. The speed will be different depending on the frame rate, e.g. my video card supports 60 and 75 Hz modes, so it will run at a different speed in each, and in some old buggy cards that don't support vsync (or if you disable vsync), it will run uncontrolled. I haven't done the math to adjust it so it adapts to a given dt.
Code: Select all
Error: main.lua:4: module 'object' not found
Imagine you divide by 10 every iteration, and the starting speed is 1. In the next frame, it will be 1 / 10 = 0.1; in the next, 0.1 / 10 = 0.01, then 0.001, then 0.0001, then 0.00001 and so on. It's easy to see that it will never reach zero (in theory).
Note that dividing by 0.5 is the same as multiplying by two. If you double the number every iteration, it will grow and grow exponentially, and it's quite likely to cause overflows pretty soon. For the value to be reduced every frame, you have to multiply by some number less than 1 (or equivalently, divide by some number greater than 1). For the value to grow every frame, you have to multiply by some number greater than 1 (or equivalently, divide by some number less than 1). If you multiply or divide by 1, the value obviously won't change.
The iterative approach has the problem that it's frame-rate-dependent, unlike the tweening approach that I suggested. The speed will be different depending on the frame rate, e.g. my video card supports 60 and 75 Hz modes, so it will run at a different speed in each, and in some old buggy cards that don't support vsync (or if you disable vsync), it will run uncontrolled. I haven't done the math to adjust it so it adapts to a given dt.
Re: Kinetic scrolling
God I'm an idiot! Of course dividing by below 1 increases! Jesus!!!!
This one should work. *zipping the zip*
1,2,3 loads different models.
This one should work. *zipping the zip*
1,2,3 loads different models.
- Attachments
-
- kinetic scrolling.love.zip
- (15.83 KiB) Downloaded 133 times
Who is online
Users browsing this forum: Google [Bot] and 4 guests