Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Hilfe bei meinen Projekt (Mehrere Prozeduren gleichzeitig laufen lassen)) (https://www.delphipraxis.net/176962-hilfe-bei-meinen-projekt-mehrere-prozeduren-gleichzeitig-laufen-lassen.html)

Redak 7. Okt 2013 19:32

Hilfe bei meinen Projekt (Mehrere Prozeduren gleichzeitig laufen lassen))
 
Hi Leute,

Ich habe ein Problem beim meinen Projekt. Ich wollte ein Spiel programmieren mit folgender Idee. Rechts erscheint ein Bild z.B. von einen Ball dann links sollen Buchstaben von der Decke fallen und eine Figur soll die Buchstaben einsammeln, die das Wort "Ball" bilden. Jedoch scheitere ich schon daran, dass ich es nicht schaffe das wenn die Buchstaben fallen, dass ich gleichzeitig die Figur bewegen kann. Sprich wenn die Buchstaben sich bewegen, kann ich nicht die Figur bewegen. Ich bitte euch um Hilfe. Bitte versucht mir mit einfachen Worten es zu erklären. Danke schon mal in vorraus.

Hier mein Code.

Delphi-Quellcode:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Image1: TImage;
    SpeedButton1: TSpeedButton;
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure SpeedButton1Click(Sender: TObject);
    procedure Buchstaben();
    procedure Bewegen(x : integer; y : integer);
    procedure FormCreate(Sender: TObject);

  private
    { Private declarations }
    dynAr : array of string;
    forDisplay : array of string;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

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

case Key of

    VK_LEFT:
    begin
        Image1.Left := Image1.Left - 10;
        key:=0;
    end;

    VK_RIGHT:
    begin
        Image1.Left := Image1.Left + 10;
        key:=0;
    end;


end;
end;

procedure TForm1.Buchstaben();
var
    i:integer;
begin

    setlength(dynAr,26);
    setlength(forDisplay,6);

    dynAr[0]:='a';
    dynAr[1]:='b';
    dynAr[2]:='c';
    dynAr[3]:='d';
    dynAr[4]:='e';
    dynAr[5]:='f';
    dynAr[6]:='g';
    dynAr[7]:='h';
    dynAr[8]:='i';
    dynAr[9]:='j';
    dynAr[10]:='k';
    dynAr[11]:='l';
    dynAr[12]:='m';
    dynAr[13]:='n';
    dynAr[14]:='o';
    dynAr[15]:='p';
    dynAr[16]:='q';
    dynAr[17]:='r';
    dynAr[18]:='s';
    dynAr[19]:='t';
    dynAr[20]:='u';
    dynAr[21]:='v';
    dynAr[22]:='w';
    dynAr[23]:='x';
    dynAr[24]:='y';
    dynAr[25]:='z';


    forDisplay[0]:= dynAr[random(26)];
    forDisplay[1]:= dynAr[random(26)];
    forDisplay[2]:= dynAr[random(26)];
    forDisplay[3]:= dynAr[random(26)];
    forDisplay[4]:= dynAr[random(26)];
    forDisplay[5]:= dynAr[random(26)];


end;

procedure TForm1.Bewegen(x : integer; y : integer);
var
    i:integer;
begin

    for i := 1 to 1 do
    begin

        canvas.TextOut(100*i+x,-10+y,forDisplay[0]);
        canvas.TextOut(100+100*i+x,-10+y,forDisplay[1]);
        canvas.TextOut(200+100*i+x,-10+y,forDisplay[2]);
        canvas.TextOut(300+100*i+x,-10+y,forDisplay[3]);
        canvas.TextOut(400+100*i+x,-10+y,forDisplay[4]);
        canvas.TextOut(500+100*i+x,-10+y,forDisplay[5]);

    end;

end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
    i :integer;
begin

    Buchstaben();

    for i := 0 to 300 do
    begin
        sleep(10);
        Bewegen(0,i);
    end;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
    randomize;
end;

end.

Aviator 7. Okt 2013 20:28

AW: Hilfe bei meinen Projekt (Mehrere Prozeduren gleichzeitig laufen lassen))
 
Ich würde mal das Stichwort Threads in den Raum werfen. Allerdings ohne Gewähr :roll:

himitsu 7. Okt 2013 20:41

AW: Hilfe bei meinen Projekt (Mehrere Prozeduren gleichzeitig laufen lassen))
 
Gerade Threads sind hier nicht angebracht.

Die VCL ist nicht threadsicher, daß heißt man müßte alle Zugriffe sowieso wieder synchronisieren.


Statt der Schleife mehrere einen Timer verwenden.

- i ordentlich benennen
- i als globale Variable in die Form
und dann im Timer
- i um 1 hochzählen
- die Bewegen-Funktion je einmal aufrufen

Redak 7. Okt 2013 20:45

AW: Hilfe bei meinen Projekt (Mehrere Prozeduren gleichzeitig laufen lassen))
 
Ok danke für die schnellen Antworten, jedoch habe ich keine Vorstellung wie ich das jetzt umsetzen soll.

Der schöne Günther 7. Okt 2013 20:51

AW: Hilfe bei meinen Projekt (Mehrere Prozeduren gleichzeitig laufen lassen))
 
Hast du denn überhaupt mal etwas mit einem Timer gemacht bzw. verstanden was das Ding tut?

donyfreaky 7. Okt 2013 21:04

AW: Hilfe bei meinen Projekt (Mehrere Prozeduren gleichzeitig laufen lassen))
 
Hallo Redak,
Es gibt die Möglichkeit über TThreadYield bzw. TThread (http://docwiki.embarcadero.com/CodeE...Yield_(Delphi)) gleichzeitig Dinge zu erledigen aber all zu sinnvoll ist das in deinem Fall nicht. Der Schlüssel hier ist das Timing. Anstatt deinen Routinen feste Positionen zu liefern, könntest du ihnen einen Timecode liefern mit dessen dann die Position innerhalb der Routine ermittelt wird.

Hier mal ein bisschen Code um das zu veranschaulichen.

Das füllen etwas kürzer...
Delphi-Quellcode:
procedure TForm1.Buchstaben();
var
    i:integer;
begin
    setlength(dynAr,26);
    setlength(forDisplay,6);

    // buchstaben füllen
    for i := 0 to 26 do
        dynAr[i]:= Chr(97+i);
   
    // buchstaben für anzeige
    for i := 0 to 5 do
       forDisplay[i]:= dynAr[random(26)];
end;
Textausgabe mit Timecode...
Delphi-Quellcode:
point1 : TPoint; //Startposition des Textes

...

point1.X := 100;
point1.Y := -10;

...

procedure TForm1.Bewegen(const timecode, anim_delay: Cardinal);
var
    i: Integer;
    txt_pos: TPoint;
const
  add = Point(0, 100); // Wo soll der Text am Ende sein?
  offset = Point(100, 0); // Buchstabenabstand
begin
    txt_pos.X := Round(((timecode / anim_delay) * add.X) + point1.X);
    txt_pos.Y := Round(((timecode / anim_delay) * add.Y) + point1.Y);
    for i := 0 to High(TextOut)-1 do
        canvas.TextOut(txt_pos.X + (i*offset.X), txt_pos.y + (i*offset.Y), forDisplay[i]);
end;
Jetzt noch das Timing und ausführen der Animationen
Delphi-Quellcode:
procedure TForm1.Animate;
var
    TickCount, TickCountStart, TickCountEnd, timecode: Cardinal;
const
    anim_delay = 5000; // Wie lange soll es dauern?
begin
    TickCountStart := GetTickCount;
    TickCountEnd := TickCountStart + anim_delay;
    repeat
        TickCount := GetTickCount;
        timecode := TickCount - TickCountStart;
        // Deine Animationen
        Bewegen(timecode, anim_delay);
    until (TickCountEnd <= TickCount);
end;
Der Code ist ungetestet sollte aber hoffentlich so funktionieren. Falls du planst, später noch mehrere Animationen zu benutzen würde sich eine abstrakte Klasse TAnimation empfehlen, um das ganze Timing etwas eleganter zu gestalten. Prinzipiell kann ich dir aber auch Andora2D ans Herz legen, da es bereits alle benötigten Klassen für Animationen etc. mitbringt.

stahli 7. Okt 2013 21:14

AW: Hilfe bei meinen Projekt (Mehrere Prozeduren gleichzeitig laufen lassen))
 
Ich denke, Delphi ist für solche Zwecke nicht die optimale Lösung.

Man kann das zwar irgendwie hinfummeln, aber eher mit Notlösungen.
Die VCL ist für Anwendungsentwicklungen vorgesehen und arbeitet in einem entsprechenden Rahmen.

Ich weiß nicht, ob es einfache Spieleengines gibt, die man dafür verwenden kann.
Es gab wohl auch mal ein Buch "Spieleentwicklung mit Delphi3" (oder so), aber inhaltlich kann ich da nix sagen.
Das setze sicher auf ein grafisches Framework.

Mit Delphi und der VCL lauern bei der Problemstellung einige Tücken.

Redak 7. Okt 2013 21:16

AW: Hilfe bei meinen Projekt (Mehrere Prozeduren gleichzeitig laufen lassen))
 
Also ich haben noch nie mit einen Timer gearbeitet und weiß auch nicht so genau wie es funktioniert.

Wirklich ein danke an donyfreaky, dass du dir so viel mühe gemacht hast. Jedoch ist es doch ein wenig komplizierter als ich gedacht habe. Dennoch versuche ich es in meinen Projekt anzuwenden

DeddyH 8. Okt 2013 07:10

AW: Hilfe bei meinen Projekt (Mehrere Prozeduren gleichzeitig laufen lassen))
 
Zitat:

Zitat von stahli (Beitrag 1231095)
Ich weiß nicht, ob es einfache Spieleengines gibt, die man dafür verwenden kann.

Nur ein Beispiel: http://www.delphipraxis.net/81314-an...-12-08%5D.html, es gibt noch etliche mehr, sowohl OpenSource wie auch kommerziell. Inwieweit man damit klarkommt, muss aber jeder für sich selbst herausfinden.

Perlsau 8. Okt 2013 07:22

AW: Hilfe bei meinen Projekt (Mehrere Prozeduren gleichzeitig laufen lassen))
 
Zitat:

Zitat von Redak (Beitrag 1231096)
Also ich haben noch nie mit einen Timer gearbeitet und weiß auch nicht so genau wie es funktioniert.

Die Verwendung eines Timers ist eigentlich recht einfach:

1. Wirf eine TTimer-Komponente auf dein Formular und nenne sie z.B. MeinTimer.
2. Stelle im Propery Interval ein, in welchen Zeitabständen (Millisekunden) dein Timer auslösen (triggern) soll.
3. Setze das Property Enabled im Objektinspektor auf False.
4. Wähle im Objektinspektor den Reiter Ereignisse und doppelklicke in das Property OnTimer (das einzige Property), so daß ein Procdure-Rumpf entsteht.
5. Dort hinein schreibst du nun, was geschehen soll, wenn die Eregnisbehandlung deines Timers ausgelöst wird:
Delphi-Quellcode:
procedure TFormMain.MeinTimerTimer(Sender: TObject);
begin
  TueIrgendWas;
end;
5. Setze Enabled auf True, wenn der Timer arbeiten soll:
Delphi-Quellcode:
procedure TFormMain.Button1Click(Sender: TObject);
begin
  MeinTimer.Enabled := True;
end;
Nun wird einmal pro Sekunde die Methode TueIrgendWas aufgerufen:
Delphi-Quellcode:
procedure TFormMain.TueIrgendWas;
begin
  MachIrgendwas;
end;


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