-
20.11.11 02:31 #1
- Registriert seit
- Nov 2011
- Beiträge
- 148
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
CCCGeändert von CodeCrafterCpp (20.11.11 um 18:17 Uhr)
-
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 ...?Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
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)
-
20.11.11 15:00 #4
- Registriert seit
- Nov 2011
- Beiträge
- 148
@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...Geändert von CodeCrafterCpp (20.11.11 um 18:19 Uhr)
-
Hallo,
wie sieht denn deine Hauptschleife aus? Verwendest du ein Framework (GLUT, SDL, etc.)?
Grüße,
Matthias„Gib einem Menschen einen Fisch, und er wird für einen Tag satt. Lehre ihn Fischen, und er wird ein Leben lang satt.“
“For every complex problem, there is an answer that is short, simple and wrong.”
“Pessimism is safe, but optimism is a lot faster!”
Aktuelles Coding Quiz: #17 - Wörter kreuz und quer
-
20.11.11 19:46 #6
- Registriert seit
- Nov 2011
- Beiträge
- 148
Also ich benutze DrawGLScene
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
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; }
-
20.11.11 23:31 #7
Warum machst du nicht einfach wenn up gedrückt wird Spieler nach oben bewegen und dann:
Das wären glaube ich 10 pixel die MillisekundeCode cpp:1
Player.y -= 100*speed;

MfGGeändert von MSVCplusplus (20.11.11 um 23:34 Uhr)
Fehlermeldung bitte!
Google - Dein Freund und Helfer
-
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„Gib einem Menschen einen Fisch, und er wird für einen Tag satt. Lehre ihn Fischen, und er wird ein Leben lang satt.“
“For every complex problem, there is an answer that is short, simple and wrong.”
“Pessimism is safe, but optimism is a lot faster!”
Aktuelles Coding Quiz: #17 - Wörter kreuz und quer
-
21.11.11 18:10 #9
- Registriert seit
- Nov 2011
- Beiträge
- 148
Ok hier ist der Komplette Code:
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
#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; }
-
22.11.11 17:53 #10
- Registriert seit
- Nov 2011
- Beiträge
- 148
Sprachlos noch nie so ein guten Code gesehen?

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....
mfG
-
Ich habe jetzt nicht alle Posts im Details gelesen und auch deinen Code nicht ganz durchsehen, aber ich denke du solltest dir unbedingt folgenden Artikel durchlesen:
http://www.koonsolo.com/news/dewitters-gameloop/
Auch wenn ich jetzt mit Spielentwicklung nichts mehr zu tun habe, hat mir dieser Artikel damals sehr viel geholfen.
-
22.11.11 21:01 #12
- Registriert seit
- Nov 2011
- Beiträge
- 148
Ich hab mal ein bisschen rumprobiert aber nicht richtig weiter gekommen. Soll ich jetzt durch ein Game-Loop immer wieder DrawGLScene aufrufen oder wie? Ich hab da auch ein bisschen rumgespielt und das weiteste war das ich ohne Fehlermeldung starten konnte aber dann nur ein Windows Fenster gekommen ist aber nichts mehr und das hat dann zeimlich stark gehangen also VS2010
-
Wenn ich in deinen Code gucke (Zeile 66 und 82) machst du genau das ja bereits.
Es geht darum, dass der Loop eine gewisse Zeit braucht, um einmal durchzulaufen. Diese Zeit kannst du messen und anhand der Dauer dann berechnen, wie weit sich die Figur bewegen muss (Geschwindigkeit und Zeit sind bekannt, also kannst du den Weg ausrechnen).
Mehr wollte ich mit dem Link nicht sagen. Was darüber hinaus geht, z.B. die exakte Implementierung, da kann ich dir nicht weiter helfen.
-
23.11.11 15:39 #14
Also du brauchst halt einen Timer der von Anfang bis Ende der Update und Render Methoden läuft und dann stoppt und auf 0 gesetzt wird.
Dann bekommst eine Zahl. Mit der musst du halt alles malnehmen. Sonst läuft das Spiel unterschiedlich schnell auf anderen PCs. Und wenn du dann auch wirklich reales springen darstellen willst empfehle ich dir Box 2D. Dann einfach mal nach der Funktion setvelocity suchen.
MfG
Fehlermeldung bitte!
Google - Dein Freund und Helfer
-
23.11.11 20:43 #15
- Registriert seit
- Nov 2011
- Beiträge
- 148
Wie ok das hab ich ja alles verstanden aber wie mach ich ein game_update und ein Display update mit OpenGL also ich brauch eine Funktion die alle berechnet und so und eine die das dann Zeichnet richtig?
Und wie mach ich das am schlausten? Ok danke für den Vorschlag mit Box 2D möchte dann aber lieber selber den Sprung machen....
mfG
Ähnliche Themen
-
Hot Jump
Von Dicrivity im Forum Hall of FameAntworten: 4Letzter Beitrag: 22.06.09, 22:45 -
World Jump Day!
Von Ultraflip im Forum SmalltalkAntworten: 33Letzter Beitrag: 20.07.06, 23:52 -
Unable to jump to row 0?
Von Muffinmampfer im Forum Relationale DatenbanksystemeAntworten: 4Letzter Beitrag: 22.08.02, 05:49 -
[jump to] links
Von :: c0rt0na :: im Forum HTML-EditorenAntworten: 4Letzter Beitrag: 03.10.01, 14:13 -
jump and run game
Von guigui im Forum Flash PlattformAntworten: 1Letzter Beitrag: 11.09.01, 12:24



8Danke

Zitieren



Login






