_kbhit() und SDL
-
Hallo Leute.
bin zwar nicht soo neu hier, dennoch ist dies mein erster Post, stiller Mitleser bisweilen.
Also, bin gerade dabei das Spiel Nibbles nachzumachen. Wer kennt es nicht...
Und scheitere bei der Abfrage nach einer Taste... *G
wie kann ich die while schleife unterbrechen, indem ich eine beliebige Taste drücke, wo liegt der Fehler in meinem Code?Kann es sein, dass ich SDL und den Befehl _kbhit nicht miteinander kombinieren kann, und ein Pollevent anlegen muss?
bin schon am verzweifeln weil ich keinen Fehler entdecken kann.
Google & Suchfkt dieses schönen Forums bringt mir kein Ergebnis.
(bitte die ganzen eingebundenen Headers ignorieren, da ich sie zum Lerneffekt stehengelassen habe)#include "stdafx.h" #include "windows.h" #include "SDL.h" #include "stdio.h" #include "stdlib.h" #include "time.h" #include "conio.h" #pragma comment(lib, "SDL.lib") #undef main void DrawPixel(SDL_Surface *screen, int x, int y,Uint8 R, Uint8 G,Uint8 B) { Uint32 color = SDL_MapRGB(screen->format, R, G, B); SDL_LockSurface(screen); Uint16 *bufp; bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x; *bufp = color; SDL_UnlockSurface(screen); } int main(int argc, char *argv[]) { //FreeConsole(); int x=100,y=100; char direction = 'r'; char key; bool done=false; SDL_Surface *screen; //GFX SDL_Init(SDL_INIT_VIDEO); screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE); while( !_kbhit() ) // Wieso funzt das net { DrawPixel (screen, x, y, 255,255,255); SDL_Flip(screen); switch(direction){ case 'r': x++;break; case 'l': x--;break; case 'o': y--;break; case 'u': y++;break;} if (x > 640) done = TRUE; // switch(key){ // case 'd': direction = 'r';break; //case 'a': direction = 'l';break; //case 'w': direction = 'o';break; //case 's': direction = 'u';break; } } SDL_Quit(); return 0; }
-
Deine Schleife wird ausgeführt, bis eine Taste gedrückt wurde! Das willst du doch nicht, ne? Du willst Stillstand, bis eine Taste gedrückt wurde, und im Anschluss soll dann ausgewertet werden, welche Taste.
Also eher so (grob aus dem Kopf, Anpassungen könnten nötig sein
):while(bContinue) { while(!_kbhit()); //Stillstand, bis Taste gedrückt wird char c=getch(); //Taste wurde gedrückt, also Zeichen aus dem Eingabepuffer holen switch(c) { //Zeichen auswerten (z.B. bei Escape bContinue auf false setzen...) //... } }EDIT: Übrigens führst du ein switch auf key aus, ohne key jemals einen Wert zugewiesen zu haben...
-
_matze schrieb:
Deine Schleife wird ausgeführt, bis eine Taste gedrückt wurde! Das willst du doch nicht, ne?
.
.
.
EDIT: Übrigens führst du ein switch auf key aus, ohne key jemals einen Wert zugewiesen zu haben...zu 1. doch
zu 2. irrelevant, es geht nur um _kbhit()...
...
jemand anderes ne Idee?
-
tommi schrieb:
zu 2. irrelevant
Wenn du meinst, dass Fehler in deinem Programm irrelevant sind, dann bitte...

-
_matze schrieb:
tommi schrieb:
zu 2. irrelevant
Wenn du meinst, dass Fehler in deinem Programm irrelevant sind, dann bitte...

es ist nur eine Warnung, und kein compilerfehler. mein Programm ist nicht fertig.
jemand anderes ne Idee?
-
Es ist ein semantischer Fehler. Was ist daran so schwer zu verstehen? Normalerweise sind hier alle froh, wenn man sie auf ihre Fehler hinweist...
EDIT: Im Übrigen solltest du auf deine Einrückung achten.

-
Danke für den Tipp. wie gesagt, bin gerade noch in einer Lehrphase.
Um zu verstehen, sollte man doch am besten auf seine Art lernen,
wie er am besten kann. Und da nervt mich diese Formsachen.
Aber ich verspreche dir, ich werde mich bessern.
Hast du vielleicht ne Idee zu meinem Problem?
Die Schleife zu unterbrechen sehe ich nicht als Herausforderung im eigentlichen Sinne. sondern nur dass ich die Schleife einfach nicht durch eine beliebige Taste unterbrechen kann.
Es geht darum wieso !_kbhit() nicht so funktioniert, wie es sollte.
Hast ne evtl. ne Lösung?grüsse Tommi
-
Hm, ich wüsste nicht warum _kbhit nicht funktionieren sollte. Bastel dir doch mal ein Minimal-Beispiel, und wenn das funktioniert, füge Schritt für Schritt deine anderen Anweisungen hinzu. Also erstmal einfach sowas hier:
while(!_kbhit()) { } MessageBox("Taste gedrückt!");
-
_matze schrieb:
Hm, ich wüsste nicht warum _kbhit nicht funktionieren sollte. Bastel dir doch mal ein Minimal-Beispiel, und wenn das funktioniert, füge Schritt für Schritt deine anderen Anweisungen hinzu. Also erstmal einfach sowas hier:
...habe ich getan, es funktioniert alles wie erwartet, sobald ich SDL mit einbinde, funktioniert es nicht mehr. Meine Vermutung erhärtet sich.
Ich werde es heute mal mit einem Pollevent versuchen.Danke für die Hilfe
-
Wie ich bereits vermutet habe, muss man offensichtlich ein Pollevent anlegen, weil SDL, aus welchen Gründen auch immer _kbhit() blockiert...
so klappts:
#include "stdafx.h" #include "windows.h" #include "SDL.h" #pragma comment(lib, "SDL.lib") #undef main void DrawPixel(SDL_Surface *screen, int x, int y,Uint8 R, Uint8 G,Uint8 B) // Pixel zeichnen (16bit) { Uint32 color = SDL_MapRGB(screen->format, R, G, B); SDL_LockSurface(screen); Uint16 *bufp; bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x; *bufp = color; SDL_UnlockSurface(screen); } int main(int argc, char *argv[]) { FreeConsole(); int x=100,y=100; char direction = 'r'; bool done=false; SDL_Event event; Uint8 *keys; SDL_Surface *screen; //GFX SDL_Init(SDL_INIT_VIDEO); screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE); SDL_Rect dst;dst.x = 0;dst.y = 0;dst.w = 640;dst.h = 480; //Hintergrund rot SDL_FillRect(screen, &dst, SDL_MapRGB(screen->format, 255, 0, 0)); while (!done) { //Pollevent while (SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: done = 1; break; }} DrawPixel (screen, x, y, 0,0,0); //1 Pixel zeichnen SDL_Flip(screen); keys = SDL_GetKeyState(NULL); // Tastaturabfrage über SDL if (keys[SDLK_UP]) { direction = 'o';} if (keys[SDLK_DOWN]) { direction = 'u';} if (keys[SDLK_RIGHT]) { direction = 'r';} if (keys[SDLK_LEFT]) { direction = 'l';} if (keys[SDLK_ESCAPE]) {done = TRUE;} switch(direction){ //Richtung case 'r': x++;break; case 'l': x--;break; case 'o': y--;break; case 'u': y++;break;} if (x >= 640) done = TRUE; // Kollision if (x <= 0) done =TRUE; if (y <= 0) done =TRUE; if (y >= 480) done =TRUE; } SDL_Quit(); return 0; }danke Matze