Help with ball physics (2/1-2-D)?

Blitz3D Forums/Blitz3D Programming/Help with ball physics (2/1-2-D)?

Guy Fawkes(Posted 2014) [#1]
Hi all. As you know, I've been working on my 3D game in a 2D view (top-down view) for a while now. I've recently run into a little snag. What I've tried to do is make it so that if you hold down the left or right arrow, the ball will roll to the left or the right on the X-Axis in 3D, depending on its' changed velocity. Now the problem is when I go to let go of the left or the right arrow key, the friction that stops the ball is incorrect. It goes to Infinity / NaN when letting go of the left arrow key and it gets very close to 0 when letting go of the right arrow key, but it's supposed to no matter what, either count up to 0 from a maximum negative velocity, or count down from a maximum positive velocity, both down to 0.

I need to use the "CurveValue#()" function, in order to make the positive or negative velocity "slingshot" back to 0.00, slowly or fast depending on the speed of the current velocity.

Without further delay, here is the code:

Ball_Physics.bb:



Any assistance is GREATLY appreciated!

Thanks, and have a wonderful afternoon / evening! =)

~GF


Stevie G(Posted 2014) [#2]
Something like this?




Guy Fawkes(Posted 2014) [#3]
Yes Stevie. EXACTLY like that! Thanks alot, man! :D


Guy Fawkes(Posted 2014) [#4]
Hi all. Ok, for some reason I can't get my ball to jump on the Z axis. (I'm using a top-down view so that the 3D graphics appear in 2D), and for some reason when I hit space, the ball is not "jumping" like it should. What am I doing wrong here? I'm about to pull my hair out! O_O



Thank You again for the help as usual everyone! =)

Have a GREAT afternoon!

~GW

EDIT:

Bounce has been fixed, but I'm still having trouble with making the ball realistically jump. O_O;


Stevie G(Posted 2014) [#5]
When you are jumping you should set the acceleration c\ay to the jump acceleration, not c\vy. The accelerations are effectively the forces being applied to the ball which influence the velocity - you should not directly change the velocity. Obviously, only allow jump acceleration to be applied if the ball is touching the ground.

For gravity, create a constant GRAVITY# to be 0.01 or whatever feels right and in the section below, deduct the gravity from the velocity at all times even when the ball is on the ground.

c\vx#=c\vx# * FRICTION + c\ax#
c\vy#=c\vy# * FRICTION + c\ay# - GRAVITY
c\vz#=c\vz# * FRICTION + c\az#


fox95871(Posted 2014) [#6]
Why not use a physics wrapper? I was trying to do my own physics once too, til someone told me about dlls.


Guy Fawkes(Posted 2014) [#7]
Good idea, @Fox. Which Physics wrapper is easiest, and where can I download it from? Thanks alot, @Fox! =)


Stevie G(Posted 2014) [#8]
A physics wrapper to do a moving and bouncing ball? Really? Acht well, to each their own :)


Guy Fawkes(Posted 2014) [#9]
Hey, if there's ONE thing I've learned the hard way, it's to "keep it simple, stupid" =D


fox95871(Posted 2014) [#10]
I could tell, since you're using Blitz3d. I always tell people, if you're starting programming at age 30 instead of age 3, use Blitz3d. Anyway, I spent quite a while checking out all the physics wrappers some time ago, and eventually did decide on a best one. Look at post 9 on the following thread.

http://blitzbasic.com/Community/posts.php?topic=86991


LineOf7s(Posted 2014) [#11]
Hey, if there's ONE thing I've learned the hard way, it's to "keep it simple, stupid" =D

...which is the opposite of using a physics wrapper to (just) bounce a ball.


RemiD(Posted 2014) [#12]
What about trying to do a search on the forum ?
http://www.blitzbasic.com/codearcs/codearcs.php?code=856


Guy Fawkes(Posted 2014) [#13]
Ya know, Lineof7s. I feel sorry for you. Sorry that you have to pick on everybody else just to feel good about yourself. So you know what, I'm no longer talking to you or reading your rude comments. I'm done.


RemiD(Posted 2014) [#14]
Calm down, to show you how cool we are on blitzbasic.com i have even removed my provocative comment.
What do you think about the example by Jeppe Nielsen, it is good enough for what you want to do isn't it ?


fox95871(Posted 2014) [#15]
It's okay Guy, it's just some kind of mania us programmers have, probably from lack of sunlight or something. My rule of thumb: whenever you're tempted to retaliate to a post, just think of it as a baited hook. Nothing against you by the way Line of 7s. I myself am currently tempted to comment venomously on a Youtube video I recently saw.


Stevie G(Posted 2014) [#16]
Jeppe's code is very familiar, now where did I see that again?


Guy Fawkes(Posted 2014) [#17]
Yes, Remi. And thanks guys for being understanding. As for the code, the only thing I need it to do other than what it already does is jump realistically. I got it to jump. But the problem is I can't control the jump speed when going up.

Here's what I have so far (I edited the tformvector line & made it keyhit(57) instead of keydown(57)):



That's pretty much it.

Thanks again, guys! =)


Kryzon(Posted 2014) [#18]
Jeppe's code is very familiar, now where did I see that again?

Rez was even kind enough to remove the header line that mentioned the author, in the original example.

[...] The only thing I need it to do other than what it already does is jump realistically. [...] But the problem is I can't control the jump speed when going up.

A realistic jump is a combination of both a sensible jump force and a realistic gravity force. This will require that you test different values until you find a combination that is convincing.

- The gravity value is easy to modify: it's the "gravity" constant at the beginning of the code. You can change it to a more negative value so it's more realistic.

- In that program, the jump force does not have a variable assigned to it - it's a "hard-coded" value.
You need to identify the part in the program code that adds the jump vector [0, Y, 0] to the acceleration vector.
You know that the SPACE key makes the ball jump, so you can infer that whatever part of the code uses the SPACE key will involve the jump force or at least give you some clue of where it is used.
The part is this:
		If KeyHit(57)
			
			TFormVector 0,5,0,c\e,0
			
			c\ax#=c\ax+TFormedX()
			c\ay#=c\ay+TFormedY()
			c\az#=c\az+TFormedZ()			
									
		EndIf

That TFormVector line is forming a 3D vector [0, 5, 0], a strictly vertical vector. This is the jump vector that is added to the motion of the ball.
The "5" value is then the magnitude (the "strength") of the vector.
Therefore, in place of the "5" you can write the name of a constant such as "JUMP_FORCE," and at the beginning of the program write something like...

Const JUMP_FORCE# = 1.0

...so it is easier to modify and make more realistic.
The TFormVector line will become "TFormVector( 0, JUMP_FORCE, 0, c\e, 0 )."


Guy Fawkes(Posted 2014) [#19]
Thanks, Kryzon. Ok, guys. Gravity / jumping works now. The problem I have run into now is that I cannot seem to "accurately" do a linepick to the floor in order to detect whether or not the player is "onground". The linepick code I created sorta' works, but when I start to move the ball for some reason it doesn't let me jump even though "onground" = 1... Here's what I have so far for the jump / collision functions:



Also, when you jump, wait til' you hit the floor, then quickly move towards an object you can collide with, the ball slowly "climbs up the object" and into the air. How do I fix this?

Thanks alot for all your help guys! :)

~GW


Guy Fawkes(Posted 2014) [#20]
Can anyone help please?

Thank You all!


Stevie G(Posted 2014) [#21]
The code you've posted doesn't include anything relating to a jump?!

Remove the linepick - it's unecessary as you already gather collision information later in the code. An entity is on the ground if the collision normal y components is positive.

Add OnGround as a field within ball type.

Within the collision code just add the parts which refer to Onground below:

c\OnGround = False

If EntityCollided(c\e,world_col)
				
	For i = 1 To CountCollisions(c\e)
		; Get the normal of the surface which the entity collided with. 
		Nx# = CollisionNX(c\e, i) 
		Ny# = CollisionNY(c\e, i) 
		Nz# = CollisionNZ(c\e, i) 
		
		;is the entity on the ground
		If Ny > 0 c\OnGround = True
				
		; Compute the dot product of the entity's motion vector and the normal of the surface collided with. 
		VdotN# = c\vx#*Nx# + c\vy#*Ny# + c\vz#*Nz# 
		
		; Calculate the normal force. 
		NFx# = -2.0 * Nx# * VdotN# 
		NFy# = -2.0 * Ny# * VdotN# 
		NFz# = -2.0 * Nz# * VdotN# 
				
		; Add the normal force to the direction vector. 
		c\vx# = c\vx# + NFx# * c\bounce#
		c\vy# = c\vy# + NFy# * c\bounce#
		c\vz# = c\vz# + NFz# * c\bounce#

		avx#=EntityPitch(c\sphere)
		avy#=EntityYaw(c\sphere)
		avz#=EntityRoll(c\sphere)

		;Rotate stuff
		;Get vector from center to collision
		dx1#=(CollisionX(c\e,i)-c\x)
		dy1#=(CollisionY(c\e,i)-c\y)
		dz1#=(CollisionZ(c\e,i)-c\z)
				
		dx2#=c\vx
		dy2#=c\vy
		dz2#=c\vz
				
		;Cross product
		cx# = ( dy1 * dz2 ) - ( dz1 * dy2 ) 
		cy# = ( dz1 * dx2 ) - ( dx1 * dz2 ) 
		cz# = ( dx1 * dy2 ) - ( dy1 * dx2 ) 				
															
		AlignToVector c\pivot,cx,cy,cz,1
																									
	Next


Then just use the c\Onground to determine whether a jump is possible.

Stevie


Guy Fawkes(Posted 2014) [#22]
Hi Stevie! It works GREAT! Thanks ALOT! I do have one small quarrel though. Why won't the code let me jump when my ball is rolling on the ground, but only lets me jump when the ball is not moving at all?

ballcontrol() & ballupdate() functions:



Thanks alot to ALL of you for your help! I really appreciate it! :)

~GF


Stevie G(Posted 2014) [#23]
You are overwriting the acceleration each time you move. You need to make it accumulative within the ballcontrol function:

Function ballcontrol()

	For c.ball=Each ball
	
		If KeyHit(57)
		
			If c\OnGround = True

				TFormVector 0,0.75,0,c\e,0
				c\ax = c\ax + TFormedX()
				c\ay = c\ay + TFormedY()
				c\az = c\az + TFormedZ()

			EndIf
		
		EndIf
		
		If KeyDown(200)

			If c\OnGround = True
			
				TFormVector 0,0,0.03,c\e,0
				c\ax = c\ax + TFormedX()
				c\ay = c\ay + TFormedY()
				c\az = c\az + TFormedZ()
				
			Else
			
				TFormVector 0,0,0.003,c\e,0
				c\ax = c\ax + TFormedX()
				c\ay = c\ay + TFormedY()
				c\az = c\az + TFormedZ()
				
			EndIf
			
		EndIf
		
		If KeyDown(208)
			
			c\vx=c\vx*0.94
			c\vy=c\vy*0.94
			c\vz=c\vz*0.94
			
		EndIf

		If KeyDown(203)

			TurnEntity c\e,0,2,0

		EndIf

		If KeyDown(205)

			TurnEntity c\e,0,-2,0

		EndIf

	Next

End Function