Physics Tools Extension (Beta Release 4)

Rainbros

It's sometimes useful to use the push block to create custom gravity for actors. Would there perhaps be a simple way to modify this extension to work with that?

merrak

It's sometimes useful to use the push block to create custom gravity for actors. Would there perhaps be a simple way to modify this extension to work with that?

You can replace every call of the function getGravity( ) to return an actor's own custom gravity, but there are two catches:

1. You'll have to change the arguments to some of the functions to accept an actor as an argument
2. The actor's custom gravity would have to be implemented in the same way scene gravity is

There are roughly 20 getGravity( ) calls, and every function that contains one would need to have its arguments inspected to make sure it can handle the additional input. I don't think it'd be that hard to do--just tedious.

mdotedot

Hey Merrak,

This weekend I was playing around with your extension.

I'm a bit confused about the [ launch [actor] to x [] y: [] at angle [] ] block.

Only when I use the default Stencyl push-block  ( push [actor] sharply )  the actor follows the path, but what does launch actor do?!

In my code I have used another angle calculation which appears to be working with the default Stencyl-push-block.
How is the extension-angle block differently ?!?

(I know that this code can be optimized, but I wanted just one draw event to demonstrate) As you can see I tested with different angles, and I also tried using the [ launch  velocity ] block but I do not know how related all those blocks are. Are the results of the blocks part of the launch block or do we need to use them seperately?!?

Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

I'm a bit confused about the [ launch [actor] to x [] y: [] at angle [] ] block.
It automatically calculates the force according to any chosen angle.
So, you can choose any angle within a viable range.

« Last Edit: February 24, 2020, 11:12:49 am by LIBERADO »
I'm spanish, excuse me for my bad English.
I'm not a private teacher. Please, post your questions in the public forum.

merrak

As you can see I tested with different angles, and I also tried using the [ launch  velocity ] block but I do not know how related all those blocks are. Are the results of the blocks part of the launch block or do we need to use them seperately?!?

I had to look at the documentation to remember how it works... it's been a while since I've looked at this.

The 'angle' parameter may be misnamed. 'Aspect ratio' might do better. It calculates the force needed to launch a projectile at a target, like Liberado said.  But in addition, you also have to use the 'angle' parameter to tell it if you want a high arc or a shallow arc (like selecting which golf club you want to use).

You can see in the diagram how 'angle' is used to define the box the arc resides in. You probably don't want to set 'angle' to the angle between the launcher and the target, since then the arc would have to form a straight line to the target. You'll need to play around with the 'angle' parameter to find one that produces the arc you want. I'd suggest starting with the average of the straight-line angle to the target and 90 degrees. Set it higher if you need to lob a projectile over a wall between the two actors.

You can also use the arc ray-cast function in an AI routine, to check if 'angle' is high enough to clear any obstacles between the launcher and target. This was the use for the parameter I had originally intended. An NPC actor would need some control over the height of the arc.

mdotedot

Thanks LIBERADO and Merrak for the explanations.

@Merrak : Great Extension

I've made a small demonstration game that demonstrates most of the blocks.
The extension was investigated to see if I can use it in a multiplayer game. Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

airman4

awesomeness ! thanks ! and thanks to merrak too !

I've made a small demonstration game that demonstrates most of the blocks.
Good work!
I'm spanish, excuse me for my bad English.
I'm not a private teacher. Please, post your questions in the public forum.

mdotedot

Hello Merrak,

I'm trying to use it to interpolate the position of a phycsicball in a multiplayer environment.
I use physicsTools.trajectoryPosition3 to calculate the position that a physicsball will have when it hits a screenborder.
I need to adjust for time between the client and the server.
This is what happen when you don't take the network time into account: I'm trying to compensatie the time with the lagtime and using the pink circle as the new target after network update.

It now snaps to the new position. I've tried using a slide to block but the timing is different on each angle
and it kind of arcs between the two positions.

Then I used a way to predict the network time and used one of the positions in front of the actor (the purple circle). That looks like this: But I'm still not satisfied with the result: it still snaps too often

On the internet I've read that interpolation is used to compensate for the difference between client and server positions.
I tried to understand  https://en.wikipedia.org/wiki/Linear_interpolation and I can't find any timing in these forumulas.

Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

merrak

Glad you've found it useful so  far The formulas in the  Wikipedia article are for single-variable functions: y as a function of x. What would be more appropriate (and simpler) is a parametric approach: x and y as functions of t.

The x and y positions of an actor t seconds in the future should be:

x(t) = x0 + k * xvel * t
y(t) = y0 + k * yvel * t

where (x0, y0) is the current position of the actor, xvel and yvel the x and y velocities respectively, and k = 0.01. I think that is the right value for k. I'm a little rusty on this, but k should be the number of seconds per engine tick: 0.01.

You can use linear splines to accommodate for changes in direction. Suppose at time t0 the velocities were xvel0 and yvel0; and at time t1 the velocities changed to xvel1 and yvel1. Define range(a,b,c) as max(a, min( b, c ) ). Then

x(t) = x0 + k * xvel0 * range( 0, t - t0, t1 ) + k * xvel1 * max( 0, t - t1 )
y(t) = x0 + k * yvel0* range( 0, t - t0, t1 ) + k * xvel1 * max( 0, t - t1 )

If we define t2 to be some time in the far off future (+infinity or some arbitrary large number), we can modify the formula

x(t) = x0 + k * xvel0 * range( 0, t - t0, t1 - t0 ) + k * xvel1 * range( 0, t - t1, t2 - t1 )
y(t) = x0 + k * yvel0 * range( 0, t - t0, t1 - t0 ) + k * xvel1 * range( 0, t - t1, t2 - t1 )

This doesn't change the value, but would allow embedding it in a loop since both terms now use the same range( ) function. Suppose you now have a sequence of trajectories and corresponding velocities: (t0, xvel0, yvel0), (t1, xvel1, yvel1), (t2, xvel2, yvel2), ... Then use a loop to compute the positions

Code: [Select]
N = number of trajectories in (t0, xvel0, yvel0), (t1, xvel1, yvel1), (t2, xvel2, yvel2)
t_N = infinity or some arbitrarily large number

predicted_x = x0
predicted_y = y0

For each trajectory i:
predicted_x = predicted_x + k * xvel_i * range( 0, t - t_i, t_(i + 1) - t_i )
predicted_y = predicted_y + k * yvel_i * range( 0, t - t_i, t_(i + 1) - t_i )

I haven't tested the formulas, so at this point I can't guarantee they're correct. I just sketched them out over a few minutes. One nice feature is you would just need to sync the trajectory sequences between the client and server. Unfortunately, there is one significant issue I can think of: computing the time of collision.

If I remember correctly, when a collision occurs, Box2D will compute a time offset. If you use a collision event to stamp the time, chances are that time would place the ball into the wall. The collision data would have the offset you would want to add to time you recorded to obtain the proper t_i value. In your gifs, it looks like the sync is getting worse every time a ball bounces. This might be the reason why.

mdotedot

Hey Merrak,

Thank you for the formulas.
I'm still having a hard time dealing with the time-value. I assume the t-variables in your formula are TIME values.

To keep things simple, I now use one ball:  Your formulas did make a smoother path instead of the snap, but as you can see it still lags.

I have diffculty understanding the t, t0 and t1 in the formula.

The code block where you mentioned: N = number of trajectories in (t0, xvel0, yvel0), (t1, xvel1, yvel1), (t2, xvel2, yvel2)
Do you assume that I send all the positions calculated from the ' server ' to the client?!
I was hoping to keep the data send between the server and the client as minimal as possible.

Currently I only send position of the ball when it changes direction.
'actornr','xpos','ypos','xspeed','yspeed'
I experimented with the xpos and ypos using the predicted position = purple/pink circle.

The velocity is constant due to the fact that bounciness = 1.0 and friction = 0.0 and no physics setting on the scene.   I might want to play with those in the
future, but for now I want things to be as simple as can be.
That is why I set the same screen-bound-collision-behavior on the 'orange' ball as the 'black' ball.

Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

merrak

Just to clarify: t is time (you're correct there). t0 is the time that the ball begins its trajectory in the xvel0, yvel0 direction. t1 is the time that the ball begins its trajectory in the xvel1, yvel1 direction, and so on. If you use these formulas to predict the ball's position t seconds on the future, t0 will always be 0. t1 and onward would be the times of impacts.

The t1, t2, etc. values are the ones that might have to be adjusted using the "offset" that I mentioned earlier.

The client-server communication side of this problem isn't something I know much about. I can think of a few ideas, but you have a lot more experience with this than I do.

I imagine you could use the Physics Tools to compute the times (t1, t2, t3,...) at which the ball will impact a wall, along with the velocities after each impact. I'm not sure how you would use that information, though. When the server sets the ball in motion, it can send this data to the client... but by the time the client receives it, the ball (on the server end) has already moved some. Unless the lag is severe, it shouldn't be off by much--so you could use tweens to move the ball a little faster along the spline "track"... I'm assuming, then, that all of the physics calculations are handled on the sever-side only and the client is only seeing a "doodads" actor that only moves where the server tells it to. If both actors are interacting with the physics model, then that's a lot of data to keep aligned. I think the trick here isn't so much to minimize the amount of data sent to the sever and back, but also minimize how much data needs to be kept in sync.

mdotedot

Hey Merrak,

Thanks again for the explanations.

I might get back to the time-sending-mechanism.
You also make a good point about predicting path of object AFTER the collision. I might visit that mechanism later.

For now I have made something some progress. I'm not going for perfect alignment since what I've read on the internet and
encountered you will never be perfect in physics based multiplayer environments.
I was merely trying to figure out what everybody meant by ' interpolation ' . Your extension + explanations helped tremendous with that.

I have to do a lot more testing and experimentation with more collisions, player input and other things but I made progress.

Your formulas helped by removing the snap-behaviour and the transition is much smoother now. I don't mind that the path is altered! Code used (a bit of Merrak and a bit of Stencyl) Edit:    Running 8 clients (one of which is Windows executable) I switched the ' server ' to another client : that is why the black circles are then on the second window

« Last Edit: March 10, 2020, 04:31:37 am by mdotedot »
Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

mdotedot

Hi Merrak,

Today I wanted to use your awesome toolkit again for a NON-phyisics game. Yeah I know that this is a physics tools extension.
But I could really use the flightTime component. That gave an error.

It is caused by the gravity being 0.0.

Code: [Select]
// 1. Figure out the needed horizontal velocity.
var arcHeight:Float = Math.abs( x2 - x1 ) * Math.tan( -1 * angle * Math.PI / 180 )+0.01; // M.E. : avoid infinity / divide by zero later on

...

var a:Float = gy == 0.0 ? 0.01  : 0.5 / gy; // M.E. : infinity check (divide by zero)

...

// 3. Find number of steps to reach target's height
a = gy == 0.0 ? 0.01  : 0.5 / gy; // M.E. : infinity check (divide by zero)

Maybe I should change the 0.01 to a lower number, but you are the math-wizard and let you decide.

Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.