Use image_xscale to slow down speed GameMaker Studio - game-maker

Using the image_xscale that increases every time an object collides with a certain object, how can I make its speed go down using the increasing image_xscale? An example would be in agar.io, where circles slow down as they get bigger. What equation using the image_xscale would I use for this?
I've tried things like this:
speed = image_xscale * -speed
but that doesn't work. Any ideas?

You can use something like:
speed = start_speed - image_xscale * k;
where start_speed is your normal speed, without slowing.
and k is value which will define slowing factor.
Also you can add max() for define minimal possible speed (for speed can't equal to 0):
speed = max(1, start_speed - image_xscale * k);
speed = max(1, 10 - image_xscale * 0.5);

Related

Theta time complexity for loop

What would be the time complexity for this kind of loop in theta notation?
for (j=1; j< n^3 ; j=3*j)
Is it logn^3?
I understand independently when to use logn and when to use n^x but when combining them together, I seem to have an issue understanding the outcome.
Yes, you are right.
But note that
Log(n^3) = 3 * Log(n)
so complexity is Theta(Log(n)), because constant factor doesn't affect on asymptotic behavior.

Closing towards a point, independent of the frame rate?

I'm making a Camera class in 3D that closes in towards a point, slowing down and easing into stopping. To do this regularly is pretty simple:
// positions are vectors, dampening is a scalar, usually set to ~0.9
currentPosition += (targetPosition - currentPosition) * dampening;
However, this is locked to the framerate, assuming it's executed exactly once per frame.
How would one best implement this behaviour that's dependent on time, instead of frame rate or times executed?
A short experiment (and if you need a bit of induction) shows that after n frames you are at
targetPosition*(1 - (1 - dampening)^n) + currentPosition*(1 - dampening)^n
so to make this time-dependent, write
targetPosition*(1 - pow(1 - dampening, t)) + currentPosition*pow(1 - dampening, t)
where dampening is now per unit of time, and time might even be fractional.
Your question reminds me of Calculate speed by distance and friction.

Frequency Shift without Intermediate Buffer using IPP

I have a buffer full of real/imaginary sample values of a signal, and would like to shift the signal in the frequency domain by multiplying a sinusoid.
I see myself with four options:
some IPP function (I could not find one though)
manually calculate the result (probably slower than IPP)
generate the sinusoid in a separate buffer (probably requires lots of memory)
generate parts of the sinusoid in a separate buffer (requires recalculating the tone buffer)
I'm wondering what would be the best approach here, and/or whether I have just missed that there is a readymade function for frequency shifting a complex signal.
If you are going for speed, do it in the frequency domain.
FFT -> circular shift by N bins -> IFFT
I have found the ffw++ wrapper quite handy.
If you are really set on doing it in the time domain, you could use Intel's VML functions in some fashion like this:
// Create a single period of frequency offset wave
vector<complex<float> > cxWave(period);
for(int i = 0; i < period; ++i)
cxWave = i * 2 * M_PI / period;
vcExp( period, &cxWave.at(0), &cxWave.at(0) );
// Multiply entire signal by the complex sinusoid
for(int frame=0; frame < numFrames; ++frame)
{
vcMul( period, &input.at(frame*period), &cxWave.at(0), &cxWave.at(0) );
}
You would of course need to fill in the blanks.

How do I correctly use Recursion in MATLAB?

I have a simple m file that I have created as a recursive function:
function[velocity] = terminal(m,c,t,vi)
%inputs:
% m = mass
% c = coeffcient of drag
% t = time
% vi = initial velocity
if t==18, velocity = vi+(9.8-c/m*(vi))*2;
return
end
velocity = vi+(9.8-c/m*(vi))*2;
velocity %used to print out velocity for debugging
terminal(m,c,t+2,velocity);
end
The calculation of velocity is being done correctly as it prints out every recursion. However the "ans" that is returned at the end is the first calculated value of recursion. My question is how do I correctly setup a matlab function recursively? Or can it be done, and is it better to use a loop?
Although my answer will stray away from programming and into the realm of calculus, it should be noted that you can solve your problem both without recursion or a loop since you can exactly solve for an equation v(t) using integration. It appears that you are modeling Stokes' drag on a falling body, so you can use the fourth formula from this integration table to compute a final velocity vFinal that is achieved after falling for a time tDelta given a starting velocity vInitial. Here is the resulting formula you would get:
vFinal = 9.8*m/c + (vInitial - 9.8*m/c)*exp(-c*tDelta/m);
This will be a more accurate answer than approximating vFinal by making sequential steps forward in time (i.e. the Euler method, which can display significant errors or instabilities when the time steps that are taken are too large).
Bear with me, haven't done a lot of Matlab for some time now.
But I would simply call your function iteratively:
velocity = vi
for t = 0:2:18
velocity = velocity+(9.8-c/m*(velocity))*2;
end
Then for each instance of t it would calculate velocity for a given initial velocity and update that value with it's new velocity.
To have it take incremental steps with a size of 2, simply add your step size to it.
Updated in response to the comments
velocity = terminal(m,c,t+2,velocity)
should work.
The problem with recursion here is it adds function call overhead for each time through. This will make your code far slower and less efficient in matlab. Use a loop instead and you will be far ahead of things. Yes, there are cases where recursion is a valuable tool. But in many cases a carefully written loop is the better solution.
Finally, when you DO use recursion, learn when to apply tools like memoization to improve the behavior of the algorithm. Memoization simply means to not recompute that which you have already done. For example it is possible to use recursion for a fibonacci sequence, but this is a terribly inefficient way to do so.
The return value of your function is velocity. Matlab will return the last value assigned to velocity in the function body. Even though velocity is assigned deeper into the recursion, this doesn't matter to Matlab.
velocity in the next call to terminal() is a different variable!
Changing the final line to
function[velocity] = terminal(m,c,t,vi)
%inputs:
% m = mass
% c = coeffcient of drag
% t = time
% vi = initial velocity
if t==18, velocity = vi+(9.8-c/m*(vi))*2;
return
end
velocity = vi+(9.8-c/m*(vi))*2;
velocity %used to print out velocity for debugging
velocity = terminal(m,c,t+2,velocity);
end
Gives the expected result.

Simple physics-based movement

I'm working on a 2D game where I'm trying to accelerate an object to a top speed using some basic physics code.
Here's the pseudocode for it:
const float acceleration = 0.02f;
const float friction = 0.8f; // value is always 0.0..1.0
float velocity = 0;
float position = 0;
move()
{
velocity += acceleration;
velocity *= friction;
position += velocity;
}
This is a very simplified approach that doesn't rely on mass or actual friction (the in-code friction is just a generic force acting against movement). It works well as the "velocity *= friction;" part keeps the velocity from going past a certain point. However, it's this top speed and its relationship to the acceleration and friction where I'm a bit lost.
What I'd like to do is set a top speed, and the amount of time it takes to reach it, then use them to derive the acceleration and friction values.
i.e.,
const float max_velocity = 2.0;
const int ticks; = 120; // If my game runs at 60 FPS, I'd like a
// moving object to reach max_velocity in
// exactly 2 seconds.
const float acceleration = ?
const float friction = ?
I found this question very interesting since I had recently done some work on modeling projectile motion with drag.
Point 1: You are essentially updating the position and velocity using an explicit/forward Euler iteration where each new value for the states should be a function of the old values. In such a case, you should be updating the position first, then updating the velocity.
Point 2: There are more realistic physics models for the effect of drag friction. One model (suggested by Adam Liss) involves a drag force that is proportional to the velocity (known as Stokes' drag, which generally applies to low velocity situations). The one I previously suggested involves a drag force that is proportional to the square of the velocity (known as quadratic drag, which generally applies to high velocity situations). I'll address each one with regard to how you would deduce formulas for the maximum velocity and the time required to effectively reach the maximum velocity. I'll forego the complete derivations since they are rather involved.
Stokes' drag:
The equation for updating the velocity would be:
velocity += acceleration - friction*velocity
which represents the following differential equation:
dv/dt = a - f*v
Using the first entry in this integral table, we can find the solution (assuming v = 0 at t = 0):
v = (a/f) - (a/f)*exp(-f*t)
The maximum (i.e. terminal) velocity occurs when t >> 0, so that the second term in the equation is very close to zero and:
v_max = a/f
Regarding the time needed to reach the maximum velocity, note that the equation never truly reaches it, but instead asymptotes towards it. However, when the argument of the exponential equals -5, the velocity is around 98% of the maximum velocity, probably close enough to consider it equal. You can then approximate the time to maximum velocity as:
t_max = 5/f
You can then use these two equations to solve for f and a given a desired vmax and tmax.
Quadratic drag:
The equation for updating the velocity would be:
velocity += acceleration - friction*velocity*velocity
which represents the following differential equation:
dv/dt = a - f*v^2
Using the first entry in this integral table, we can find the solution (assuming v = 0 at t = 0):
v = sqrt(a/f)*(exp(2*sqrt(a*f)*t) - 1)/(exp(2*sqrt(a*f)*t) + 1)
The maximum (i.e. terminal) velocity occurs when t >> 0, so that the exponential terms are much greater than 1 and the equation approaches:
v_max = sqrt(a/f)
Regarding the time needed to reach the maximum velocity, note that the equation never truly reaches it, but instead asymptotes towards it. However, when the argument of the exponential equals 5, the velocity is around 99% of the maximum velocity, probably close enough to consider it equal. You can then approximate the time to maximum velocity as:
t_max = 2.5/sqrt(a*f)
which is also equivalent to:
t_max = 2.5/(f*v_max)
For a desired vmax and tmax, the second equation for tmax will tell you what f should be, and then you can plug that in to the equation for vmax to get the value for a.
This seems like a bit of overkill, but these are actually some of the simplest ways to model drag! Anyone who really wants to see the integration steps can shoot me an email and I'll send them to you. They are a bit too involved to type here.
Another Point: I didn't immediately realize this, but the updating of the velocity is not necessary anymore if you instead use the formulas I derived for v(t). If you are simply modeling acceleration from rest, and you are keeping track of the time since the acceleration began, the code would look something like:
position += velocity_function(timeSinceStart)
where "velocity_function" is one of the two formulas for v(t) and you would no longer need a velocity variable. In general, there is a trade-off here: calculating v(t) may be more computationally expensive than simply updating velocity with an iterative scheme (due to the exponential terms), but it is guaranteed to remain stable and bounded. Under certain conditions (like trying to get a very short tmax), the iteration can become unstable and blow-up, a common problem with the forward Euler method. However, maintaining limits on the variables (like 0 < f < 1), should prevent these instabilities.
In addition, if you're feeling somewhat masochistic, you may be able to integrate the formula for v(t) to get a closed form solution for p(t), thus foregoing the need for a Newton iteration altogether. I'll leave this for others to attempt. =)
Warning: Partial Solution
If we follow the physics as stated, there is no maximum velocity. From a purely physical viewpoint, you've fixed the acceleration at a constant value, which means the velocity is always increasing.
As an alternative, consider the two forces acting on your object:
The constant external force, F, that tends to accelerate it, and
The force of drag, d, which is proportional to the velocity and tends to slow it down.
So the velocity at iteration n becomes: vn = v0 + n F - dvn-1
You've asked to choose the maximum velocity, vnmax, that occurs at iteration nmax.
Note that the problem is under-constrained; that is, F and d are related, so you can arbitrarily choose a value for one of them, then calculate the other.
Now that the ball's rolling, is anyone willing to pick up the math?
Warning: it's ugly and involves power series!
Edit: Why doe the sequence n**F** in the first equation appear literally unless there's a space after the n?
velocity *= friction;
This doesn't prevent the velocity from going about a certain point...
Friction increases exponentially (don't quote me on that) as the velocity increases, and will be 0 at rest. Eventually, you will reach a point where friction = acceleration.
So you want something like this:
velocity += (acceleration - friction);
position += velocity;
friction = a*exp(b*velocity);
Where you pick values for a and b. b will control how long it takes to reach top speed, and a will control how abruptly the friction increases. (Again, don't do your own research on this- I'm going from what I remember from grade 12 physics.)
This isn't answering your question, but one thing you shouldn't do in simulations like this is depend on a fixed frame rate. Calculate the time since the last update, and use the delta-T in your equations. Something like:
static double lastUpdate=0;
if (lastUpdate!=0) {
deltaT = time() - lastUpdate;
velocity += acceleration * deltaT;
position += velocity * deltaT;
}
lastUpdate = time();
It's also good to check if you lose focus and stop updating, and when you gain focus set lastUpdate to 0. That way you don't get a huge deltaT to process when you get back.
If you want to see what can be done with very simple physics models using very simple maths, take a look at some of the Scratch projects at http://scratch.mit.edu/ - you may get some useful ideas & you'll certainly have fun.
This is probably not what you are looking for but depending on what engine you are working on, it might be better to use a engine built by some one else, like farseer(for C#).
Note Codeplex is down for maintenance.

Resources