PDA

View Full Version : Jumping Physics I got. Key Presses I dont!!



Edward472
11-07-2010, 05:46 PM
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;
}

bcthund
11-08-2010, 02:55 AM
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.

Edward472
11-08-2010, 07:45 AM
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.

Edward472
11-08-2010, 08:53 AM
Would passing by reference fix this?

bcthund
11-08-2010, 03:48 PM
Would passing by reference fix this?
I Agree, that should solve the problem.

Edward472
11-08-2010, 07:22 PM
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

bcthund
11-09-2010, 02:44 AM
Without seeing more of the code it could be hard to pinpoint the problem without guess work.

Edward472
11-09-2010, 11:07 AM
My code is already pretty extensive. Which parts would you have to see?

bcthund
11-09-2010, 06:16 PM
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().

Edward472
11-10-2010, 04:48 PM
#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.mVi ew.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.mVie w.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 &amp;&amp; !ReleaseDC(hWnd,hDC))
{
MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hDC=NULL;
}

if (hWnd &amp;&amp; !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(&amp;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(&amp;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_PELSWID TH|DM_PELSHEIGHT;


if (ChangeDisplaySettings(&amp;dmScreenSettings,CDS_FULLS CREEN)!=DISP_CHANGE_SUCCESSFUL)
{

if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour 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(&amp;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,&amp;pfd)))
{
KillGLWindow();
MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}

if(!SetPixelFormat(hDC,PixelFormat,&amp;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(&amp;msg,NULL,0,0,PM_REMOVE))
{
if (msg.message==WM_QUIT)
{
done=TRUE;
}
else
{
TranslateMessage(&amp;msg);
DispatchMessage(&amp;msg);
}
}
else
{
Keyboard_Input();

;
if ((active &amp;&amp; !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();
}
}

bcthund
11-10-2010, 06:24 PM
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 &amp;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 &amp;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.

Edward472
11-10-2010, 06:55 PM
OMG!! it finally works. Thank you for all the help and patience. I hope to do the same for others on the forum.