Jumping Physics I got. Key Presses I dont!!

I am working on a game. And i have got my jumping physics down. The only problem is that the user has to keep the button pressed or it wont finish. If i replace my “if” statement with a “while” the jump happens in less than a second. Any thoughts on how i could get this to 1) check for a key press and not a key hold down 2) get the code to work the same?

double velocity = .06;
double max = -.07;
void CCamera::Jump()
{
if(mPos.y<=2.5)
{
mPos.y=2.5;
mView.y=2;
}
if(velocity>max)
{
mPos.y+=velocity;
mView.y+=velocity;
velocity-= .0003;
}

You could set a bool value when the key has been pressed and set it to return to false when the jump routine is complete. This would prevent the jump from being pressed again until the first jump is complete.

Thank you for the response I tried something like this


void CCamera::Jump(bool canJump)
{     
      
   if(mPos.y<=2.5)
   {
     mPos.y=2.5; 
     mView.y=2;  
   }   
    if(canJump==true)
    {    
    if(velocity>max)
    {
       mPos.y+=velocity;
       mView.y+=velocity;  
       velocity-= .0003;                 
    }
    else
    {
      canJump=false;
      velocity = .06;
      max =  -.07;
      } 
    }
} 

but now it just jumps over and over. I know it is a problem with me setting velocity and max back to original values after I am done. But i dont know where else I can. If i make them global the same thing is going to happen. When I try to save velocity and max to member variable in my function. The camera just goes up to infinity.

Would passing by reference fix this?

I Agree, that should solve the problem.

tried that and it still didnt work. I removed the bitwise operator 0x80 from my keyboardinput() for the key im pressing. I can now can the camera to jump once but it wont do it again

Without seeing more of the code it could be hard to pinpoint the problem without guess work.

My code is already pretty extensive. Which parts would you have to see?

It could be many things, such as the way that you handle input from the keyboard could cause the problem. Or some other conflicting conditional test causing an unintentional loop.

If you could at least post some snippets the of relevant parts that are used for the jumping system. Basically, what is the process up to the point where CCamera::Jump() is called? Also, what are the relevant routines that occur during and after CCamera::Jump().



#include "main.h"
#include "camera.h"
#include "skybox.h"
#include "font.h"
#include "boundingbox.h"
#include<iostream>
#define KEYDOWN( vk_code ) ( ( GetAsyncKeyState( vk_code ) & 0x8000 ) ? 1 : 0 )
#define KEYUP( vk_code ) ( ( GetAsyncKeyState( vk_code ) & 0x8000 ) ? 0 : 1 )


HDC			hDC=NULL;		// Private GDI Device Context
HGLRC		hRC=NULL;		// Permanent Rendering Context
HWND		hWnd=NULL;		// Holds Our Window Handle
HINSTANCE	hInstance;		// Holds The Instance Of The Application

bool	keys[256];			// Array Used For The Keyboard Routine
bool	active=TRUE;		// Window Active Flag Set To TRUE By Default
bool	fullscreen=TRUE;	// Fullscreen Flag Set To Fullscreen Mode By Default

CCamera objCamera; 
Skybox skybox;
Font font;
GLuint  textures[6];

      




LRESULT	CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);	// Declaration For WndProc

/////////////////////////////////////////////////////////////////////////////////////////////////
//										THE RESIZE GL SCENE
/////////////////////////////////////////////////////////////////////////////////////////////////
GLvoid ReSizeGLScene(GLsizei width, GLsizei height)	
{
	if (height==0)									
	{
		height=1;									
	}

	glViewport(0,0,width,height);					

	glMatrixMode(GL_PROJECTION);					
	glLoadIdentity();								


	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

	glMatrixMode(GL_MODELVIEW);						
	glLoadIdentity();								
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//										THE OPENGL INIT
/////////////////////////////////////////////////////////////////////////////////////////////////
int InitGL(GLvoid)										// All Setup For OpenGL Goes Here
{
	glShadeModel(GL_SMOOTH);							// Enable Smooth Shading
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);				// Black Background
	glClearDepth(1.0f);									// Depth Buffer Setup
	glEnable(GL_DEPTH_TEST);							// Enables Depth Testing
	glDepthFunc(GL_LEQUAL);								// The Type Of Depth Testing To Do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations
    glEnable(GL_TEXTURE_2D);

				           // Position      View(target)  Up
	objCamera.Position_Camera(0, 2.5f, 5,	0, 2.5f, 0,   0, 1, 0);
    textures[0] = skybox.LoadTextureRAW( "image001.raw", TRUE );
    textures[1] = skybox.LoadTextureRAW( "image002.raw", TRUE );
    textures[2] = skybox.LoadTextureRAW( "image003.raw", TRUE );
	textures[3] = skybox.LoadTextureRAW( "image004.raw", TRUE );
	textures[4] = skybox.LoadTextureRAW( "image005.raw", TRUE );
    textures[5] = skybox.LoadTextureRAW( "image006.raw", TRUE );
    
  font.buildFont();
 
    return TRUE;										
}

int DrawGLScene(GLvoid)								
{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
	glLoadIdentity();									
	

	gluLookAt(objCamera.mPos.x,  objCamera.mPos.y,  objCamera.mPos.z,	
			  objCamera.mView.x, objCamera.mView.y, objCamera.mView.z,	
			  objCamera.mUp.x,   objCamera.mUp.y,   objCamera.mUp.z);       

	Draw_Grid();
	skybox.Draw_Skybox(objCamera.mPos.x,objCamera.mPos.y,objCamera.mPos.z,100,100,100,textures);
	    glTranslatef(0,1.0f,0);
    	glBegin(GL_QUADS);						
		glColor3f(0.0f,1.0f,0.0f);			
		glVertex3f( 1.0f, 1.0f,-1.0f);		
		glVertex3f(-1.0f, 1.0f,-1.0f);		
		glVertex3f(-1.0f, 1.0f, 1.0f);		
		glVertex3f( 1.0f, 1.0f, 1.0f);		
		glColor3f(1.0f,0.5f,0.0f);			
		glVertex3f( 1.0f,-1.0f, 1.0f);		
		glVertex3f(-1.0f,-1.0f, 1.0f);		
		glVertex3f(-1.0f,-1.0f,-1.0f);		
		glVertex3f( 1.0f,-1.0f,-1.0f);
		glColor3f(1.0f,0.0f,0.0f);			
		glVertex3f( 1.0f, 1.0f, 1.0f);		
		glVertex3f(-1.0f, 1.0f, 1.0f);		
		glVertex3f(-1.0f,-1.0f, 1.0f);		
		glVertex3f( 1.0f,-1.0f, 1.0f);		
		glColor3f(1.0f,1.0f,0.0f);			
		glVertex3f( 1.0f,-1.0f,-1.0f);		
		glVertex3f(-1.0f,-1.0f,-1.0f);		
		glVertex3f(-1.0f, 1.0f,-1.0f);		
		glVertex3f( 1.0f, 1.0f,-1.0f);		
		glColor3f(0.0f,0.0f,1.0f);			
		glVertex3f(-1.0f, 1.0f, 1.0f);		
		glVertex3f(-1.0f, 1.0f,-1.0f);		
		glVertex3f(-1.0f,-1.0f,-1.0f);		
		glVertex3f(-1.0f,-1.0f, 1.0f);		
		glColor3f(1.0f,0.0f,1.0f);			
		glVertex3f( 1.0f, 1.0f,-1.0f);		
		glVertex3f( 1.0f, 1.0f, 1.0f);		
		glVertex3f( 1.0f,-1.0f, 1.0f);		
		glVertex3f( 1.0f,-1.0f,-1.0f);		
	glEnd();
	
	
    glRasterPos3f(objCamera.mView.x+.05f,objCamera.mView.y,objCamera.mView.z+ 0.05f);
    float posx = objCamera.mPos.x;
    float posz = objCamera.mPos.z;
    float posy = objCamera.mPos.y;
 	font.glPrint("x: %f",posx);	// Print GL Text To The Screen
 	glRasterPos3f(objCamera.mView.x+.5f,objCamera.mView.y-2,objCamera.mView.z+ 0.05f);
 	font.glPrint("y: %f",posy);
 	glRasterPos3f(objCamera.mView.x+ 1.5f,objCamera.mView.y-2,objCamera.mView.z+ 0.05f);
 	font.glPrint("z: %d",posz);

	return TRUE;									
}



/////////////////////////////////////////////////////////////////////////////////////////////////
//										THE KILL GL WINDOW
/////////////////////////////////////////////////////////////////////////////////////////////////
GLvoid KillGLWindow(GLvoid)								
{
	if (fullscreen)										
	{
		ChangeDisplaySettings(NULL,0);				
		ShowCursor(TRUE);								
	}

	if (hRC)										
	{
		if (!wglMakeCurrent(NULL,NULL))					
		{
			MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		}

		if (!wglDeleteContext(hRC))						
		{
			MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		}
		hRC=NULL;										
	}

	if (hDC && !ReleaseDC(hWnd,hDC))					
	{
		MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		hDC=NULL;									
	}

	if (hWnd && !DestroyWindow(hWnd))					
	{
		MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		hWnd=NULL;										
	}

	if (!UnregisterClass("OpenGL",hInstance))		
	{
		MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		hInstance=NULL;									
	}
}

BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
	GLuint		PixelFormat;			// Holds The Results After Searching For A Match
	WNDCLASS	wc;						// Windows Class Structure
	DWORD		dwExStyle;				// Window Extended Style
	DWORD		dwStyle;				// Window Style
	RECT		WindowRect;				// Grabs Rectangle Upper Left / Lower Right Values
	WindowRect.left=(long)0;			// Set Left Value To 0
	WindowRect.right=(long)width;		// Set Right Value To Requested Width
	WindowRect.top=(long)0;				// Set Top Value To 0
	WindowRect.bottom=(long)height;		// Set Bottom Value To Requested Height

	fullscreen=fullscreenflag;			// Set The Global Fullscreen Flag

	hInstance			= GetModuleHandle(NULL);				// Grab An Instance For Our Window
	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;	// Redraw On Size, And Own DC For Window.
	wc.lpfnWndProc		= (WNDPROC) WndProc;					// WndProc Handles Messages
	wc.cbClsExtra		= 0;									// No Extra Window Data
	wc.cbWndExtra		= 0;									// No Extra Window Data
	wc.hInstance		= hInstance;							// Set The Instance
	wc.hIcon			= LoadIcon(NULL, IDI_WINLOGO);			// Load The Default Icon
	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);			// Load The Arrow Pointer
	wc.hbrBackground	= NULL;									// No Background Required For GL
	wc.lpszMenuName		= NULL;									// We Don't Want A Menu
	wc.lpszClassName	= "OpenGL";								// Set The Class Name

	if (!RegisterClass(&wc))									// Attempt To Register The Window Class
	{
		MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;											// Return FALSE
	}
	
	if (fullscreen)												// Attempt Fullscreen Mode?
	{
		DEVMODE dmScreenSettings;								// Device Mode
		memset(&dmScreenSettings,0,sizeof(dmScreenSettings));	// Makes Sure Memory's Cleared
		dmScreenSettings.dmSize=sizeof(dmScreenSettings);		// Size Of The Devmode Structure
		dmScreenSettings.dmPelsWidth	= width;				// Selected Screen Width
		dmScreenSettings.dmPelsHeight	= height;				// Selected Screen Height
		dmScreenSettings.dmBitsPerPel	= bits;					// Selected Bits Per Pixel
		dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

	
		if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
		{
	
			if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By
Your Video Card. Use Windowed Mode Instead?","OPENGL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
			{
				fullscreen=FALSE;		
			}
			else
			{
			
				MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);
				return FALSE;								
			}
		}
	}

	if (fullscreen)											
	{
		dwExStyle=WS_EX_APPWINDOW;							
		dwStyle=WS_POPUP;									
		ShowCursor(FALSE);								
	}
	else
	{
		dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;		
		dwStyle=WS_OVERLAPPEDWINDOW;						
	}

	AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);		

	// Create The Window
	if (!(hWnd=CreateWindowEx(	dwExStyle,							// Extended Style For The Window
								"OpenGL",							// Class Name
								title,								// Window Title
								dwStyle |							// Defined Window Style
								WS_CLIPSIBLINGS |					// Required Window Style
								WS_CLIPCHILDREN,					// Required Window Style
								0, 0,								// Window Position
								WindowRect.right-WindowRect.left,	// Calculate Window Width
								WindowRect.bottom-WindowRect.top,	// Calculate Window Height
								NULL,								// No Parent Window
								NULL,								// No Menu
								hInstance,							// Instance
								NULL)))								// Dont Pass Anything To WM_CREATE
	{
		KillGLWindow();								// Reset The Display
		MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;							
	}

	static	PIXELFORMATDESCRIPTOR pfd=				
	{
		sizeof(PIXELFORMATDESCRIPTOR),				// Size Of This Pixel Format Descriptor
		1,											// Version Number
		PFD_DRAW_TO_WINDOW |						// Format Must Support Window
		PFD_SUPPORT_OPENGL |						// Format Must Support OpenGL
		PFD_DOUBLEBUFFER,							// Must Support Double Buffering
		PFD_TYPE_RGBA,								// Request An RGBA Format
		bits,										// Select Our Color Depth
		0, 0, 0, 0, 0, 0,							// Color Bits Ignored
		0,											// No Alpha Buffer
		0,											// Shift Bit Ignored
		0,											// No Accumulation Buffer
		0, 0, 0, 0,									// Accumulation Bits Ignored
		16,											// 16Bit Z-Buffer (Depth Buffer)  
		0,											// No Stencil Buffer
		0,											// No Auxiliary Buffer
		PFD_MAIN_PLANE,								// Main Drawing Layer
		0,											// Reserved
		0, 0, 0										// Layer Masks Ignored
	};
	
	if (!(hDC=GetDC(hWnd)))							
    	{
		KillGLWindow();							
		MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								
	}

	if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))	
	{
		KillGLWindow();								
		MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;							
	}

	if(!SetPixelFormat(hDC,PixelFormat,&pfd))		
	{
		KillGLWindow();							
		MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;							
	}

	if (!(hRC=wglCreateContext(hDC)))				
	{
		KillGLWindow();								
		MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								
	}

	if(!wglMakeCurrent(hDC,hRC))				
	{
		KillGLWindow();								
		MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;							
	}

	ShowWindow(hWnd,SW_SHOW);						
	SetForegroundWindow(hWnd);						
	SetFocus(hWnd);									
	ReSizeGLScene(width, height);				

	if (!InitGL())								
	{
		KillGLWindow();								
		MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;							
}

	return TRUE;								
}

LRESULT CALLBACK WndProc(	HWND	hWnd,			// Handle For This Window
							UINT	uMsg,			// Message For This Window
							WPARAM	wParam,			// Additional Message Information
							LPARAM	lParam)			// Additional Message Information
{
	switch (uMsg)									
	{
		case WM_ACTIVATE:							
		{
			if (!HIWORD(wParam))					
			{
				active=TRUE;						
			}
			else
			{
				active=FALSE;						
			}

			return 0;								
		}

		case WM_SYSCOMMAND:							
		{
			switch (wParam)							
			{
				case SC_SCREENSAVE:				
				case SC_MONITORPOWER:			
				return 0;						
			}
			break;									
		}

		case WM_CLOSE:								
		{
			PostQuitMessage(0);						
			return 0;							
		}

		case WM_SIZE:							
		{
			ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));  
			return 0;								
		}
		case WM_KEYDOWN:							// Is A Key Being Held Down?
		{
			keys[wParam] = TRUE;					// If So, Mark It As TRUE
			return 0;								// Jump Back
		}

		case WM_KEYUP:								// Has A Key Been Released?
		{
			keys[wParam] = FALSE;					// If So, Mark It As FALSE
			return 0;								// Jump Back
		}
    
	}

	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}



/////////////////////////////////////////////////////////////////////////////////////////////////
//										THE WINMAIN
/////////////////////////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain(	HINSTANCE	hInstance,			// Instance
					HINSTANCE	hPrevInstance,		// Previous Instance
					LPSTR		lpCmdLine,			// Command Line Parameters
					int			nCmdShow)			// Window Show State
{
	MSG		msg;									// Windows Message Structure
	BOOL	done=FALSE;								// Bool Variable To Exit Loop


	if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO)
	{
		fullscreen=FALSE;							
	}


	if (!CreateGLWindow("First Person Kirby",640,480,16,fullscreen))
	{
		return 0;								
	}
	while(!done)									
	{
		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))	
		{
			if (msg.message==WM_QUIT)			
			{
				done=TRUE;							
			}
			else								
			{
				TranslateMessage(&msg);				
				DispatchMessage(&msg);			
			}
		}
		else										
		{
          	Keyboard_Input();
   
          	    ;
            if ((active && !DrawGLScene()) || KEYDOWN(VK_ESCAPE))
			{
				done=TRUE;						
			}
			else									
			{
				SwapBuffers(hDC);					
			}

			if (KEYDOWN(VK_F1))						
			{
				keys[VK_F1]=FALSE;					
				KillGLWindow();						
				fullscreen=!fullscreen;			
				if (!CreateGLWindow("First Person Kirby",640,480,16,fullscreen))
				{
					return 0;						
				}
			}
			
			objCamera.Mouse_Move(640,480);
			objCamera.Update();
		}
	}
	KillGLWindow();								
	return (msg.wParam);						
}

void Keyboard_Input()
{
	if(GetKeyState('W') & 0x80)
	{	
		objCamera.Move_Camera( CAMERASPEED);
      
	}

	if(GetKeyState('S') & 0x80)
	{
		objCamera.Move_Camera(-CAMERASPEED);
	}

	if(GetKeyState('A') & 0x80)
	{	
		objCamera.Strafe(-CAMERASPEED);
	}

	if(GetKeyState('D') & 0x80)
	{
		objCamera.Strafe(CAMERASPEED);
	}
    if(GetKeyState(VK_CONTROL))
    {         
                                        
		   objCamera.Jump(false);
	} 
 }

void Draw_Grid()
{															

	for(float i = -500; i <= 500; i += 5)
	{
		glBegin(GL_LINES);
			glColor3ub(150, 190, 150);						
			glVertex3f(-500, 0, i);					
			glVertex3f(500, 0, i);
			glVertex3f(i, 0,-500);							
			glVertex3f(i, 0, 500);
		glEnd();
	}
}




What it looks like you need to do is separate our jump call from the input check.
Declare a bool such as “isJumping” in WinMain at the top:


SG      msg;
BOOL    done=FALSE;
BOOL    isJumping=FALSE;

Set isJumping when VK_CONTROL is pressed to true, this will have to be passed to KeyBoard_Input() by reference:


void Keyboard_Input(bool &isJumping)
{
   if (GetKeyState('W') & 0x80) objCamera.Move_Camera( CAMERASPEED);
   if (GetKeyState('S') & 0x80) objCamera.Move_Camera(-CAMERASPEED);
   if (GetKeyState('A') & 0x80) objCamera.Strafe(-CAMERASPEED);
   if (GetKeyState('D') & 0x80) objCamera.Strafe(CAMERASPEED);
   if (GetKeyState(VK_CONTROL)) isJumping=true;
}

Then you need to add a check on “isJumping” every pass, which will be in your loop in WinMain after KeyBoard_Input():


if (isJumping) objCamera::Jump(isJumping);

You also need to pass by reference because objCamera::Jump() is going to have to set “isJumping” to false eventually. I may have the below example slightly incorrect because I don’t know the specifics of your translation code, but the idea is that when the jump is supposed to be complete, set “isJumping=false”:


void CCamera::Jump(bool &isJumping)
{     
   if (mPos.y<=2.5) {
      mPos.y=2.5;
      mView.y=2;
      isJumping=false;
   }

   if (velocity>max) {
      mPos.y+=velocity;
      mView.y+=velocity;
      velocity-= .0003;
   }
   else {
      velocity = .06;
      max =  -.07;
   }
}

As far as timing, you will need to add a precision timer to manage how long it takes the jump to complete. For example allowing an executing of objCamera::Jump() every 10ms and no faster. Hope all this helps get you in the right direction.

OMG!! it finally works. Thank you for all the help and patience. I hope to do the same for others on the forum.