Jump n Run...Jump Probleme

CodeCrafterCpp

Erfahrenes Mitglied
Hallo,
Ich bin dabei mir ein kleines Jump n Run zu Programmieren mit OpenGL und C++.
Jetzt ist mein Problem das ich nicht weiß wie ich das machen soll das der Spieler beim Springen zb. pro Millisec. 10 Pixel fällt...Es sollte möglichst genau und wenig CPU fressen also flüssig laufen. Eine delay wäre nicht schlecht aber beim Googln hab ich nichts passendes gefunden....

Achja noch was ich möchte ja das man über Löcher Springen muss wie mach ich am besten?
Das ich immer eine Abfrage macht ob der Spieler auf Boden Steht oder das wenn der Spieler in das Loch läuft das er runter fällt?
EDIT: Der Welten werden zufällig aufgebaut....


Hoffe ihr könnt mir Helfen.

mfG
CCC
 
Zuletzt bearbeitet:
Hi

Windows?
Google nach Query Performance Counter.

Zu den Löchern:
Wie ist den die Welt generell aufgebaut?
Hast du Leveldateien oder kommt immer alles zufällig oder ...?
 
Ist es Tile-basiert? Generell hast du ja hoffentlich einen Update-Loop mit einer Delta-Zeit.
Grade bei Action-Spielen sollte man damit ein Fixed-Length-Update machen.

D.h. du hast einen interen Zähler, der das Zeitdelta aufnimmt. Solange dieses Delta dann größer-gleich z.Bsp. 0.02s Sekunden ist, machst du ein Fixed-Delta-Time-Update.
Jede Steuerung machst du nur innerhalb dieses Fixed-Update. Dadurch rutschen dir schon mal keine Ungenauigkeiten mit Floats dazwischen.

Zum Springen/Fallen: Verabschiede dich von dem Gedanken der direkten Pause. Sowas macht man in einer Spieleschleife nicht, da ja sonst alles andere steht. Vielmehr merkst du dir für den Spieler den Status (am Boden, springt).

Zu jedem Fixed Update dann in etwa so (Pseudocode):

Wenn der Spieler springt:
Sprungzähler hoch.
Spieler nach oben bewegen (anfangs mehr, später weniger, abhängig vom Sprungzähler)
Wenn der Sprungzähler das Maximum erreicht hat
Sprungstatus entfernen

Einmal einfach so und sonst bei jeder Abwärtsbewegung prüfen, ob der Spieler jetzt am Boden steht.
Steht der Spieler am Boden
"Spieler am Boden"-Status setzen
Steht der Spieler nicht am Boden
Wenn nicht im Springen-Status
Fallzähler hoch
Spieler nach unten bewegen (anfangs wenig, später schneller, abhängig vom Fallzähler)
 
@Endurion ich versteh das nicht richtig....Ich hab ja DrawGlScene und da hab ich ja auch drinne was passiert wenn man rechts oder klinks drückt....Soll ich jetzt machen und wie mach ich das mit der Delta Zeit....


@ Sheel Schau in ersten Beitrag unter Edit...
Und wie mach ich das mit Query performance counter bekomm da nur errors...
 
Zuletzt bearbeitet:
Also ich benutze DrawGLScene


C++:
bool DrawGLScene()									
{
	QueryPerformanceCounter((LARGE_INTEGER*)&g_CurentCount);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	


	
	glLoadIdentity();
	glTranslatef(p1, p2, p3);
	glRotatef(rviereck,0.0f,1.0f,0.0f);

	glBegin(GL_QUADS);
	glColor3f(0.0f,1.0f,0.0f); // Blau (Oben)
    glVertex3f(-1.0f, 1.0f, 0.0f); 
    glVertex3f( 1.0f, 1.0f, 0.0f); 
    glVertex3f( 1.0f,-1.0f, 0.0f); 
    glVertex3f(-1.0f,-1.0f, 0.0f); 
	glEnd();

	if(keys[VK_RIGHT])
	{
	p1 += 0.01f *speed;
	}
	if(keys[VK_LEFT])
	{
	p1 -= 0.01f * speed;
	}
	if(keys[VK_UP])
	{
	boden = false;
	}




	return true;										
}
 
Warum machst du nicht einfach wenn up gedrückt wird Spieler nach oben bewegen und dann:
C++:
Player.y -= 100*speed;
Das wären glaube ich 10 pixel die Millisekunde ;)
MfG
 
Zuletzt bearbeitet von einem Moderator:
Also ich benutze DrawGLScene


C++:
...
DrawGLScene heißt die Funktion, aber über das verwendete Framework oder gar deine Hauptschleife verrät uns das genau gar nichts… abgesehen davon: der Name der Funktion deutet darauf hin, dass du in dieser deine Welt nur zeichnen und nicht verändern solltest. Dafür gibt es in der Regel eine eigene Update-Funktion. Wenn du uns verraten würdest, welches Framework du verwendest bzw. wie deine Hauptschleife aussieht, dann könnten wir dir dabei vielleicht sogar helfen.

Grüße,
Matthias
 
Ok hier ist der Komplette Code:

C++:
#include <Windows.h>
#include <gl/GL.h>
#include <gl/GLU.h>


#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")

HDC hDC = 0;
HGLRC hRC = 0;
HWND hWnd = 0;
HINSTANCE hInstance;		
LRESULT	CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);	
RECT window;



GLfloat rviereck;

float p1 = 0.0f;
float p2 = 0.0f;
float p3 = -20.0f;
float speed = 10.0f;
bool boden = true;
float sprung = 1.0f;
float sprunghöhe = 10.0f;
float sprungspeed = 1.0f;
float akthöhe = 0;
LONGLONG g_Frequency, g_CurentCount, g_LastCount;









bool keys[256];
bool active = true;
bool fullscreen = false;

bool InitGL();
void ReSizeGLScene(unsigned int width, unsigned int height);
bool DrawGLScene();
bool KillGLWindow();
bool CreateGLWindow(LPCWSTR title, int width, int height, int bits, bool fullscreenflag);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR nlpCmdLine, int nCmdShow);


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR nlpCmdLine, int nCmdShow)
{
	MSG	msg;									
	bool done = false;								

	if(MessageBox(0, L"Im Vollbildmodus starten?", L"Vollbild?", MB_YESNO | MB_ICONQUESTION) == IDYES)
	{
		fullscreen = true;							
	}

	if(!CreateGLWindow(L"OpenGL", 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										
		{
			if((active && !DrawGLScene()) || keys[VK_ESCAPE])	
			{
				done = true;							
			}
			else									
			{
				SwapBuffers(hDC);					
			}
		}	
	}

	KillGLWindow();	

	return (msg.wParam);						
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	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_KEYDOWN:							
		{
			keys[wParam] = true;

			return 0;								
		}

		case WM_KEYUP:								
		{
			keys[wParam] = false;	

			return 0;							
		}

		case WM_SIZE:								
		{
			ReSizeGLScene(LOWORD(lParam), HIWORD(lParam));  

			return 0;							
		}
	}

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

bool CreateGLWindow(LPCWSTR title, int width, int height, int bits, bool fullscreenflag)
{
	GLuint PixelFormat;			
	WNDCLASS wc;						
	DWORD dwExStyle;				
	DWORD dwStyle;				
	RECT WindowRect;				
	WindowRect.left = 0;			
	WindowRect.right = width;		
	WindowRect.top = 0;				
	WindowRect.bottom = height;		

	fullscreen = fullscreenflag;	

	hInstance			= GetModuleHandle(NULL);				
	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;	
	wc.lpfnWndProc		= (WNDPROC) WndProc;					
	wc.cbClsExtra		= 0;									
	wc.cbWndExtra		= 0;									
	wc.hInstance		= hInstance;							
	wc.hIcon			= LoadIcon(NULL, IDI_WINLOGO);			
	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);			
	wc.hbrBackground	= NULL;									
	wc.lpszMenuName		= NULL;									
	wc.lpszClassName	= L"OpenGL";								

	if(!RegisterClass(&wc))									
	{
		MessageBox(NULL, L"Window-Class konnte nicht regsitriert werden!", L"ERROR", MB_OK|MB_ICONEXCLAMATION);

		return false;											
	}
	
	if(fullscreen)												
	{
		DEVMODE dmScreenSettings;								
		memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));	
		dmScreenSettings.dmSize = sizeof(dmScreenSettings);		
		dmScreenSettings.dmPelsWidth = width;				
		dmScreenSettings.dmPelsHeight = height;				
		dmScreenSettings.dmBitsPerPel = bits;					
		dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

		if(ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
		{
			if(MessageBox(0, L"Vollbild-Modus wird nicht unterstützt. Window-Mode nutzen?", L"OpenGl - Info", MB_YESNO|MB_ICONEXCLAMATION) == IDYES)
			{
				fullscreen = false;		
			}
			else
			{
				MessageBox(0, L"Programm wird beendet.", L"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);	

	if (!(hWnd = CreateWindowEx(dwExStyle, L"OpenGL", (LPCWSTR)title, dwStyle |	WS_CLIPSIBLINGS | WS_CLIPCHILDREN,					
								0, 0, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top,	
								NULL, NULL, hInstance, NULL)))								
	{
		KillGLWindow();								
		MessageBox(NULL, L"Fenster konnte nicht erstellt werden!", L"ERROR", MB_OK|MB_ICONEXCLAMATION);

		return false;								
	}

	static PIXELFORMATDESCRIPTOR pfd =				
	{
	    sizeof(PIXELFORMATDESCRIPTOR), 
		1,											
		PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA,								
		bits,										
		0, 0, 0, 0, 0, 0,							
		0,											
		0,											
		0,											
		0, 0, 0, 0,									
		16,											
		0,											
		0,											
		PFD_MAIN_PLANE,								
		0,											
		0, 0, 0										
	};
	
	hDC = GetDC(hWnd);					
	PixelFormat = ChoosePixelFormat(hDC, &pfd);	
	SetPixelFormat(hDC, PixelFormat, &pfd);		
	hRC = wglCreateContext(hDC);				
	wglMakeCurrent(hDC, hRC);					
	
	ShowWindow(hWnd, SW_SHOW);						
	SetForegroundWindow(hWnd);						
	SetFocus(hWnd);									
	ReSizeGLScene(width, height);					

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

		return false;								
	}

	return true;								
}

bool KillGLWindow()								
{
	if(fullscreen)										
	{
		ChangeDisplaySettings(0, 0);					
		ShowCursor(TRUE);								
	}

	if(hRC)											
	{
		wglMakeCurrent(0, 0);				
		wglDeleteContext(hRC);					
		hRC = 0;									
	}

	ReleaseDC(hWnd, hDC);				

	DestroyWindow(hWnd);					

	UnregisterClass(L"OpenGL", hInstance);	

	return true;
}

bool InitGL()										
{
	//glEnable(GL_TEXTURE_2D);							
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);				
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	glClearDepth(1.0);									
	glDepthFunc(GL_LEQUAL);								
	glEnable(GL_DEPTH_TEST);							
	glShadeModel(GL_SMOOTH);							
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

	return true;										
}

void ReSizeGLScene(unsigned int width, unsigned int height)		
{
	if(height == 0)										
		height = 1;										

	glViewport(0, 0, width, height);						

	glMatrixMode(GL_PROJECTION);						
	glLoadIdentity();									

	gluPerspective(45.0f, (float)width/(float)height, 0.1f, 500.0f);

	glMatrixMode(GL_MODELVIEW);							
	glLoadIdentity();									
}

bool DrawGLScene()									
{
	QueryPerformanceCounter((LARGE_INTEGER*)&g_CurentCount);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	


	
	glLoadIdentity();
	glTranslatef(p1, p2, p3);
	glRotatef(rviereck,0.0f,1.0f,0.0f);

	glBegin(GL_QUADS);
	glColor3f(0.0f,1.0f,0.0f); // Blau (Oben)
    glVertex3f(-1.0f, 1.0f, 0.0f); 
    glVertex3f( 1.0f, 1.0f, 0.0f); 
    glVertex3f( 1.0f,-1.0f, 0.0f); 
    glVertex3f(-1.0f,-1.0f, 0.0f); 
	glEnd();

	if(keys[VK_RIGHT])
	{
	p1 += 0.01f *speed;
	}
	if(keys[VK_LEFT])
	{
	p1 -= 0.01f * speed;
	}
	if(keys[VK_UP])
	{
	boden = false;
	}




	return true;										
}
 
Zuletzt bearbeitet von einem Moderator:
Sprachlos noch nie so ein guten Code gesehen? :D
Ich hab es einfach zusammengewürfelt aus meinen Wissen könnt ihr mir helfen oder mir Tipps geben falls ich etwas ganz schrecklich geschreiben habe....:D

mfG
 
Zurück