Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Spiel mit Tasten (https://www.delphipraxis.net/5415-spiel-mit-tasten.html)

MadMax 5. Jun 2003 11:45


Spiel mit Tasten
 
Ich bin gerade dabei ein einfaches Spiel zu schreiben. Der Spieler spielt mit dem Nummernblock der Tastertour( die Tasten 1 bis 9). Ich hab das ganze über eine OnkeyDown Procedure aufgebaut. Mein Problem ist: Wenn eine Taste des Nummernblocks gedrückt wurde z.b die 1 dann darf dies Taste für das restliche Spiel nicht mehr benütz werden.

Wie könnte ich das am besten lösen. Hab schon versucht den rückgabewert von OnkeyDown(key) in ein Array zu speichern und dann per if schleife das ganze zu steuern aber funtzt leider nicht.

chris 5. Jun 2003 11:52

hi,

am einfachsten ist es wenn du für jede taste eine variable vom typ boolean erstellst und diese nach dem ersten benutzen der taste auf true setzt, dann kannst du ganz einfach abfragen welche tasten schon benutzt wurden und welche nicht, bei jedem neuen spiel setzt du die vars dann wieder auf false

Darty 5. Jun 2003 11:54

Dass müsste aber gehen ? Vielleicht ne Fehler in Code ? Oder was geht nicht ?

r_kerber 5. Jun 2003 11:55

Versuche es doch mal mit einem array von bool-Werten. Für jede Taste ein Element. Wenn Taste gedrückt von false auf true setzen und einen Tastendruck nur verarbeiten, wenn der zugehörige bool-Wert true ist.

MadMax 5. Jun 2003 12:12

So sieht das ganze aus.
Delphi-Quellcode:
keywert: array[1..9] of boolean = (false,false,false,false,false,false,false,false,false);

procedure Tform1.keyw(key: word);
begin
  case key of
     VK_NUMPAD1: Keywert[1] := True;
     VK_NUMPAD2: Keywert[2] := True;
     VK_NUMPAD3: Keywert[3] := True;
     VK_NUMPAD4: Keywert[4] := True;
     VK_NUMPAD5: Keywert[5] := True;
     VK_NUMPAD6: Keywert[6] := True;
     VK_NUMPAD7: Keywert[7] := True;
     VK_NUMPAD8: Keywert[8] := True;
     VK_NUMPAD9: Keywert[9] := True;
  end
end;
Das Problem ist dies for schleife mit if Anweisung. Wenn als erste das z.B die 5 gedrückt wirt ist die array[1] logischweiße auf false also wird der Anweisungsblock ausgeführt. Irgendwie hab ich da einen Denk Fehler.

Delphi-Quellcode:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var i: integer;
begin
 for i := 0 to 9 do
    if keywert[i] = false then
    begin
      form1.posi(Geo1,key);
      Geo1.kreis(form1.Canvas, Geo1.farbe);
      keyw(key);
    end

r_kerber 5. Jun 2003 12:16

Keywert ist von 1 bis 9 definiert, die Schleife durchläufst Du aber von 0 bis 9! keywert[0] existiert somit nicht.

mjenke 5. Jun 2003 12:19

Abgesehen davon wird der Anweisungsblock für jeden Tastenwert ausgeführt, der nicht auf false sitzt. Wo liegt das Problem? Oder willst Du den Anweisungsblock NUR für die gedrückte Taste ausführen?

Christian Seehase 5. Jun 2003 12:27

Moin MadMax,

ausserdem solltest Du besser nicht so abfragen

Delphi-Quellcode:
if keywert[i] = false then
sondern so

Delphi-Quellcode:
if not keywert[i] then

MadMax 5. Jun 2003 12:29

Das ändert nichts daran das der erste wert des Array false ist und somit die Anweisung ausgeführt wird.

Ich meine es würde so gehen:
Der Rückgabewert der Taste wird in einen Array eingelesen sobald sie gedrückt wir.
Als erste Teste wird die 5 gedrückt jetzt den wert in einen Array eingelesen also sieht der Array dann etwa so aus array[0] = 5 dann würde das mit der for schleife funktionieren.

Nur ich weiß nicht genau wie ich das umsetzen kann.

MadMax 5. Jun 2003 12:37

Zitat:

Zitat von mjenke
Abgesehen davon wird der Anweisungsblock für jeden Tastenwert ausgeführt, der nicht auf false sitzt. Wo liegt das Problem? Oder willst Du den Anweisungsblock NUR für die gedrückte Taste ausführen?

Wenn eine Taste in einem Spiel schon mal gedrückt wurde darf der Anweisungsblock mit dieser Taste nicht mehr ausgeführt werden.

mjenke 5. Jun 2003 12:43

Das ist schon klar. Problem ist folgendes. Wenn Du das zweite mal die 5 drückst, wird der Anweisungsblock aber immer noch 8 mal durchlaufen (1-4 und 6-9)...

Aber wenn Du die gedrückten Tasten in einem Array halten willst, kannst Du auch folgendermassen vorgehen:

Code:
procedure Tform1.keyw(key: word);
var
  counter: integer;
begin
  for counter := 1 to 9 do begin
    if Keypressed[counter] := 0 then begin
      Keypressed[counter] := Key;
      break;
    end;
  end;
end;
Du benötigst dann ein Array Keypressed, das ein array[1..9] of integer ist. Die einzelnen Felder werden mit 0 initialisiert. So kannst Du immer im ersten Feld, das eine Null beinhaltet, die aktuell gedrückte Taste speichern...

Und Deine Abfrage würden dann lauten:
Code:
for i := 1 to 9 do
    if Keypressed[i] = 0 then
    begin
:)
Matthias

MadMax 5. Jun 2003 13:02

Ok das ganze leuchtet mir ein. Die keyw Procedere ist jetzt genau so wie ich das gedacht habe. Nur es funktioniert nicht die Tasten können immer noch gedrückt werden. Ich schick mal die ganze Procedure mit. Die „voll“ Variablen sind dafür das abwechselnd gespielt werden muss(ich weiß ist nicht die beste Lösung aber auf die schnelle ist mir jetzt nicht eingefallen).
Delphi-Quellcode:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var i: integer;
begin
  if (voll = 0) or (voll = 2) or (voll = 4) or (voll = 6) or (voll = 8) then
  begin
    for i := 1 to 9 do
    if Keypressed[i] = 0 then
    begin
      form1.posi(Geo1,key);
      Geo1.kreis(form1.Canvas, Geo1.farbe);
    end
     end else
        if (voll = 1) or (voll = 3) or (voll = 5) or (voll = 7) or (voll = 9) then
        begin
          for i := 0 to 9 do
          if Keypressed[i] = 0 then
            begin
              form1.posi(Geo2,key);
              Geo2.kreis(form1.Canvas, Geo2.farbe);
            end
          end;
    keyw(key);
    inc(voll);
end;
end.

mjenke 5. Jun 2003 13:12

Dann versuch doch mal folgendes:

Code:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var i: integer;
begin

  // Prüfen, ob die Taste schonmal gedrückt wurde
  for i := 1 to 9 do begin
    if Keypressed[i] = Key then exit;   // steigt aus, wenn die Taste schonmal gedrückt wurde...
  end;

  // Weiter im Text...
  if (voll = 0) or (voll = 2) or (voll = 4) or (voll = 6) or (voll = 8) then
  begin
    for i := 1 to 9 do
    if Keypressed[i] = 0 then
    begin
Hilft das weiter?

:)
Matthias

MadMax 5. Jun 2003 13:20

Vielen Dank es Geht.

Sharky 5. Jun 2003 13:58

Hai,

nur mal als Tip:

Anstelle deiner For do Schleife kannst Du auch einfach rechnen.

Einfach ein Array [0..9] Of Boolean und beim Start alles auf False setzen.

Code:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var i: integer;
begin
  if (Keypressed[ORD (key) - 48)]) then
   begin
    exit;   // steigt aus, wenn die
   end;
  Keypressed[ORD (key) - 48)] := True // als gedrückt kenzeichnen
 . . .
 . . . // Weiter im Code

mjenke 5. Jun 2003 14:26

@Sharky

Man muss dabei nur bedenken, dass die 1 im Nummernblock nicht den Wert 49 besitzt, sondern 97. Also:
Delphi-Quellcode:
Keypressed[ORD (key) - 96)]
:)
Matthias

[edit=Daniel B]Delphi-Tags eingefügt. MfG Daniel B.[/edit]

Sharky 5. Jun 2003 15:20

Zitat:

Zitat von mjenke
@Sharky

Man muss dabei nur bedenken, dass die 1 im Nummernblock nicht den Wert 49 besitzt, sondern 97. Also:
Code:
Keypressed[ORD (key) - 96)]
:)
Matthias

Ähmmm... ORD liefert mir doch den ASCII-Code. und da ist es egal woher das zeichen '1' kommt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:12 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz