Player floating in air constantly. Help please!

Blitz3D Forums/Blitz3D Beginners Area/Player floating in air constantly. Help please!

Captain Wicker (crazy hillbilly)(Posted 2011) [#1]
Alright now I have an object loaded etc. That isn't the problem here. I was testing out a few of my own recipes for gravity and jumping and have gotton myself into a complete mesh here. The object is supposed to jump in the air and float back down really quick like when the spacekey is hit once only. The only problem is that the player remains floating in the air until I release the cursor keys which are up and down. I feel that my problem lies within this small piece of my code and I absolutely cannot figure out what my problem is. Below is that small snippet that I had mentioned before:

        x#=0
	y#=0
	z#=0
	
	
	If KeyDown(208)=True Then y#=-.1
	If KeyDown(200)=True Then y#=.1
	If KeyHit(57)=True Then y#=5.0
	MoveEntity sphere,0,y#,0
        TranslateEntity sphere,0,-0.1,0
    

This small code is located at the end of my program right before UpdateWorld and everything else.

Again I mention that I was trying to make the object jump when the spacekey is hit and not be able to jump again until he floats back down. He was/is supposed to NOT be floating but move forward while jumping and again float down. If anyone here could be so kind as to show me the correct way to set this up would be greatly appreciated. :)


H&K(Posted 2011) [#2]
Were is the decrease y# (ie falling) code?


Captain Wicker (crazy hillbilly)(Posted 2011) [#3]
If you mean gravity, it should be here:
TranslateEntity sphere,0,-0.1,0

Here is what makes the sphere move:
	If KeyDown(203) Then TurnEntity sphere,0,5,0
	If KeyDown(205) Then TurnEntity sphere,0,-5,0
	If KeyDown(200) Then MoveEntity sphere,0,0,0.3
	


Need anymore code? Should I post my entire game code?


Rob the Great(Posted 2011) [#4]
The problem is that you're offsetting gravity movement with the keys 208 and 200. Note that:
If KeyDown(200)=True Then y#=.1 ; suppose that y# = 0.1
MoveEntity sphere,0,y#,0 ;Now you're moving the sphere up by 0.1
TranslateEntity sphere,0,-0.1,0 ;And now you're moving the sphere down by 0.1

will always counter-balance each other, making no movement on the sphere.

In other words, if I told you to move up 1 stair, and in the same second, move down 1 stair, how many stairs did you travel in one second? 0.

This is what you're doing with the sphere. If you hold down key (200), then you're going to move the sphere up by 0.1, and in the same loop, you're going to translate the sphere down by 0.1, therefore resulting in no movement on the sphere when rendered.

What are you trying to accomplish with those lines, anyway? Are you trying to have some sort of "jet pack" that allows you to defy gravity?


Rob the Great(Posted 2011) [#5]
Another thing to consider is that if you drop a ball from the top of a building, it won't fall at a constant rate of 0.1 units per second. That would be really cool, but gravity doesn't actually work like that.

Instead, the ball gradually picks up speed until 1 of 2 things happen:

1. The ball smashes into the face of the Earth, in which all downward energy is transferred into the Earth and the sphere stops moving.
2. The ball hits terminal velocity, in which the amount of force the air exerts on the ball from downward movement evens out the amount of force gravity exerts on the ball, therefore the ball stops accelerating at a very high speed. Then, the ball will come smashing into the face of the Earth.

Try to program your gravity to do the same thing. Start with some very simple pseudo:
;Setup a constant for gravity
;Setup a Global variable to store the current downward movement.

;Setup a collisions system to let Blitz know about the ground and the player

;The Main Loop Here

   ;If the player is not touching the ground
      ;Increase the Global downward movement by the constant of gravity
      ;If the downward movement is greater than "terminal velocity"
         ;the downward movement should now become "terminal velocity"
      ;End of that If section
   ;End of that If section

   ;If the player is touching the ground
      ;Reset the downward movement back to the starting constant
   ;End of that If section

   ;Move the player downward according to the current downward movement

;Do it all  again

I picked English pseudo so that you can see the logic, but ultimately, you will have to translate the English into another language, Blitz's language.

Last edited 2011


Captain Wicker (crazy hillbilly)(Posted 2011) [#6]
Alright I'm really confused now. What do you mean by translating English into other languages?


Yasha(Posted 2011) [#7]
"Pseudocode" is when one writes something that is structured (and usually indented, as above) like code, to indicate how an algorithm might work, but hasn't been fully fleshed out with the details that make it compile. A prose equivalent to arrows and boxes and so on, that you might draw if you were trying to plan your program on paper.

"Translate", in this case, therefore means "read the prose outline in the codebox, to get an idea of how to structure code that does the same thing".


Rob the Great(Posted 2011) [#8]
Yeah, what Yasha said. When I think about what I want to program, I write it in pure English first, and then "translate" it (just take the English and write the equivalent into BASIC).

So, this:
;Pseudo Code
;Set Up Graphics Here
;Load the Main Character

;The Game Loop Is Here

   ;Do Some Stuff

;Repeat the Loop

;End The Game

Would "translate" into Blitz's language of:
Graphics3D 640,480,0,2
SetBuffer BackBuffer()

Global hero = LoadMesh("Hero.b3d")

While Not KeyDown(1)

   DoSomeStuff()

Wend

End

If you're still lost, see if you can't look at my example above and write a program that would mimic the situation. If you need help, let me know and I can help you. It's not really directly related to your problem, but it's good practice nonetheless.

EDIT: Any luck with the previous problem? I tend to go off on tangents, and sometimes my advice is more of a distraction than a solution.

Last edited 2011


Captain Wicker (crazy hillbilly)(Posted 2011) [#9]
Any luck with the previous problem?

No luck yet. been at this for hours nonstop


Midimaster(Posted 2011) [#10]
your code is exactly doing, what you descripe:

the key 200 keeps the object floating in the air, because it adds 0.1 to the Y-value while the gravity substract 0.1. If you release the keys the objects falls back to the floor.

Is this not what you want to do with the cursor keys? Or do you want to use the 200 and 208 for moving? the they should change the Z-values, or?

you should use more DEBUGLOGs command to understand what is really happeing in you code:
        x#=0
	y#=0
	z#=0
	
	
	If KeyDown(208)=True Then y#=-.1
	If KeyDown(200)=True Then y#=.1
	If KeyHit(57)=True Then y#=5.0
	DEBUGLOG "Y=" + y
	DEBUGLOG "SPHERE before =" + EntityY(Sphere)
	MoveEntity sphere,0,y#,0
 	DEBUGLOG "SPHERE moved =" + EntityY(Sphere)
       TranslateEntity sphere,0,-0.1,0
	DEBUGLOG "SPHERE translated =" + EntityY(Sphere)
	DEBUGLOG ""



Captain Wicker (crazy hillbilly)(Posted 2011) [#11]
do you want to use the 200 and 208 for moving

Yes that is all I was trying to do. Why is my player floating in the air though? He is supposed to be fallnig back down like when it is floating instead. The cursor keys aren't supposed to make him float. What do you mean DEBUGLOG command/s? I've never heard of these.


Rob the Great(Posted 2011) [#12]
Ok, THAT explains a lot.

Since you're new to programming, keep in mind something very important:

X-axis: Left and Right
Y-axis: Up and Down
Z-axis: Forward and Backward (into the screen)

Pitch: Rotation along the X-axis (picture a bowling ball rotating down the floor)
Yaw: Rotation along the Y-axis (picture a ballerina twirling)
Roll: Rotation along the Z-axis (picture a spaceship tilting side-to-side)

Depending on what country you live in, this could be different than what you're used to. For example, in the U.S.A., 3D math uses a different axis system, and if memory serves me well, Y and Z are reversed from what Blitz uses. That's the United States for you, though. We're backwards with everything (cars, math, temperature, distance measurement).

Anyways, here's the problem:
MoveEntity sphere,0,y#,0

This should become:
MoveEntity sphere,0,0,z#

Don't forget to change your variable y# to z#. Also, you don't have to use a variable in this situation, but it's completely up to you. You could just as easily type:
If KeyDown(208)=True Then MoveEntity sphere,0,0,-0.1

Before, you would be moving your sphere on the Y-axis (up and down), and you wanted to move it on the Z-axis (forward and backward).

If you are ever in doubt about how the movement works, remember that the alpha-bet order goes X,Y,Z, and Blitz works the same way. X-axis first (left and right), Y-axis next (up and down), and finally the Z-axis last (forward and backward).



Now, DebugLog....This is perhaps one of the most useful tools that Blitz has come up with. DebugLog will dump information to a log while the game is running. This is useful because even if you try to text the variable values on screen, it can be hard to read because even a slow game will still have about 15 frames a second, which is much too fast to be able to read and process. In reality, most games shoot for either 30 frames a second or 60 frames a second, so it's hard to know the internal process of Blitz. For example, consider:
Graphics3D 640,480,0,2

SetBuffer BackBuffer()

Global number# = 1.0

While Not KeyDown(1)

   number# = number# - 0.1
   If number# = 0.1
      Cls
      Text 0,0,"This sentence will never be read"
      Flip
      WaitKey()
      End
   EndIf

   Text 0,0,number#

   Flip

Wend

End

This program will take away 0.1 from "number#". Logically, the numbers would read every loop:
1.0
0.9
0.8
0.7
0.6
0.5
0.4
0.3
0.2
0.1
0.0
Based on the sample program I typed in, when "number#" is 0.1, the program should stop everything, text on the screen "This sentence will never be read", wait for you to push a key, and then end the program. HOWEVER, the way it is set up, this will never happen. The reason why is because floating point numbers in computers happen to be unable to represent 0.1 perfectly when they are obtained through math (taking away 0.1 each loop).

If you didn't know this, which I didn't when I first stared programming, then you will run into trouble when you check if "number#" = 0.1. So, the program doesn't do what you want it to do. You know you've typed everything right, the logic makes sense, and you have no idea why it isn't working. At this point, the best thing you can do it DebugLog the values of "number#", and then see where the problem is. So, taking the above example, let's add in a DebugLog command to know what's really happening under the hood:
Graphics3D 640,480,0,2

SetBuffer BackBuffer()

Global number# = 1.0

While Not KeyDown(1)

   number# = number# - 0.1

   DebugLog number# ;Here's the new command we added. Run in Debug Mode

   If number# = 0.1
      Cls
      Text 0,0,"This sentence will never be read"
      Flip
      WaitKey()
      End
   EndIf

   Text 0,0,number#

   Flip

Wend

End

With DebugLog added, if we run our program in Debug Mode, Blitz is now going to text the value of "number#" each loop to the screen that appears behind the program. At any time, we can click and hold the left mouse button on the debug log and scroll through the values to see if there are any glitches in the values that shouldn't be there. If you ran this program, you would see the following values appear in the Debug Log:
1.0
0.9
0.8
0.7
0.6
0.5
0.4
0.3
0.2
0.0999999
-0.0000000745058
For speed reasons, Blitz uses numbers that are very close to 0.1 and 0.0, but they still aren't perfectly equal to 0.1 or 0.0. Because of this, with the line of code:
If number# = 0.1

The following If section will never be executed because 0.0999999 is never going to be equal to 0.1, making a huge problem with the game. Without DebugLog, you might never know why the problem was there, because 0.0999999 would flash by so fast on the screen that you wouldn't even have time to see it. Using DebugLog, you now know that the values aren't perfect, and you need to adjust your code accordingly. To do so, I would simply change this line:
If number# = 0.1

To this line:
If number# <= 0.1 And number# >= 0.09

And the game will now do what it was originally intended to do.

This turned into a much lengthier explanation than I intended, but to sum it all up, keep these things in mind:

X-axis - Left and Right
Y-axis - Up and Down
Z-axis - Forward and Backward (into the screen)

Pitch - Rotation on the X-axis
Yaw - Rotation on the Y-axis
Roll - Rotation on the Z-axis

DebugLog - Use this command to Write variable values to a temporary file to see what they are every loop, or the "under the hood" stuff.

Hopefully, this all makes sense.


Captain Wicker (crazy hillbilly)(Posted 2011) [#13]
So this Debug log stuff tells me what's going on in my program. FANTASTIC!!!!! :D