Entwickler-Ecke

Sonstiges (Delphi) - Automatisches Droppen von Dingen vom oberen Bildschirmrand


EMP_Rockhand - Sa 21.02.15 11:45
Titel: Automatisches Droppen von Dingen vom oberen Bildschirmrand
Hallo liebes Forum,
ich habe ein Problem. Ich versuche für den Informatik Unterricht ein kleines Spiel zu programmieren, bei dem eine Figur im Fenster nach links und rechts läuft und dabei Münzen auffängt, die vom oberen Bildschirmrand fallengelassen werden. Wie kann ich es also realisieren, dass ich das gleiche Image automatisch von verschiedenen Positionen am oberen Fensterrand fallen lassen kann?

Vielen Dank schon mal :)


Xion - Sa 21.02.15 14:46

:welcome:

Ein Image hat nur eine Position. Wenn du mehrere Dinge fallen lassen willst, dann kannst du zum Beispiel mehrere Images benutzen.
Um die nicht von Hand erzeugen zu müssen, und um auch besser darauf zugreifen zu können, kannst du folgenden Code benutzen, der mehrere Images in einem Array anlegt:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var coins: array of TImage;

//OnCreate der Form:
Setlength(coins, Maximale_Muenzen_Zahl);
for A:= 0 to High(coins) do
  begin
    coins[A] := TImage.Create(Form1);
    coins[A].Parent := Form1;
    coins[A].Picture.LoadFromFile( ExtractFilePath(Application.ExeName)+'coin.png');
    coins[A].Visible := false;
  end;


Dann kannst du einfach deine "FallenLassen"-Funktion anpassen:

Delphi-Quelltext
1:
2:
3:
4:
5:
procedure FallenLassen;
begin
  for A:= 0 to High(coins) do
    coins[A].Top := coins[A].Top - 1;
end;


Wenn du feststellst, dass eine Münze aufgesammelt wurde (oder sonst irgendwie verschwunden ist) dann kannst du sie wieder von oben fallen lassen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure ResetCoin(id: integer);
begin
  coins[id].top := -coins[id].height;  //oberer Bildschirmrand
  coins[id].left := random(Form1.ClientWidth);  //zufällig in der Breite
  coins[id].visible := true;
end;


EMP_Rockhand - Sa 21.02.15 15:52

vielen Dank! das hat mir sehr geholfen!!


Delete - So 22.02.15 15:40

Crosspost nennt man das, was du hier machst: Zeitgleich in zwei oder mehreren Foren dieselbe Frage stellen. Um nicht unnötig das Hirn von Leuten zu zermartern, ist es üblich, auf Crossposts hinzuweisen und diese zu verlinken [http://forum.delphi-treff.de/index.php/Thread/59956-Automatisches-Droppen-von-Dingen-vom-oberen-Bildschirmrand/?postID=442934], so wie ich das hier für dich erledige.


EMP_Rockhand - So 22.02.15 19:04

Eine Frage noch: gibt es eine Möglichkeit meine Figur mit durchgängigem Tastendruck zu bewegen, sodass ich nicht immer so oft nach links oder rechts drücken muss?


Jann1k - So 22.02.15 19:31

Ja, da gibt es mehrere.

Ich denke mal im Moment bewegst du deine Figur im OnkeyDown-Event deines Formulars. Dieses Event wird genau einmal ausgeführt (und zwar beim tastendruck). Wenn du stattdessen das OnKeyPress-Event verwendest, wird das Event solange ausgeführt, wie die Taste gedrückt bleibt.

Alternativ könntest du auch einen Timer verwenden (der periodisch ein Event ausführt). Suche dazu einfach mal ein weneig im Forum, hier gibts viele Threads dazu.


EMP_Rockhand - So 22.02.15 19:51

wenn ich die variante mit dem OnKEyPress verwende, bekomme ich in der Prozedur :


Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.dp1(Sender: TObject; var Key: Char);
begin
  if Key=VK_LEFT then Image1.Left:=Image1.Left-15;
  if Key=VK_RIGHT then Image1.Left:=Image1.Left+15;
end;


die Fehlermeldung : Inkompatible Typen.
Wie ist das zu beheben?

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


EMP_Rockhand - So 22.02.15 20:12

mir ist eingefallen, dass OnKeyPress im Gegensatz zu OnKeyUp und OnKeyDown den ASCII braucht. .. aber was sind die ASCII-Codes für Pfeiltasten?


Stundenplan - So 22.02.15 21:40

Wüsste nicht, dass es die gäbe... ;-)
Das ist mit KeyPress nicht wirklich zu lösen, da wären OnKeyDown/Up schon geschickter, die liefern die VK-Codes als Parameter... Da diese Events aber rausfallen, bleibt bloß noch der Griff zu nem Timer, der in kurzen Abständen überprüft, ob GetAsyncKeystate(VK_...) < 0 ergibt, z.B.:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TFormXX.TimerXTimer(Sender: TObject);
begin
  if GetAsyncKeystate(VK_LEFT) < 0 then
    //...
  else if GetAsyncKeystate(VK_RIGHT) < 0 then
    //...
end;


EMP_Rockhand - Mo 23.02.15 06:44

OK vielen Dank!