GLBasic forum

Other languages => GLBasic - de => Topic started by: D2O on 2007-Jan-21

Title: Wird der Tastaturbuffer nicht richtig gelöscht ?
Post by: D2O on 2007-Jan-21
Ich weis, ziemlich viel fragen von mir :)

Bei folgendem Code wird ein Gitter gezeichnet,
beim Druck der Spacetaste wird mit meiner Function Keyhit() die Function f_savescreen() aufgerufen.
Hier wird überprüft ob die datei schon vorhanden ist, wenn nicht-> Bildspeichern, wenn ja-> Counter solange hochzählen
bis die Datei nicht vorhanden ist und dann speichern.

Ok, das funktioniert im grunde auch, meistens ;)
Aber ab und zu scheint die Function Keyhit() immer 1 zurück zugeben und dadurch werden ratzfatz mal schnell 200 bildchen geschossen und gespeichert :)

Ist es hier möglich dass der Tastaturbuffer nicht sauber gelöscht wird?
Oder liegt das am Code?
Gibts hier Function dazu den buffer zu löschen und ich hab in über sehen?

Code (glbasic) Select
// --------------------------------- //
// Project:
// Start: Sunday, January 21, 2007
// IDE Version: 4.051



@Variabel_fuer_Bildschrim:
GLOBAL winx = 1024
GLOBAL winy = 768
GLOBAL winmode = 0
GLOBAL Bildfps = 75

@Bildschirm_einstellungen:
SETSCREEN winx,winy,winmode
LIMITFPS Bildfps


@varibalen_fuer_fps:
LET fps,fps_counter,fps_time,fps_temp

@Array_fuer_keyhit:
DIM Push123456[20][3]

WHILE TRUE
//-------------Frames berechnen-------------------------
fps_time = GETTIMERALL()
fps_counter = fps_counter + 1
IF (fps_time-fps_temp)>1000
fps_temp = fps_time
fps = fps_counter
fps_counter = 0
ENDIF
//-------------Gitter zeichnen-------------------------

f_gitter(32)

IF keyhit(57,0) = 1 THEN f_savescreen("32gitter")




//-----------------Textausgabe-------------------

PRINT fps+"/sec.",10,10


SHOWSCREEN
WEND





FUNCTION f_gitter:l_tile
LOCAL l_ix,l_iy

FOR l_ix = 0 TO winx/l_tile
DRAWLINE l_tile*l_ix,0,l_tile*l_ix,winy,RGB(255,255,255)

NEXT

FOR l_iy = 0 TO winy/l_tile
DRAWLINE 0,l_tile*l_iy,winx,l_tile*l_iy,RGB(255,255,255)
NEXT




ENDFUNCTION

FUNCTION keyhit :keyhit_in,keyhit_counter

LOCAL keyhit_counter
LOCAL keyhit_in

Push123456[keyhit_counter][0] = KEY(keyhit_in)
IF Push123456[keyhit_counter][0] = 1 AND Push123456[keyhit_counter][1] = 1 THEN Push123456[keyhit_counter][2] = 0
IF Push123456[keyhit_counter][0] = 1 AND Push123456[keyhit_counter][1] = 0
Push123456[keyhit_counter][2]= 1
Push123456[keyhit_counter][1] = 1
ENDIF
IF Push123456[keyhit_counter][0] = 0 AND Push123456[keyhit_counter][1] = 1 THEN Push123456[keyhit_counter][1] = 0
RETURN Push123456[keyhit_counter][2]
ENDFUNCTION



FUNCTION f_savescreen:l_name$
LOCAL l_count
LOCAL l_oki
LOCAL l_end = FALSE

WHILE l_end = FALSE
        l_oki = DOESFILEEXIST(l_name$+l_count+".bmp")

IF l_oki = FALSE
SAVEBMP l_name$+l_count+".bmp"
l_end = TRUE  
  ENDIF
 
 
  IF l_oki = TRUE
l_count = l_count + 1
ENDIF
WEND
ENDFUNCTION
Title: Wird der Tastaturbuffer nicht richtig gelöscht ?
Post by: Kitty Hello on 2007-Jan-22
Uiuiuiui. Das mit dem Push123456 kapier ich auf die Schnelle nicht. Aber lass' Dir doch mal (statt dem  f_savescreen) den Wert "1" auf den Bildschirm schreiben.
Title: Wird der Tastaturbuffer nicht richtig gelöscht ?
Post by: D2O on 2007-Jan-24
Quote from: GernotFrischUiuiuiui. Das mit dem Push123456 kapier ich auf die Schnelle nicht. Aber lass' Dir doch mal (statt dem  f_savescreen) den Wert "1" auf den Bildschirm schreiben.
Sorry für die späte antwort, mich hat etwas Fieber ans Bett gefesselt.

Hmm, meinst Du den Namen, weiler so merkwürdig ist?
Ich mach öfters solche komischen namen zum Testen, so schliess ich aus das ich sie irgendwo doppelt vergebe :)
Im Finalen werden sie "normal genannt".

So, der fehler ist nicht ganz leicht reproduzierbar, einmal funktionierts Tadellos, dann kommt der fehler nach dem 3. oder 4. Bild,
dann wieder gleich am ersten.
Ich habe den Code mal so modifiziert das er,
nur Maximal 11 Bilder anlegen kann und es wird eine Ausgabe.txt erstellt die bei jedem Bild den Namen und den wert von Keyhit speichert
und eine Keyhitwert.txt die den wert pro schleifendurchgang von Keyhit(), bzw. der Variablen Makepic (Die bekommt den wert von Keyhit() zugewiesen) speichert.
Keine angst ;) sie Speichert nur max. 300 Schleifen durchgänge, danach gehts bei 0 wieder los.
Hier sieht man ganz gut das der Wert anfangs 0 ist und dann irgendwann mehrere Duchrgänge auf 1 bleibt und später erst wieder auf 0 zurück geht.
Enfach mal selber Testen.

Code (glbasic) Select
// --------------------------------- //
// Project:
// Start: Sunday, January 21, 2007
// IDE Version: 4.051



@Variabel_fuer_Bildschrim:
GLOBAL winx = 1024
GLOBAL winy = 768
GLOBAL winmode = 0
GLOBAL Bildfps = 75

@Bildschirm_einstellungen:
SETSCREEN winx,winy,winmode
LIMITFPS Bildfps


@varibalen_fuer_fps:
GLOBAL  fps,fps_counter,fps_time,fps_temp

@Array_fuer_keyhit:
DIM Push[20][3] // Hier wird ein Arra genutzt um nur einen Variablen Namen zu haben und trotzdem
//mehrer unterschiedliche Tasten abzufragen
// Push 0 0 = aufnahme für key() wert
// Push 0 1 = aufnahme für Controllwert
// Push 0 2 = aufnahme für Rückgabewert der function
GLOBAL makepic
GLOBAL counter //Für die Datei Keyhitwert.txt

WHILE TRUE
//-------------Frames berechnen-------------------------
fps_time = GETTIMERALL()
fps_counter = fps_counter + 1
IF (fps_time-fps_temp)>1000
fps_temp = fps_time
fps = fps_counter
fps_counter = 0
ENDIF
//-------------Gitter zeichnen-------------------------

// f_gitter(32)
makepic = keyhit(57,0)

IF  makepic = 1 THEN f_savescreen("32gitter")




//-----------------Textausgabe-------------------
//PRINT keyhit(57,0),100,100
PRINT fps+"/sec.",10,10
PRINT "Der Wert von Keyhit ist :"+makepic,10,40
PUTFILE "Keyhitwert.txt",counter,"Scheifendurgang : "+counter+" : "+"Rückgabe von Keyhit() ist : "+makepic
counter = counter + 1
IF counter > 300 THEN counter = 0

SHOWSCREEN
WEND





FUNCTION f_gitter:l_tile
LOCAL l_ix,l_iy

FOR l_ix = 0 TO winx/l_tile
DRAWLINE l_tile*l_ix,0,l_tile*l_ix,winy,RGB(255,255,255)

NEXT

FOR l_iy = 0 TO winy/l_tile
DRAWLINE 0,l_tile*l_iy,winx,l_tile*l_iy,RGB(255,255,255)
NEXT




ENDFUNCTION

FUNCTION keyhit :keyhit_in,keyhit_counter //Key(),Counter für Array Push [X] []

LOCAL keyhit_counter
LOCAL keyhit_in

Push[keyhit_counter][0] = KEY(keyhit_in) //Dem Array [0] [0] den wert von Key() übergeben

// Wenn Key() gedrückt und Controllwert 1 ist dan ist die Rückgabe 0
IF Push[keyhit_counter][0] = 1 AND Push[keyhit_counter][1] = 1 THEN Push[keyhit_counter][2] = 0
// Wenn Key() gedrückt und Controllwert 0 ist, controllwert aus 1 setzen und Rückgabe 1
IF Push[keyhit_counter][0] = 1 AND Push[keyhit_counter][1] = 0
Push[keyhit_counter][1]= 1
Push[keyhit_counter][2] = 1
ENDIF
// Wenn Key() nicht gedrückt ist und controllwert 1 ist dann controllwert auf 0 zurücksetzten
IF Push[keyhit_counter][0] = 0 AND Push[keyhit_counter][1] = 1 THEN Push[keyhit_counter][1] = 0
RETURN Push[keyhit_counter][2]
ENDFUNCTION



FUNCTION f_savescreen:l_name$
LOCAL l_count
LOCAL l_oki
LOCAL l_end = FALSE

WHILE l_end = FALSE
//Überprüfung ob die datei vorhanden ist
        l_oki = DOESFILEEXIST(l_name$+l_count+".bmp")
//Wenn nicht, datei erstellen und die schleife beenden
IF l_oki = FALSE
SAVEBMP l_name$+l_count+".bmp"
l_end = TRUE
  ENDIF

// wenn ja, l_counter um eins zu erhöhen um den Dateinamen zu ändern
  IF l_oki = TRUE
l_count = l_count + 1
ENDIF

//Ne einfache Kontrolle ausgeben/speichern
PUTFILE "Ausgabe.txt",l_count,"Name des Bildes ist: "+l_name$+l_count+".bmp"+" : "+"Status von keyhit ist: "+makepic
IF l_count > 10 THEN l_end = TRUE //Nicht mehr als 11 Bilder speichern
WEND
ENDFUNCTION
Hier mal einen Ausschnitt von der Ausgabe(Gekürzt),
Interssant ist der durchgang "74 - 78"
Quote from: "Keyhitwert.txtScheifendurgang : 0 : Rückgabe von Keyhit() ist : 0
Scheifendurgang : 1 : Rückgabe von Keyhit() ist : 1
Scheifendurgang : 2 : Rückgabe von Keyhit() ist : 0
Scheifendurgang : 3 : Rückgabe von Keyhit() ist : 0
Scheifendurgang : 4 : Rückgabe von Keyhit() ist : 0Scheifendurgang : 34 : Rückgabe von Keyhit() ist : 0
Scheifendurgang : 35 : Rückgabe von Keyhit() ist : 0
Scheifendurgang : 69 : Rückgabe von Keyhit() ist : 0
Scheifendurgang : 70 : Rückgabe von Keyhit() ist : 0
Scheifendurgang : 71 : Rückgabe von Keyhit() ist : 0
Scheifendurgang : 72 : Rückgabe von Keyhit() ist : 0
Scheifendurgang : 73 : Rückgabe von Keyhit() ist : 0
Scheifendurgang : 74 : Rückgabe von Keyhit() ist : 1
Scheifendurgang : 75 : Rückgabe von Keyhit() ist : 1
Scheifendurgang : 76 : Rückgabe von Keyhit() ist : 1
Scheifendurgang : 77 : Rückgabe von Keyhit() ist : 1
Scheifendurgang : 78 : Rückgabe von Keyhit() ist : 1

Scheifendurgang : 79 : Rückgabe von Keyhit() ist : 0
Scheifendurgang : 80 : Rückgabe von Keyhit() ist : 0
Scheifendurgang : 81 : Rückgabe von Keyhit() ist : 0
Scheifendurgang : 94 : Rückgabe von Keyhit() ist : 0
Scheifendurgang : 95 : Rückgabe von Keyhit() ist : 0
[...]
Scheifendurgang : 243 : Rückgabe von Keyhit() ist : 0
Scheifendurgang : 244 : Rückgabe von Keyhit() ist : 1
Scheifendurgang : 245 : Rückgabe von Keyhit() ist : 0
Title: Wird der Tastaturbuffer nicht richtig gelöscht ?
Post by: Kitty Hello on 2007-Jan-24
Also, damit ich das richtig verstehe, Du willst quasi einen KeyUp / KeyDown unterscheiden können, oder?
Schau mal, ob das hilft:

Code (glbasic) Select
WHILE TRUE
KeyHitUpdate()

PRINT "SpaceBar-State:" + KeyHit(57), 100,100
IF KeyHit(57)=-1
INC tips, 1
PRINT "*BING*", 100, 120
ENDIF

PRINT "Tipps"+tips, 100, 140

HIBERNATE
SHOWSCREEN
WEND


// Update keyboard state
FUNCTION KeyHitUpdate:
GLOBAL gKeyDown[], gKeyState[]
LOCAL  k
// First Time call/ zum ersten Mal hier
IF BOUNDS(gKeyDown[],0)=0
DIM gKeyDown[256]
DIM gKeyState[256]
ENDIF

// For each key / für jede Taste
FOR i=0 TO 255
k = KEY(i)
// Key is pressed / Taste ist gedrückt
IF k
gKeyDown[i]=1
gKeyState[i]=1
ELSE
// Key is not pressed / Taste nicht gedrückt

// Has key been pressed before?
// War die Taste gedrückt?
IF gKeyDown[i]
gKeyDown[i] = 0
gKeyState[i] = -1
ELSE
gKeyState[i]=0
ENDIF
ENDIF
NEXT
ENDFUNCTION

//  0 = not pressed / nicht gedrückt
//  1 = pressed / gedrückt (gehalten)
// -1 = release event / wieder losgelassen
FUNCTION KeyHit: nkey
RETURN gKeyState[nkey]
ENDFUNCTION
Grundätzliche Frage: Will jemand so eine Funktion haben? Also: Soll GLBasic ein KEYUP zur Verfügung stellen, oder reicht der Code hier?
Title: Wird der Tastaturbuffer nicht richtig gelöscht ?
Post by: D2O on 2007-Jan-24
Hmm, ne.

Deine Function sagt ja auch nur ob die Taste Gedrückt wird plus halt ob die Taste wieder losgelassen wurde.
Das was ich meine ist, das der Rückgabe wert nur einen schleifendurchgang den rückgabewert 1 hat.
Danach soll er wieder 0 sein egal ob die taste noch gedrückt ist und erst wieder eine 1 zurückgeben kann
wenn die taste losgelasen und erneut gedrückt wurde.

Als beispiel könnte man das springe einer Figur nehmen, sie soll bei Tastendruck  1x springen und erst
wieder bei erneuten Drücken springen.

In einem andern Basic gibts hier ein
Keydown()  = solange true wie die Taste gedrückt wird
und ein
Keyhit() = wird nur einmalig 1 zurück gegeben bis sie losgelassen und erneut gedrückt wird.
Title: Wird der Tastaturbuffer nicht richtig gelöscht ?
Post by: Kitty Hello on 2007-Jan-24
Code (glbasic) Select
LIMITFPS 10

WHILE TRUE
    KeyHitUpdate()
   
    PRINT "SpaceBar-State:" + KeyHit(57), 100,100
    IF KeyHit(57)=2
        INC tips, 1
        PRINT "*BING*", 100, 120
    ENDIF
    IF KeyHit(57)=-1
        PRINT "*BONG*", 100, 120
    ENDIF
   
    PRINT "Tipps"+tips, 100, 140

    HIBERNATE
    SHOWSCREEN
WEND


// Update keyboard state
FUNCTION KeyHitUpdate:
GLOBAL gKeyDown[], gKeyState[]
LOCAL  k
    // First Time call/ zum ersten Mal hier
    IF BOUNDS(gKeyDown[],0)=0
        DIM gKeyDown[256]
        DIM gKeyState[256]
    ENDIF

    // For each key / für jede Taste
    FOR i=0 TO 255
        k = KEY(i)
        // Key is pressed / Taste ist gedrückt
        IF k
        IF gKeyDown[i]
        gKeyState[i]=1
ELSE
           gKeyDown[i]=1
           gKeyState[i]=2
ENDIF
        ELSE
            // Key is not pressed / Taste nicht gedrückt

            // Has key been pressed before?
            // War die Taste gedrückt?
            IF gKeyDown[i]
                gKeyDown[i] = 0
                gKeyState[i] = -1
            ELSE
                gKeyState[i]=0
            ENDIF
        ENDIF
    NEXT
ENDFUNCTION

//  0 = not pressed / nicht gedrückt
//  2 = just pressed / gerade runtergedrückt
//  1 = pressed / gedrückt (gehalten)
// -1 = release event / wieder losgelassen
FUNCTION KeyHit: nkey
    RETURN gKeyState[nkey]
ENDFUNCTION
So? Also:
IF KeyHit(nkey) = 2 THEN Savesomething()
Title: Wird der Tastaturbuffer nicht richtig gelöscht ?
Post by: D2O on 2007-Jan-24
Ohhh :)
genau das.

Hier wird halt die 2 zurückgegen aber genauso wie ich mir das dachte :booze:
Werde das mal für meine zwecke nutzen und testen.

Nur, was ist hier an meinem Code denn falsch, das ich solche Rückgabe werte bekomme?
Hat einer mal den Code getestet und kann mir einer sagen obs bei Ihm auch so "Unkontrolliert" läuft?
Title: Wird der Tastaturbuffer nicht richtig gelöscht ?
Post by: Kitty Hello on 2007-Jan-24
Ich bin bisserl krank und kann Deinen Code garade nicht nachvollziehen, sorry.
Übrigens:
    LOCAL keyhit_counter
    LOCAL keyhit_in
brauchst Du nicht, wenn die Werte Übergabeparameter der Funktion sind. Sollte eigentlich einen Fehler ausgeben ;)
Title: Wird der Tastaturbuffer nicht richtig gelöscht ?
Post by: D2O on 2007-Jan-24
Quote from: GernotFrisch1.
Ich bin bisserl krank und kann Deinen Code garade nicht nachvollziehen, sorry.
Übrigens:

2.    LOCAL keyhit_counter
    LOCAL keyhit_in

brauchst Du nicht, wenn die Werte Übergabeparameter der Funktion sind. Sollte eigentlich einen Fehler ausgeben ;)
1.  :) Ich weis, ich bin der Meister der Verwirrung :)

2. War mir jetzt nicht sicher ob die Variablen outomatisch als Local laufen, darum  nochmals explizit als Local declariert.
   Aber ne Fehlermeldung gibt hier nicht, das einzige was kommt ist eine Warnung.
Quote"FPS_anzeige.gbas"(23) warning : implicitly created GLOBAL  : Push
Ich habe den Code von mir mit Deinen Functionen getestet, läuft tadellos ohne Fehler.
Danke.