Entwickler-Ecke

Sonstiges (Delphi) - Zeit sichtbar verstreichen lassen


*Jenny* - So 03.01.10 13:48
Titel: Zeit sichtbar verstreichen lassen
Hallo Leute!

Ich bin hier neu und wollte euch mal um Hilfe bitten! Wir müssen in Informatik ein Spiel programmieren und dabei ein paar Vorgaben beachten. Leider habe ich das Blatt erst jetzt bekommen und muss nun mein Spiel noch umwandeln.
Ich hatte ein Pong Spiel gewählt jedoch steht in den Angaben es muss etwas eingesammelt werden in einer bestimmten Zeit......ich bin noch am überlegen wie ich mein spiel noch umgestalten kann damit ich nicht alles umsonst gemacht habe.

Jedenfalls müssen wir eine Zeit verstreichen lassen in der etwas eingesammelt wird und ich wollte euch fragen wie ich dies erfüllen kann und diese sichtbar anzeigen und jetzt brauch ich euch =) Vllt habt ihr ja auch eine Idee zu meinem Problem das Pong spiel so zu programmieren das zusätzlich irgendwas eingessammelt werden muss...

Danke im Voraus

Ganz liebe Grüße

Jenny


jaenicke - So 03.01.10 13:53

Hallo und :welcome: hier im Forum!

Unter dem Stichwort Countdown z.B. findest du bestimmt auch einiges über die Suche.

Was du machen kannst:


Hidden - So 03.01.10 13:59

Hi, und :welcome: im Delphi-Forum!

Was hast du denn bisher geschrieben? Ich nehme mal an der Pong-Ball ist ein Objekt mit Radius, Geschwindigkeit/Tempo, x- und y-Position, und er bewegt sich über einen Tisch, der mehrere Wände hat?

Wie hast du denn die Bewegung des Balls bisher gelöst, die muss ja auch zeitgesteuert sein :?:

Prallt der Ball an den Wänden ab? Dann hast du ja wahrscheinlich schon eine Kollisionsabfrage und brauchst nun eine Zweite für irgendwelche Gegenstände, die der Ball streifen könnte. Am einfachsten wären wohl Upgrades/etc(die den Ball schneller/langsamer machen oder Punkte geben könnten), die eingesammelt werden wenn der Ball sie streift. Die machst du dann ähnlich wie den Ball und entfernst sie, wenn ihre Position innerhalb des Ballkreises liegt.

Zeit sichtbar verstreichen lassen? Kein Problem, erhöhe einfach jedes Mal, wenn der Ball sich bewegt eine Variable um eins und male unten entsprechend viele Kreise oder so hin.

mfG,


*Jenny* - So 03.01.10 14:33

Danke erstmal für die hilfreichen Antworten ich werde mal versuchen auf die Fragen einzugehen, muss allerdings dazu sagen das ich Delphi erst seit 3 Monaten haben aber ich werds versuchen.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Label1: TLabel;
    Timer1: TTimer;
    Button1: TButton;
    Spieler: TPanel;
    Ball: TPanel;
    CPU: TPanel;
    stand: TLabel;
    Label2: TLabel;
    Edit1: TEdit;
    Edit2: TEdit;
    Label4: TLabel;
    Label5: TLabel;
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Edit1KeyPress(Sender: TObject; var Key: Char);
    procedure Edit2KeyPress(Sender: TObject; var Key: Char);
  private
    { Private-Deklarationen }
    //procedure AppMessage(var Msg: TMsg; var Handled: Boolean);
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  var CPU_top,Spieler_top : integer;
  var ball_top,ball_left, ball_x, ball_y : integer;
  var limit_oben,limit_unten,limit_links,limit_rechts : integer;
  var geschwindigkeit, differenz, schwierigkeit : integer;
  var b, bMehrspieler : boolean;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
    b:=false;
    if not (checkbox1.Checked=true) then b:=true; //wer fängt an? false=CPU, true=Spieler
    if checkbox2.Checked=true then bMehrspieler:=true;
    if checkbox2.Checked=false then bMehrspieler:=false;
    geschwindigkeit:=StrToInt(edit1.text);
    ball_x:=StrToInt(edit1.text);
    ball_y:=StrToInt(edit1.text);                       //geschwindigkeit etc. festlegen, start!
    Stand.Caption:='0:0';
    sleep(500);
    Timer1.Enabled:=true;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
//ball top
  if ball_top < 8 then
  begin
    ball_top:=8;
    ball_y:= - ball_y;
  end;
  if ball_top > 568 then
  begin
    ball_top:=568;
    ball_y:= - ball_y;
  end;
  ball_top:=ball_top + ball_y;
  ball.Top:=ball_top;
//ball left
  if ((ball_left < 49and (ball_top>CPU_top-1and (ball_top<CPU_top+153)) then
  begin
    geschwindigkeit:=geschwindigkeit+1;     //
    ball_y:=ball_y+1;                       //    ball/schläger schneller werden lassen (KI ruckelt)
    ball_x:=ball_x+1;                       //
    b:=true;        //ball wechselt richtung
  end;
  if (ball_left > 975and (ball_top>Spieler_top-1and (ball_top<Spieler_top+153then
  begin
    geschwindigkeit:=geschwindigkeit+1;     //
    ball_y:=ball_y+1;                       //    ball/schläger schneller werden lassen
    ball_x:=ball_x+1;                       //
    b:=false;       //ball wechselt richtung
  end;
//nicht abgeprallt
  if (ball_left>1020or (ball_left<4then
  begin
    if ball_left > 1020 then stand.caption:=IntToStr(StrToInt(copy(stand.Caption, 0, pos(':', stand.Caption)-1)) + 1) + copy(stand.Caption, pos(':', stand.Caption), MaxInt);
    if ball_left < 4 then stand.caption:=copy(stand.Caption, 0, pos(':', stand.Caption)) + IntToStr(StrToInt(copy(stand.Caption, pos(':', stand.Caption)+1, MaxInt)) + 1);
    ball.top:=240;
    ball.Left:=512;                       //
    CPU.Top:=200;                         //                   nächstes spiel: punktestand ändern, alles auf anfang
    Spieler.Top:=200;                     //
    CPU_top:=200;
    Spieler_Top:=200;
    ball_top:=240;
    ball_left:=512;
    geschwindigkeit:=StrToInt(edit1.text);
    ball_x:=StrToInt(edit1.text);
    ball_y:=StrToInt(edit1.text);
    differenz:=0;
    b:=false; //wer fängt an? false=CPU, true=Spieler
    if not (checkbox1.Checked=true) then b:=true; //wer fängt an? false=CPU, true=Spieler
    timer1.Enabled:=false;
    if (copy(stand.Caption, pos(':', stand.Caption)+1, MaxInt)=edit2.text) then   //wenn jmd edit2.text punkte erreicht hat, ende
    begin
      showmessage('Spiel zuende du hast gewonnen');
      exit;
      end;
    if (copy(stand.Caption, 0, pos(':', stand.Caption)-1)=edit2.text) then
    begin
      showmessage('Spiel zuende du hast verloren');
      exit;

    end;
    sleep(500);
    timer1.Enabled:=true;
    exit;
  end;
  if b=false then ball_left:=ball_left - ball_x;        //     in welche richtung soll der ball?
  if b=true then ball_left:=ball_left + ball_x;         //
  ball.left:=ball_left;
//CPU
  if bMehrspieler=false then
  begin
    if(ball_left < 350then // hier kann man den schwierigkeitsgrad der KI einstelllen kleiner=leichter(weniger zeit zu reagieren) größer=schwerer(mehr zeit zu reagieren) --> 512(mitte)=unschlagbar
    begin
      differenz := CPU_top+76 - ball_top;
      if(differenz < 0then CPU_top := CPU_top + geschwindigkeit else CPU_top := CPU_top - geschwindigkeit;
      if (CPU_top < 8then CPU_top := 8;
      if (CPU_top > 440then CPU_top := 440;
      CPU.Top := CPU_top;
    end;
  end;
//Steuerung mit den Pfeiltasten
  if GetAsyncKeystate(VK_UP) < 0 then
  begin
    Spieler_top := Spieler_top - geschwindigkeit;          //
    if (Spieler_top < 8then Spieler_top := 8;            //
    if (Spieler_top > 440then Spieler_top := 440;        // Schläger nach oben
    Spieler.Top := Spieler_top;                            //
  end;
  if GetAsyncKeystate(VK_DOWN) < 0 then
  begin
    Spieler_top := Spieler_top + geschwindigkeit;          //
    if (Spieler_top < 8then Spieler_top := 8;            //
    if (Spieler_top > 440then Spieler_top := 440;        // Schläger nach unten
    Spieler.Top := Spieler_top;                            //
  end;
// 2ter Spieler (Optional: bMehrspieler=true)
  if bMehrspieler=true then
  begin
    if GetAsyncKeystate(VK_CAPITAL) < 0 then
    begin
      CPU_top := CPU_top - geschwindigkeit;          //
      if (CPU_top < 8then CPU_top := 8;            //
      if (CPU_top > 440then CPU_top := 440;        // Schläger nach oben
      CPU.Top := CPU_top;                            //
    end;
    if GetAsyncKeystate(VK_SHIFT) < 0 then
    begin
      CPU_top := CPU_top + geschwindigkeit;          //
      if (CPU_top < 8then CPU_top := 8;            //
      if (CPU_top > 440then CPU_top := 440;        // Schläger nach unten
      CPU.Top := CPU_top;                            //
    end;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  randomize;
  b:=false; //wer fängt an? false=CPU, true=Spieler
  DoubleBuffered := true;
  CPU_top:=200;
  Spieler_Top:=200;
  ball_top:=240;                         //startzustände etc.
  ball_left:=512;
  ball_x:=5;
  ball_y:=5;
  geschwindigkeit:=5;
  differenz:=0;
end;




procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if not (key in [#48..#57#8#44#13#46]) then key := #0;
end;

procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char);
begin
  if not (key in [#48..#57#8#44#13#46]) then key := #0;
end;

end.

Das ist jetzt das ganz normale pong welches ich mal programmiert habe....hatte mir schon bereits gute vorschläge von euch zum Thema Pong durchgelesen und muss sagen es war sehr hilfreich =)
Vllt hilft der Quelltext....

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


DelphiProgrammer97 - So 03.01.10 15:28

mit der zeit die runterlauft das könntest du machen indem du

1. in die var eine variable reinschreibst:

zeit1 : Integer;

2.dann nimmst du dir noch einen timer und 2 Labels

3. den timer stellst du bei Enabled auf False, damit er nicht gleich zu beginn läuft

4. In das eine Label screibst du hinein "Zeit übrig:" oder so, das andere lässt du frei(also Label2)

5. dann schreibst du in den button, mit dem das spiel startet hinein:

Timer1.Enabled:=True;(also das der timer mit klick auf den button startet)


zeit1:=0

6. in die procedur im timer1 schreibst du dann:

zeit1:=zeit1+1;

Label2.Caption:=IntToStr (zeit1);


so müsste das funktionieren mit zeit runterzählen


jaenicke - So 03.01.10 15:32

  1. user profile icon*Jenny* hat folgendes geschrieben Zum zitierten Posting springen:

    Delphi-Quelltext
    1:
    2:
        b:=false; //wer fängt an? false=CPU, true=Spieler
        if not (checkbox1.Checked=true) then b:=true; //wer fängt an? false=CPU, true=Spieler
    Vergleiche mit true im if, also sowas wie "if x = true then" können ganz böse [http://www.delphi-forum.de/viewtopic.php?p=548760#548760] ins Auge [http://www.delphi-treff.de/tutorials/objectpascal/programmierung-mit-boolean-werten/page/4/] gehen...
    Zudem ist das hier unnötig:

    Delphi-Quelltext
    1:
        b := not CheckBox1.Checked;                    

  2. Globale Variablen sind auch keine gute Idee, insbesondere, wenn du später einmal mehrere Instanzen von Formularen verwendest. Zudem verdirbt es jegliche Übersicht.
  3. Um das richtig umzusetzen kannst du GetTickCount benutzen, das ist die Zeit seit Systemstart in Millisekunden:

    Delphi-Quelltext
    1:
    2:
    3:
    4:
    5:
    6:
    7:
    8:
    9:
    10:
    type
      TForm1 = class(TForm)
      private
        FStartTime: Cardinal;

    // beim Start:
      FStartTime := GetTickCount();

    // zur Anzeige:
      LabelX.Caption := IntToStr((GetTickCount() - FStartTime) div 1000) + ' Sekunden';


user profile iconDelphiProgrammer97 hat folgendes geschrieben Zum zitierten Posting springen:
so müsste das funktionieren mit zeit runterzählen
Wenn es nicht um Genauigkeit geht, sondern nur um irgendein Zählen als visueller Gag, dann geht das so, ja... ;-)


*Jenny* - So 03.01.10 15:45

Okay danke für die infos! ich werd es mal versuchen :D Eine frage Hidden hat mich gefragt: Prallt der Ball an den Wänden ab? Dann hast du ja wahrscheinlich schon eine Kollisionsabfrage und brauchst nun eine Zweite für irgendwelche Gegenstände, die der Ball streifen könnte. Am einfachsten wären wohl Upgrades/etc(die den Ball schneller/langsamer machen oder Punkte geben könnten), die eingesammelt werden wenn der Ball sie streift. Die machst du dann ähnlich wie den Ball und entfernst sie, wenn ihre Position innerhalb des Ballkreises liegt.

Weil ich ja noch etwas zum einsammeln muss.....wie genau kann ich das umsetzen? Ihr kennt euch so gut aus und fragen kostet ja nichts :wink:


Hidden - So 03.01.10 15:57

Hi user profile icon*Jenny* =),

Für drei Monate sieht das glaube ich schon erstaunlich gut aus(wenn ich so an meine Mitschüler denke, ich bin nämlich selbst noch für ein Vierteljahr Schüler :mrgreen:) :zustimm:
Ein Paar Tipps hätte ich aber doch noch(das macht euer Lehrer vielleicht auch falsch, stammt also nicht notwendigerweise von dir/euch):
Mit dem Timer ist glaube ich alles gesgt, das wiederhole ich jetzt nich nochmal^^

E: Bezüglich der Kollionsabfrage. Der Ball braucht eine Größe, nicht nur eine Position. Entweder stellst du ihn als Kreis dar, oder als Rechteck. Dann bestimmst du in jedem Timerstep für die Positionen der Boni, ob der Bonus sich "im Ball" befindet.
Für ein Rechteck geht das am leichtesten, nämlich exakt so wie du geprüft hast, ob der ball über eine der Tischkanten geht kannst du prüfen, ob der Boni innerhalb der Ballkanten geht.
Für einen Kreis ginge das mit Pythagoras: Im Ball <=> (x-xBall)*(x-xBall) + (y-yBall)*(y-yBall) <= 25, für einen Ball mit Radius 5.

mfG,