Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Lazarus (IDE) (https://www.delphipraxis.net/81-lazarus-ide/)
-   -   Ressourcen pro Sekunde generieren (https://www.delphipraxis.net/191554-ressourcen-pro-sekunde-generieren.html)

heel213 27. Jan 2017 10:42

Ressourcen pro Sekunde generieren
 
Ja moin, hier ist wieder euer Heel.
Und zwar will ich für das "Spiel", welches ich im Rahmen unseres Schulprojekts zusammenbasteln will eine Funktion einbauen, welche Ressourcen/s generiert, bisher habe ich mir das so vorgestellt:
Code:
repeat
      begin
      timer1.enabled:=true;
      Luxusgueter:=Luxusgueter+Luxusgueterproduktion;
      Stein:=Stein+Steinproduktion;
      Nahrung:=Nahrung+Nahrungproduktion;
      Gold:=Gold+Goldproduktion;
      label13.caption:=floattostrf(Stein,fffixed,10,0);
      label14.caption:=floattostrf(luxusgueter,fffixed,10,0);
      label15.caption:=floattostrf(Nahrung,fffixed,10,0);
      label16.caption:=floattostrf(gold,fffixed,10,0);
      label17.caption:=inttostr(einwohner);
      i:=i+1;
      end;
  until i=100000000;
Allerdings musste ich feststellen, dass es erst die Funktion bis zum Ende durchläuft und man dann erst weiterspielen kann.
Die Funktion soll im Optimalfall natürlich nebenher weiterlaufen und den Ressourcenstand immer updaten.
Den ganzen Quelltext findet ihr unten.
Vielen Dank schonmal für die Hilfe,
mit heelischen Grüßen, euer heel213







Code:
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Image1: TImage;
    Label1: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    Label13: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    Label17: TLabel;
    Label18: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    ScrollBar1: TScrollBar;
    ScrollBar2: TScrollBar;
    ScrollBar3: TScrollBar;
    ScrollBar4: TScrollBar;
    ScrollBar5: TScrollBar;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ScrollBar1Change(Sender: TObject);

    procedure ScrollBar2Change(Sender: TObject);

    procedure ScrollBar3Change(Sender: TObject);

    procedure ScrollBar4Change(Sender: TObject);

    procedure ScrollBar5Change(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);

  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;
  timer1: ttimer;
  Einwohner : UInt64;
  Zusammenrechnung, i: Integer;
  Stein,Nahrung,Luxusgueter,Gold,Goldproduktion, Nahrungproduktion, Steinproduktion, Holzproduktion, Luxusgueterproduktion : real;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.ScrollBar1Change(Sender: TObject);
begin
   Label8.caption:=inttostr(Scrollbar1.position);
end;

procedure TForm1.ScrollBar2Change(Sender: TObject);
begin
    Label9.caption:=inttostr(scrollbar2.position);
end;

procedure TForm1.ScrollBar3Change(Sender: TObject);
begin
   label10.caption:=inttostr(scrollbar3.position);
end;


procedure TForm1.ScrollBar4Change(Sender: TObject);
begin
   label11.caption:=inttostr(scrollbar4.position);
end;

procedure TForm1.ScrollBar5Change(Sender: TObject);
begin
    label12.caption:=inttostr(scrollbar5.position);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
   timer1.Interval:=1000;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Zusammenrechnung:=Scrollbar1.position+Scrollbar2.position+Scrollbar3.position+
  scrollbar4.position+scrollbar5.position;
   If Zusammenrechnung=100 then
  begin
    label6.Visible:=false;
    label7.visible:=false;
    Goldproduktion:=(scrollbar1.position/100)*Einwohner;
    Nahrungproduktion:=(scrollbar2.position/100)*Einwohner;
    Steinproduktion:=(scrollbar3.position/100)*Einwohner;
    Holzproduktion:=(scrollbar4.position/100)*Einwohner;
    Luxusgueterproduktion:=(scrollbar5.position/100)*Einwohner;
  end
  else
  begin
    if Zusammenrechnung<100 then
    begin
      label7.visible:=true;
      label6.visible:=false;
      end
    else
    begin
      label6.visible:=true;
      label7.visible:=false;
      end;
end;
  label18.caption:='Momentane Produktion: Stein='+floattostr(Steinproduktion)+'/s Luxusgüter='+floattostr(Luxusgueterproduktion)+'/s Nahrung='+floattostr(Nahrungproduktion)+'/s Gold='+floattostr(Goldproduktion)+'/s';
  repeat
      begin
      timer1.enabled:=true;
      Luxusgueter:=Luxusgueter+Luxusgueterproduktion;
      Stein:=Stein+Steinproduktion;
      Nahrung:=Nahrung+Nahrungproduktion;
      Gold:=Gold+Goldproduktion;
      label13.caption:=floattostrf(Stein,fffixed,10,0);
      label14.caption:=floattostrf(luxusgueter,fffixed,10,0);
      label15.caption:=floattostrf(Nahrung,fffixed,10,0);
      label16.caption:=floattostrf(gold,fffixed,10,0);
      label17.caption:=inttostr(einwohner);
      i:=i+1;
      end;
  until i=100000000;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  i:=1;
  label6.visible:=false;
  label7.visible:=false;
  Einwohner:=5000;
  end;
end.

end.

a.def 27. Jan 2017 10:44

AW: Ressourcen pro Sekunde generieren
 
1. Wieso aktivierst du in jedem Schleifendurchgang den Timer neu?
Der Timer hat nicht mal eine Aufgabe zu erledigen. Warum also dann der Timer?
Außerdem hast du die Variable "Timer1" doppelt deklariert. Genau derselbe Fehler wie all deine Schulkollegen.

2. Setze ein
Delphi-Quellcode:
Application.ProcessMessages;
in die Schleife und dein Problem ist gelöst.
Aber das kann schon eine Weile dauern und "nebenher" ist relativ. Das wird dein Programm in der Bedienung wahrscheinlich schon irgendwie blockieren.

heel213 27. Jan 2017 10:49

AW: Ressourcen pro Sekunde generieren
 
Ich dachte, wenn ich den Timer aktiviere läuft er die Sekunde durch und dann wird der rest erledigt?
Wie kann ich den denn anders benutzen in der Schleife?
Und wofür genau ist Application.ProcessMessages; bzw. wie benutze ich den Befehl?

a.def 27. Jan 2017 10:52

AW: Ressourcen pro Sekunde generieren
 
Nein ein Timer macht was vollkommen anderes als das was du willst.
Was du meinst ist
Delphi-Quellcode:
Sleep(1000);
Aber wenn du
Delphi-Quellcode:
Sleep(1000);
machst... guck dir mal an wieviele Schleifendurchgänge du hast. Das würde 3 Jahre dauern.

SProske 27. Jan 2017 10:56

AW: Ressourcen pro Sekunde generieren
 
Müsste nicht das Hochsetzen der Produktion in die onTimer-Methode rein und der Timer einfach nur gestartet werden? Oder verstehe ich das völlig falsch?

a.def 27. Jan 2017 10:57

AW: Ressourcen pro Sekunde generieren
 
So sehe ich das auch. Das muss in den Timer, welcher im OnCreate (oder woanders...) gestartet wird.
Sonst blockierst du dir den Button.

Valle 27. Jan 2017 10:58

AW: Ressourcen pro Sekunde generieren
 
Ich würde dir, unabhängig von deinem Problem, übrigens empfehlen dich nicht auf die Zeit des Timers zu verlassen. Rechne stattdessen lieber selbst aus, wie viel Zeit seit der letzten Messung vergangen ist und berechne daran den Resourcengewinn. Sonst wird es längerfristig zu starken Abweichungen kommen.

Klaus01 27. Jan 2017 10:59

AW: Ressourcen pro Sekunde generieren
 
... wieso berechnest Du nicht erst die Werte und gibst sie dann aus?

Delphi-Quellcode:
  repeat
      begin
      Luxusgueter:=Luxusgueter+Luxusgueterproduktion;
      Stein:=Stein+Steinproduktion;
      Nahrung:=Nahrung+Nahrungproduktion;
      Gold:=Gold+Goldproduktion;
      label13.caption:=floattostrf(Stein,fffixed,10,0);
      label14.caption:=floattostrf(luxusgueter,fffixed,10,0);
      label15.caption:=floattostrf(Nahrung,fffixed,10,0);
      label16.caption:=floattostrf(gold,fffixed,10,0);
      label17.caption:=inttostr(einwohner);
      i:=i+1;
      end;
  until i=100000000;
Das kann doch keiner am Bildschirmverfolgen..

Delphi-Quellcode:
  repeat
    begin
      Luxusgueter:=Luxusgueter+Luxusgueterproduktion;
      Stein:=Stein+Steinproduktion;
      Nahrung:=Nahrung+Nahrungproduktion;
      Gold:=Gold+Goldproduktion;
      i := i+1;
    end;
  until i = 100000000;
  label13.caption:=floattostrf(Stein,fffixed,10,0);
  label14.caption:=floattostrf(luxusgueter,fffixed,10,0);
  label15.caption:=floattostrf(Nahrung,fffixed,10,0);
  label16.caption:=floattostrf(gold,fffixed,10,0);
  label17.caption:=inttostr(einwohner);
und eigentlich könnte man das dann auch ohne Schleife bereichnen.

Grüße
Klaus

heel213 27. Jan 2017 11:00

AW: Ressourcen pro Sekunde generieren
 
Vielen Dank, Sleep war der Befehl den ich gebraucht habe, jetzt funktioniert es auch, wie ich es wollte.
Die Funktion soll ja auch möglichst unendlich lange gehen, damit immer nebenbei die Ressourcen generiert werden,

a.def 27. Jan 2017 11:00

AW: Ressourcen pro Sekunde generieren
 
Zitat:

Zitat von Valle (Beitrag 1360154)
Ich würde dir, unabhängig von deinem Problem, übrigens empfehlen dich nicht auf die Zeit des Timers zu verlassen. Rechne stattdessen lieber selbst aus, wie viel Zeit seit der letzten Messung vergangen ist und berechne daran den Resourcengewinn. Sonst wird es längerfristig zu starken Abweichungen kommen.

Sag mal einem Sachbearbeiter der soll ein Haus bauen. Ungefähr so fühlt sich der Themenersteller jetzt :P

Zitat:

Die Funktion soll ja auch möglichst unendlich lange gehen, damit immer nebenbei die Ressourcen generiert werden,
Pack das trotzdem in den Timer sonst macht das alles gar keinen Sinn.

markus5766h 27. Jan 2017 12:53

AW: Ressourcen pro Sekunde generieren
 
Moin.

Soll das so etwas wie Zivilisation werden ?

Wenn ja, wird eine Schleife nicht benötigt :
Zivilisation ist ein Runden-basiertes Spiel, d.h. Ressourcen werden je Runde aktualisiert,
nachdem alle Spieler (oder auch Engines) ihre Aktionen durchgeführt haben - die Resourcenänderung ist ja von
den Aktionen der Spieler abhängig . . .

Neutral General 27. Jan 2017 13:27

AW: Ressourcen pro Sekunde generieren
 
Okay Timer kurz erklärt:

Du willst ein Stück Code regelmäßig ausführen?

1) Zieh dir einen Timer aufs Formular (Name "Timer1" als Beispiel)
2) Setze die Eigenschaft "Interval" auf das Zeitinterval in Millisekunden in dem du deinen Code ausgeführt haben willst. (1000 = 1x pro Sekunde)
3) Wechsel auf das "Ereignisse" Tabsheet des Timers im Objektinpektor und klicke doppelt auf die leere Fläche rechts von "OnTimer".
4)

Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  // Hier kommt der Code hin der jede Sekunde ausgeführt werden soll
end;
In deinem Fall also so:
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Luxusgueter:=Luxusgueter+Luxusgueterproduktion;
  Stein:=Stein+Steinproduktion;
  Nahrung:=Nahrung+Nahrungproduktion;
  Gold:=Gold+Goldproduktion;
  label13.caption:=floattostrf(Stein,fffixed,10,0);
  label14.caption:=floattostrf(luxusgueter,fffixed,10,0);
  label15.caption:=floattostrf(Nahrung,fffixed,10,0);
  label16.caption:=floattostrf(gold,fffixed,10,0);
  label17.caption:=inttostr(einwohner);
end;
5) Ein Timer ist standardmäßig angeschaltet, würde also sobald du das Formular bzw. die Anwendung öffnest anfangen den Code auszuführen.
Wenn du das nicht willst stell die Eigenschaft "Enabled" im Objektinspektor erst mal auf false und um den Timer zu aktivieren setzt du dann einfach irgendwo
im Quelltext (also da wo du ihn an/aus schalten willst) Timer1.Enabled := true (oder auch wieder auf false, falls du die Rohstoffproduktion wieder abschalten willst).

HINWEIS: Mach es NICHT mit dieser Schleife und Application.ProcessMessages! Das ist auf unendlich viele Arten schlecht und falsch!

himitsu 27. Jan 2017 20:23

AW: Ressourcen pro Sekunde generieren
 
Und nochmal kurz zu dem Problem mit den ungenauen Timern.
Die Timer sind nicht ganz genau, je kürzer das Interrval ist.
Und wenn dein Programm oder der PC etwas "hängt" (ausgelastet ist), dann bleibt der Timer quasi kurz stehen.

Stichwort: Interpolation

Da ist es dann egal, ob der Timer alle 0.5 , 1 oder 55 Sekunden auslöst.

* einfach den Zeitpunkt des Starts, bzw. des letzten Updates merken
* ausrechnen wieviel Zeit seitdem vergangen ist, in Sekunden
* und das mit dem WertProSekunde multipliziert dazuaddieren

heel213 24. Feb 2017 23:59

AW: Ressourcen pro Sekunde generieren
 
Zitat:

Zitat von Neutral General (Beitrag 1360174)
Okay Timer kurz erklärt:

Du willst ein Stück Code regelmäßig ausführen?

1) Zieh dir einen Timer aufs Formular (Name "Timer1" als Beispiel)
2) Setze die Eigenschaft "Interval" auf das Zeitinterval in Millisekunden in dem du deinen Code ausgeführt haben willst. (1000 = 1x pro Sekunde)
3) Wechsel auf das "Ereignisse" Tabsheet des Timers im Objektinpektor und klicke doppelt auf die leere Fläche rechts von "OnTimer".
4)

Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  // Hier kommt der Code hin der jede Sekunde ausgeführt werden soll
end;
In deinem Fall also so:
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Luxusgueter:=Luxusgueter+Luxusgueterproduktion;
  Stein:=Stein+Steinproduktion;
  Nahrung:=Nahrung+Nahrungproduktion;
  Gold:=Gold+Goldproduktion;
  label13.caption:=floattostrf(Stein,fffixed,10,0);
  label14.caption:=floattostrf(luxusgueter,fffixed,10,0);
  label15.caption:=floattostrf(Nahrung,fffixed,10,0);
  label16.caption:=floattostrf(gold,fffixed,10,0);
  label17.caption:=inttostr(einwohner);
end;
5) Ein Timer ist standardmäßig angeschaltet, würde also sobald du das Formular bzw. die Anwendung öffnest anfangen den Code auszuführen.
Wenn du das nicht willst stell die Eigenschaft "Enabled" im Objektinspektor erst mal auf false und um den Timer zu aktivieren setzt du dann einfach irgendwo
im Quelltext (also da wo du ihn an/aus schalten willst) Timer1.Enabled := true (oder auch wieder auf false, falls du die Rohstoffproduktion wieder abschalten willst).

HINWEIS: Mach es NICHT mit dieser Schleife und Application.ProcessMessages! Das ist auf unendlich viele Arten schlecht und falsch!

Vielen vielen Dank, das war genau das, was ich brauchte! :D

t.roller 25. Feb 2017 05:55

AW: Ressourcen pro Sekunde generieren
 
Zitat:

Zitat von heel213 (Beitrag 1360145)
Ja moin, hier ist wieder euer Heel.
Und zwar will ich für das "Spiel", welches ich im Rahmen unseres Schulprojekts zusammenbasteln will eine Funktion einbauen, welche Ressourcen/s generiert, bisher habe ich mir das so vorgestellt:
Code:
Gaaanz laaanges Prograaamm

Ein ZIP-File im Anhang wäre sinnvoll, um das ganze Timing im Spiel zu erfassen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:40 Uhr.

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