#Ball bounce with fake height in tennis game 2D

1 messages ยท Page 1 of 1 (latest)

robust sky
#

Man, I love this challenge! I have a few thoughts. I'll text you back from the computer later today, I'm on my phone right now

robust sky
#

I have a few ideas:
1- Actually simulate the ball trajectory. Once the ball is hit by the paddle, create the new velocity vector and then either use the physics engine to let the ball fly, or simulate it yourself (calculate the accelerations based on the forces like air drag, gravity, integrate the acceleration to find speed, and impose this new speed in the dynamic rigid body). This would make the game realistic, but since the game is 2d, it doesn't make a lot of sense.
2- Establish the ball initial point (where it's hit by the paddle) and arbitrarily establish the final point (based on where it is, the angle that it was hit and by how strong it was hit by the paddle), and just interpolate from one point to another using Vector3.MoveTowards, or better, Lerp with extrapolation. In this case, the ball is at the player's height when it's hit (initial position), and at ground level when it arrives on the destination point, and keeps moving forward (by extrapolating the lerp function) and up again, so you'll have to establish this third point where the ball hits the ground again.

#

I recommend you to play "Tennis" from Atari, you seem to be looking for the same dynamic

#

I know it sounds like I'm oversimplifying your game, but this Tennis Atari game was actually good. The console had a button behind to set the difficulty to Normal or Expert

#

On expert mode, you could get sharper angles to hit the ball

#

the ball was sent to a straight angle when it hit the center of the paddle, and to a sharper angle (towards the diagonal) when the ball hit the paddle's corner. It doesn't make sense from a physics point of view, but it made the game interesting

#

looking at your code, it seems like the paddle has a round shape and then you decide where the ball will go based on where the ball was hit. I like it. It gives the player the control to know exactly how to hit the ball to send it to a certain place. However, it doesn't take into account the ball's current speed and direction. I think it's a good decision, games don't have to be physically accurate. Also it'd be a shit ton of work to make it accurate ๐Ÿ˜„

#

so the 2d movement of the ball is all set, all you need to do is establish the height. The atari game seems to have a constant parabolic function that makes the ball oscillate up and down constantly, which makes sense for a game. Then the ball will just hit the ground on the back of the court when it goes fast, and close to the net when it's hit with a low force

#

So you could just go with height = k* abs( sin(w) ), which will make the ball go up and down in a frequency of w, at a height of k

twin terrace
twin terrace
robust sky
#

Nice, so the 2d mechanics is working, good!

#

for the elevation, I'd say:
Create a "private float ballElevation" in the script that controls de ball
Create a const float racketElevation = 1.0 (could be anything)
Create a float racketTimer = 0.0
Every time the ball is hit by the paddle, make racketTimer = Time.time
Inside Update(), you update the ball elevation like ballElevation = racketElevation * Mathf.Abs( Math.Sin ( racketTimer * omega ) )

#

Oh, yeah, we need to declare private float omega = 1.0, and you can tune this thing later. Omega represents the ball velocity to bounce up and down

#

the funcion Math.Sin will oscilate if you put a timer inside, right?
Now, if you take the absolute value of it, it'll oscillate like this:

#

(which is the ball bouncing up and down)

#

(maybe we should establish a parabolic function, but I'm pretty sure the SIN will look nice)

#

but ABS(SIN(timer)) might be too fast or too slow, so what you do is put a constant inside to help you scale it up or down, which I called omega

#

You could even do tests like when the ball crosses the net, check if ballHeight < netHeight THEN ballHitsNet

#

(I'm not sure it's a good mechanic, but you gotta try ๐Ÿ™‚ )

#

now that you have the ball height, you just scale the ball object up and down according to the height. I'd guess you could make
transform.scale.x = (ballHeight + delta) / racketElevation
(I added the multiplier so the scale doesn't become zero when touching the ground; also, you gotta change the y scale as well)

#

so far so good?

twin terrace
twin terrace
#

Some other errors are that at the moment of being hit, it immediately becomes as small as possible and starts the cycle of size change, regardless of the height it was at before being hit. Another thing is that if possible I would like to set something so that the ball does not bounce when it is still, being that it bounces when it is thrown.

robust sky
#

Ah, it's because we're using mathf.sin, and sin(0)=0

#

Then, as soon as you hit the ball, it disappears

#

So, try replacing sin with cos

#

Or, better, make it sin( (t-t0 + shift) *omega)

#

The shift variable should adjust the ball height when it's hit. If it's zero, the ball will be small when hit, if the shift var = pi/2, the ball will be big when you hit it

#

If the ball is too small, increase the delta variable, say, 0.5 instead of 0.1

#

Now, to make the ball not change the size when hit, that's something else completely... We might have to rethink of what do we want for the code

#

Maybe we have to start thinking of actually simulating the physics

#

To simulate the vertical physics, you integrate the acceleration to find speed, and integrate speed to find position. Do you want me to explain more?

robust sky
#

Right now the ball seems to bounce on the other side, which should not be the case

#

I just had another idea, which is to control the ball height based on the position over the table

#

I'll write something later and send here

twin terrace
twin terrace
robust sky
#

I think it could work that you establish the initial ball height when it was hit, and pre-set where, on the other side of the court (or table) will the ball hit the ground (and be the smallest), and where it will be at its high point again, based on the speed the ball was hit. So we remove the Mathf.Sin, and introduce a linear interpolation

#

for example,
float tableMinY = 0; float tableMidY = 5f; float tableMaxY = 10f; float ballScaleMin = 0.1f; float ballScaleMax = 1.0f; BallWasHit() { ballWasHitAtY = ball.transform.position.y; ballWasHitAtSpeed = racket.rigidbody.velocity.y; ballHitsGroundAtY = mathf.clamp(ballWasHitAtSpeed, -5f, 5f) + tableMidY; //if the ball vertical speed is negative, the target is on the lower court ballHitsGroundAtY = mathf.clamp(ballHitsGroundAtY, tableMinY, tableMaxY); } Update { float t = Mathf.Abs((ball.transform.position.y - ballWasHitAtY) / ( ballHitsGroundAtY - ballWasHitAtY)); float ballHeightScale = Mathf.Lerp (ballWasHitAtY, ballHitsGroundAtY, t ); ball.transform.scale = Vector3.one * ballHeightScale; }

#

I didn't test it, but you get the idea

#

also, the code above is only interpolating between the initial and final points where the scale is zero

#

after the ball reaches the target, you have to start scaling it up again using a new target even further

#

I'm pretty sure I messed up with the signs somewhere inside the Update function

#

but you can do it ๐Ÿ™‚

#

(I typically write my codes very fast with the ideas and then come back fixing the math signs, interpolations, clamps, abs, etc)

azure marlin
#

Hey why no one there in my post?

#

I want help man, for these

proven rock
#

bruh

robust sky
azure marlin
#

Nope

hot charm