Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

sebi

Frischling

  • »sebi« ist der Autor dieses Themas
  • Private Nachricht senden

1

09.12.2009, 10:26

SDL texte eingabe

Hallo unf guten morgen,

da ich neu bin eine kurze vorstellung
mein name ist sebastian aka sebi
bin 22 komme aus bremen
und programmiere seit ich 13 bin.

so nun zum problem.
momentan arbeite ich an einem remake eines amiga spiels
das ich sehr geliebt habe. dafür brauch ich eine texte eingabe box.
ich habe auch schon einen kleinen code schnipsel dazu geschrieben,
der aber leider nicht funktionierz.da ich momentan in der schule bin
kann ich ihn grade nicht senden, werde ihn aber heute abend nach reichen.

den teil mit der texte eingabe kann ich aber schon posten.

C-/C++-Quelltext

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
void drawTextBox(SDL_Surface* screen, const char* string, TTF_Font* font)
{

SDL_Event evt;

.
.
.

if(*selected == true)
{
   while(SDL_PollEvent(&evt))
   {
       swich(evt.type)
       {
        case SDL_KEYDOWN:
           {        
               string = SDL_GetKeyName(evt.key.keysym.sym); //momentan zum wird nur die gedrueckte taste gespeichert

               drawText( screen, font, string, x + 5, y + 8, 255, 0, 0); //selbst geschrieben funktion!!!

            }
         }
   }
}
.
.
.
}


so ich hoffe ich hab mich richtig dran erinnert
und freue mich auf hilfe, denkanstöße und kritik

schönen gruß aus dem norden
sebi

2

09.12.2009, 11:00

Hm.

Wäre es nicht einfacher die gedrückten Tasten erstmal alle aufzufangen und dann beim drücken der Enter-Taste oder eines Ok-Buttons dann in deinen string zu swappen?

sebi

Frischling

  • »sebi« ist der Autor dieses Themas
  • Private Nachricht senden

3

09.12.2009, 11:06

aber dann würde man ja gar nicht sehen was man getippt hat
deswegen lasse ich den string ja direkt danach anzeigen

edit:
ganz vergessen hier die fehlerbeschreibung: xD
es wird mir gar nix angezeigt.
also kein buchstabe

4

09.12.2009, 12:13

Hm,

hilft so auch nicht sonderlich weiter. Der Fehler könnte auch in drawText() liegen.
Versuch's mal zu Debuggen wegen Wertübergabe an Variable und wie sich die Funktion verhält.

5

09.12.2009, 12:35

Wenn ich anstatt drawText eine eigene Funktion verwende funktioniert es. Die Frage ist ob du überhaupt wirklich SDL_GetKeyName verwenden möchtest. Dort bekommst du nämlich genau das was die Funktion aussagt, also den Namen der Taste. Die Leertaste heißt bei mir zb "space"...
Tutorials zu OpenGL, Ubuntu und Programmieren allgemein: www.tomprogs.at

Forum und Wiki zum Programmieren lernen: proggen.org/forum.proggen.org

sebi

Frischling

  • »sebi« ist der Autor dieses Themas
  • Private Nachricht senden

6

09.12.2009, 17:58

wie gesagt die funktion liegt noch in den kinderschuhen.^^

ich füge hier mal eben den code an:

C-/C++-Quelltext

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
void drawTextBox(SDL_Surface* screen, TTF_Font* font, const char* string, int x, int y, bool* selected, bool* othersel)
{
    int iMausX, iMausY, iClick;
    SDL_Rect rctTextBox;
    SDL_Event evt;

    rctTextBox.x = x;
    rctTextBox.y = y;

    iClick = SDL_GetMouseState( &iMausX, &iMausY);

    if((iMausX > x) && (iMausY > y) && (iMausX < (x + 256)) && (iMausY < (y + 35)))
    {
        if(iClick && SDL_BUTTON(SDL_BUTTON_LEFT))
        {
            *selected = true;
            *othersel = false;
        }
    }

    if(*selected == true)
    {
        SDL_BlitSurface(imgTextBoxH, NULL, screen, &rctTextBox);

        while(SDL_PollEvent(&evt))
        {
            switch(evt.type)
            {
                case SDL_KEYDOWN:
                {
                string = SDL_GetKeyName(evt.key.keysym.sym);
                printf("%s", string);
                break;
                }
            }
        }

        drawText(screen, font, string, (x + 5), (y + 8), 255, 0, 0);
    }
    else
    {
        SDL_BlitSurface(imgTextBox, NULL, screen, &rctTextBox);
    }
}


und hier für mein drawtext funktion

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
void drawText(SDL_Surface* screen, TTF_Font* font, const char* string, int x, int y, int fR, int fG, int fB)
{
    SDL_Color color = { fR, fG, fB };

    SDL_Surface* textSurface = TTF_RenderText_Blended(font, string, color);

    SDL_Rect textLocation = { x, y, 0, 0 };

    SDL_BlitSurface(textSurface, NULL, screen, &textLocation);
    SDL_FreeSurface(textSurface);
}


so viel dazu.
@tom meintest du ich sollte vllt GetKeyState verwenden?
und müsste ich nicht dann eine if verzweigung einbauen
um den buchstaben zu bekommen? weil getkeystate uint8 zurück gibt

edit:
übrigens wenn ich an statt drawtext printf benutze
bekomme ich die eingabe in der konsole beim programmende
aber nicht alle gedrückten tasten

sebi

Frischling

  • »sebi« ist der Autor dieses Themas
  • Private Nachricht senden

7

09.12.2009, 19:07

ein kurzes erfolgserlebnis
ich habe die event schleife auf

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
while(SDL_PollEvent(&evt))
        {
            switch(evt.type)
            {
                case SDL_KEYDOWN:
                {
                    keystate = SDL_GetKeyState(NULL);
                    if(keystate[SDLK_a])
                    {
                        string = "a";
                    }
                    break;
                }
            }
        }

        printf("%s", string);
        drawText(screen, font, string, (x + 5), (y + 8), 255, 0, 0);


und es wurde ganz kurz das a angezeigt, aber es verschwand gleich wieder.
und dank getkeystate kann die zweite schleife weg xD

8

09.12.2009, 23:37

Ich würde nicht GetKeyState verwenden, da du damit ja nur den aktuellen Zustand der Tastatur bekommst, also eine ungepufferte Eingabe. Vor allem würde ich das nicht zusätzlich noch in die Nachrichtenschleife einbauen, also zur gepufferten Eingabe dazu.

Leider ist, wie in einem Beitrag in der Mailinglist der SDL erwähnt ist die Texteingabe mit der SDL 1.2 noch etwas ein Durcheinander. Ich würde versuchen Unicode zu aktivieren und dann bekommst du die entsprechenden Zeichen im unicode Feld von keysym. Näheres dazu findest du auch in der Dokumentation.

Zitat von »"sebi"«

übrigens wenn ich an statt drawtext printf benutze
bekomme ich die eingabe in der konsole beim programmende

Kein Wunder. Da du am Ende von deinem printf kein \n hast wird die Ausgabe vor dem Beenden auch nicht geflusht.

Zitat von »"sebi"«

aber nicht alle gedrückten tasten

Irgendwelche speziellen Tasten, oder einfach scheinbar zufällig?

Zu deiner drawText Funktion. SDL_ttf hab ich schon länger nicht mehr verwendet, aber soweit schaut es ganz vernünftig aus. Die Funktion drawTextBoxt kommt mir nur etwas eigenartig vor. Was sollte die denn genau tun? Damit die Funktion so wie sie jetzt ist funktioniert musst du sie in einer Schleife oder so aufrufen, da die Eingabe nur solange funktioniert wie auch die Keyevents abgefragt werden. Außerdem würden in dieser Schleife leicht wichtige Events wie zb SDL_QUIT verloren gehen. Und sollte in string nicht wirklich ein String sein und nicht immer nur eine einzelnes Zeichen?

Und weitere Anregungen für eine GUI bzw. Texteingabe kannst du auf dieser Seite finden.
Tutorials zu OpenGL, Ubuntu und Programmieren allgemein: www.tomprogs.at

Forum und Wiki zum Programmieren lernen: proggen.org/forum.proggen.org

sebi

Frischling

  • »sebi« ist der Autor dieses Themas
  • Private Nachricht senden

9

15.12.2009, 20:16

soo nabend mal wieder
hatte etwas viel stress mit arbeit und so.

back to the topic

@tom
das printf ist auch nur zu debug zwecken und kommt noch weg und
meine funktion sieht nun so aus:

C-/C++-Quelltext

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
const char* drawTextBox(SDL_Surface* screen, TTF_Font* font, const char* string, int x, int y, bool* selected, bool* othersel)
{
    int iMausX, iMausY, iClick;

    char* defString = new char[strlen(string) + 2];

    strcpy(defString, string);

    SDL_Rect rctTextBox;

    Uint8 *keystate;

    rctTextBox.x = x;
    rctTextBox.y = y;

    iClick = SDL_GetMouseState( &iMausX, &iMausY);

    if((iMausX > x) && (iMausY > y) && (iMausX < (x + 256)) && (iMausY < (y + 35)))
    {
        if(iClick && SDL_BUTTON(SDL_BUTTON_LEFT))
        {
            *selected = true;
            *othersel = false;
        }
    }

    if(*selected == true)
    {
        SDL_BlitSurface(imgTextBoxH, NULL, screen, &rctTextBox);

        keystate = SDL_GetKeyState(NULL);

        if(keystate[SDLK_a])
        {
            defString[strlen(string)] = 'a';
            defString[strlen(string) + 1] = 0;
        }
        else if(keystate[SDLK_b])
        {
            defString[strlen(string)] = 'b';
            defString[strlen(string) + 1] = 0;
        }
        else if(keystate[SDLK_c])
        {
            defString[strlen(string)] = 'c';
            defString[strlen(string) + 1] = 0;
        }
        else if(keystate[SDLK_d])
        {
            defString[strlen(string)] = 'd';
            defString[strlen(string) + 1] = 0;
        }
    }
    else
    {
        SDL_BlitSurface(imgTextBox, NULL, screen, &rctTextBox);
    }
    drawText(screen, font, defString, (x + 5), (y + 8), 255, 0, 0);
    printf("%s", defString);

    return defString;
}


sie zeichet ein bild was die text box ist und regelt die eingabe
allerdings sind halt noch nich alle tasten eingebaut. und viel wichtiger mein neues problem. je länger die taste gedrückt wird um so öfter wird der buchstabe eingefügt.
prinzipiell kein problem, nur das ich halt die taste kurz drücke und der buchstabe auch nach kurzem druck 6-7 mal erscheint.

gruß sebi

10

15.12.2009, 20:26

Leg dir doch 2 buffer an, einen mit den aktuellen Werten, einen mit den zuletzt abgefragten, und guck dann, ob die Taste im Letzten Frame gedrückt wurde, und in diesem nicht mehr, -> Sie wurde losgelassen.
Altenative wäre ein Delay nach jedem Tastendruck ;)

Werbeanzeige