Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Wiederholen einer aktion (https://www.delphipraxis.net/166262-wiederholen-einer-aktion.html)

louisnws 4. Feb 2012 23:14

Wiederholen einer aktion
 
Hallo,
Ich versuche ein Programm zu erstellen in dem man ein Quadrat steuert und ein anderes quadrat flüchtet
das flüchten habe ich erreicht durch einen zufallsgenerator und folgenden quelltext:
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  zufall:=random(4);
  if Zufall = 0 then inc(JagdX,10);
  if Zufall = 1 then dec(JagdX,10);
  if Zufall = 2 then inc(JagdY,10);
  if Zufall = 3 then dec(JagdY,10);
So das problem ist ja offensichtlich :( das quadrat bewegt sich in jede Richtugn mit derselben warscheinlichkeit. D.h. es haut nicht so richtig ab! es wackelt immer nur hin und her zwar bewegt es sich schon aber abhauen tut es halt nicht richtig
Also was ich bräuchte wäre entweder eine schleife sozusagen mache 3schritte nach links wenn random=0
nicht einen großen schritt weil dann ist es so Zackig ich wills flüßig!
und meine Lösung dafür das es die Ränder nicht überschreitet is auch eher arm
Delphi-Quellcode:
If
  (JagdX + 50 > 778) then dec(JagdX,20);

  If
  (Jagdy + 50 > 470) then dec(Jagdy,20);

  if
  (JagdX < 5) then inc(JagdX,20);

  If
  (JagdY < 7) then inc(Jagdy,20);
end;
hat da eienr noch ne bessere idee?

Coffeecoder 5. Feb 2012 07:57

AW: Wiederholen einer aktion
 
Zitat:

Zitat von louisnws (Beitrag 1149289)
Hallo,
Ich versuche ein Programm zu erstellen in dem man ein Quadrat steuert und ein anderes quadrat flüchtet
das flüchten habe ich erreicht durch einen zufallsgenerator und folgenden quelltext:
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  zufall:=random(4);
  if Zufall = 0 then inc(JagdX,10);
  if Zufall = 1 then dec(JagdX,10);
  if Zufall = 2 then inc(JagdY,10);
  if Zufall = 3 then dec(JagdY,10);

Hast du da mal mit einer For-Schleife versucht?
Hier kannst du auch eine Case-Anweisung benutzen ;)

Delphi-Quellcode:
case random(4)of
  0: inc(JagdX,10);
  1: dec(JagdX,10);
  2: inc(JagdY,10);
  3: dec(JagdY,10);
end;
Zitat:

Zitat von louisnws (Beitrag 1149289)
und meine Lösung dafür das es die Ränder nicht überschreitet is auch eher arm
Delphi-Quellcode:
If
  (JagdX + 50 > 778) then dec(JagdX,20);

  If
  (Jagdy + 50 > 470) then dec(Jagdy,20);

  if
  (JagdX < 5) then inc(JagdX,20);

  If
  (JagdY < 7) then inc(Jagdy,20);
end;
hat da eienr noch ne bessere idee?

Wofür steht die Zahl "778"? Ich nehme die Breite des Forumlars? Schreib dies:
Delphi-Quellcode:
If
  (JagdX + 50 > form1.clientwidth) then dec(JagdX,20);
Wenn du magst, kannst du ja deinen gesamten Code anhängen, dann können wir das genauer ansehen.

himitsu 5. Feb 2012 08:24

AW: Wiederholen einer aktion
 
Zitat:

Delphi-Quellcode:
case random(4)of
  0: inc(JagdX,10);
  1: dec(JagdX,10);
  2: inc(JagdY,10);
  3: dec(JagdY,10);
end;

Statt jedes Mal eine andere Richtung zu nehmen, zum Großteil die Richtung belassen.

Da gibt es Millionen Varianten es zu lösen.
z.B. die neue Richtung jedesmal aus der Nähe zum Rand in Laufrichtung, der Richtung des Gegners/Spielers und zu kleinem Teil aus Zufall bestimmen, wobei die Wahrscheinlichkeit in Richtung des letzen Schrittes weiter zu laufen nur größer sein muß, als für die anderen Richtungen.
Also erstmal Wahrscheinlichkeiten für jede Richtung berechnen und dann darüber per Zufall die Richtung auswählen.

louisnws 5. Feb 2012 11:04

AW: Wiederholen einer aktion
 
Zitat:

Zitat von Coffeecoder (Beitrag 1149300)
Hast du da mal mit einer For-Schleife versucht?
Hier kannst du auch eine Case-Anweisung benutzen ;)

Delphi-Quellcode:
case random(4)of
  0: inc(JagdX,10);
  1: dec(JagdX,10);
  2: inc(JagdY,10);
  3: dec(JagdY,10);
end;


Wofür steht die Zahl "778"? Ich nehme die Breite des Forumlars? Schreib dies:
Delphi-Quellcode:
If
  (JagdX + 50 > form1.clientwidth) then dec(JagdX,20);
Wenn du magst, kannst du ja deinen gesamten Code anhängen, dann können wir das genauer ansehen.

Also Ich hab es mit einer for it schleife probiert die müsste dann lauten
Delphi-Quellcode:
for zufall:=0 to 0 do inc(jagdx,5)
oder? ich vesteh das mit dem x to x nicht richtig
Und das
Delphi-Quellcode:
If
  (JagdX + 50 > form1.clientwidth) then dec(JagdX,20);
hab ich grade ausprobiert geht aber nicht :(

hier mein kompletter quelltext
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Timer1: TTimer;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure Timer1Timer(Sender: TObject);



  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  MannX: Integer= 60;
  MannY: Integer= 60;
  JagdX: Integer;
  JagdY: Integer;
  Zufall: Integer;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  refresh;
  Button1.Visible := false;
  Timer1.Enabled := true;


end;




procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);

begin
if Key= Ord('W') then
begin
  dec(mannY,7);
  Refresh;
  Canvas.Rectangle(MannX,MannY,MannX + 50,MannY+50);
  Canvas.Rectangle(JagdX,JagdY,JagdX+50,JagdY+50);
end;

if Key= Ord('S') then
begin
  inc(MannY,7);
  Refresh;
  Canvas.Rectangle(MannX,MannY,MannX + 50,MannY+50);
  Canvas.Rectangle(JagdX,JagdY,JagdX+50,JagdY+50);
end;

if Key= Ord('A') then
begin
  Dec(MannX,7);
  Refresh;
  Canvas.Rectangle(MannX,MannY,MannX + 50,MannY+50);
  Canvas.Rectangle(JagdX,JagdY,JagdX+50,JagdY+50);
end;

if Key= Ord('D') then
begin
  //rechts
  inc(MannX,7);
  Refresh;
  Canvas.Rectangle(MannX,MannY,MannX + 50,MannY+50);
  Canvas.Rectangle(JagdX,JagdY,JagdX+50,JagdY+50);
end;

end;


procedure TForm1.Timer1Timer(Sender: TObject);
begin
  zufall:=random(4);
  if Zufall = 0 then inc(JagdX,10);
  if Zufall = 1 then dec(JagdX,10);
  if Zufall = 2 then inc(JagdY,10);
  if Zufall = 3 then dec(JagdY,10);
  refresh;
  Canvas.Brush.Color := clred;
  Canvas.Rectangle(MannX,MannY,MannX + 50,MannY+50);
  Canvas.Brush.Color := clyellow;
  Canvas.Rectangle(JagdX,JagdY,JagdX+50,JagdY+50);
  if (MannX + 50 > JagdX) and (MannX < JagdX + 50) and (MannY + 50 > JagdY) and
      (MannY < JagdY+50) then
  begin
    JagdX := Random(200) + 1;
    JagdY := Random(200) + 1;
    refresh;
    Canvas.Rectangle(JagdX, JagdY, JagdX + 50, JagdY + 50);
    Label1.Caption:= ('Congrantulations');
    Button1.Visible := true;
    Timer1.Enabled := false;
  end;
  If

  (JagdX + 50 > 780) then dec(JagdX,20);

  If

  (JagdX + 50 < 0) then inc(JagdX,20);

  if
  (JagdX < 5) then inc(JagdX,20);

  If
  (JagdY < 7) then inc(Jagdy,20);
end;
Zitat:

Da gibt es Millionen Varianten es zu lösen.
z.B. die neue Richtung jedesmal aus der Nähe zum Rand in Laufrichtung, der Richtung des Gegners/Spielers und zu kleinem Teil aus Zufall bestimmen, wobei die Wahrscheinlichkeit in Richtung des letzen Schrittes weiter zu laufen nur größer sein muß, als für die anderen Richtungen.
Also erstmal Wahrscheinlichkeiten für jede Richtung berechnen und dann darüber per Zufall die Richtung auswählen.
wie genau geht das? da müsste ich dann mehrere fälle reinknüpfen oder? also irgendwie grad in die gegenrichtung von der koordinate des anderen quadrates oder? Wie genau?

Coffeecoder 5. Feb 2012 18:15

AW: Wiederholen einer aktion
 
Zitat:

Zitat von louisnws (Beitrag 1149329)
wie genau geht das? da müsste ich dann mehrere fälle reinknüpfen oder? also irgendwie grad in die gegenrichtung von der koordinate des anderen quadrates oder? Wie genau?

Dieser Code setzt du in den FormKeyDown:
Delphi-Quellcode:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin

        if ((MannY >= 0) and (Key=Ord('W'))) then
        begin
                dec(mannY,7);
                Refresh;
                Canvas.Rectangle(MannX,MannY,MannX + 50,MannY+50);
                Canvas.Rectangle(JagdX,JagdY,JagdX+50,JagdY+50);
        end;


        if ((Key=Ord('S')) and (MannY+50 < form1.ClientHeight)) then
        begin
                inc(MannY,7);
                Refresh;
                Canvas.Rectangle(MannX,MannY,MannX + 50,MannY+50);
                Canvas.Rectangle(JagdX,JagdY,JagdX+50,JagdY+50);
        end;

        if ((Key=Ord('A')) and (MannX >= 0)) then
        begin
                Dec(MannX,7);
                Refresh;
                Canvas.Rectangle(MannX,MannY,MannX + 50,MannY+50);
                Canvas.Rectangle(JagdX,JagdY,JagdX+50,JagdY+50);
         end;

        if ((Key=Ord('D')) and (MannX+50 < form1.ClientWidth)) then
        begin
                inc(MannX,7);
                Refresh;
                Canvas.Rectangle(MannX,MannY,MannX + 50,MannY+50);
                Canvas.Rectangle(JagdX,JagdY,JagdX+50,JagdY+50);
        end;
end;
Damit wäre die Frage gegen die Mauer/Rände laufen geklärt ;)

Zitat:

Zitat von louisnws (Beitrag 1149329)
Also Ich hab es mit einer for it schleife probiert die müsste dann lauten
Delphi-Quellcode:
for zufall:=0 to 0 do inc(jagdx,5)
oder? ich vesteh das mit dem x to x nicht richtig
Und das
Delphi-Quellcode:
If
  (JagdX + 50 > form1.clientwidth) then dec(JagdX,20);
hab ich grade ausprobiert geht aber nicht :(

Für mich klingt das nach einem Verständnisproblem der For-Schleife oder der Schleifen allgemein. Ich empfehle dir die Schleifen genauer anzusehen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:59 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