Entwickler-Ecke

Multimedia / Grafik - Problem bei Spiel - Falsche Punktezählung - Wie


wolverine78 - So 11.09.05 12:39
Titel: Problem bei Spiel - Falsche Punktezählung - Wie
Hallo, ich bin hier neu inner Community und auch ziemlicher Anfänger in Delphi.
Mein erstes etwas komplexeres Projekt ist ein Spiel, in dem man mit einer Figur per Tastatur nach links und rechts
laufen kann und man versuchen muss runterfallende Äpfel zu fangen. Das sollte dann Punkte geben, erstmal 1 Punkt pro Apfel. Nur ich hab folgendes Problem: Der erste Apfel bringt normal 1 Punkt nur bei den nächsten kommen keine Punkte mehr, bis auf einem bestimmten Punkt. Dort zählt der dann pro 1ms 1Punkt.

Hier mal der gesamte Quellcode.


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:
 unit Applecatcher;

interface

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

type
  TAC1 = class(TForm)
    Item: TImage;
    Itemtimer: TTimer;
    Button1: TButton;
    Itemy: TTimer;
    Frau: TImage;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Punkte1: TTimer;
    Label4: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure ItemyTimer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure ItemtimerTimer(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
  private
    { Private declarations }
      procedure ItemXK;
      procedure Itemauswahl;
      procedure ItemYK;
      procedure Punktezählung;
      var Punkte : Integer;

  public
    { Public declarations }

  end;

var
  AC1: TAC1;

implementation

{$R *.dfm}


procedure TAC1.FormKeyPress(Sender: TObject; var Key: char);
{Variablen für Tastatur erstellen}
var Buchstabeklein : char;
var Buchstabegroß :char;
begin
{Variablen für Tastatur setzen}
buchstabeklein := (key);
buchstabegroß := upcase(key);
{Bewegungen bei Tastendruck erstellen}
 if buchstabeklein = 'a' then frau.Left := frau.left-14;
 if buchstabeklein = 'd' then frau.Left := frau.left+14;
 if buchstabegroß = 'A' then frau.Left := frau.left-14;
 if buchstabegroß = 'D' then frau.Left := frau.left+14;
 {Kollisionsabfrage bei Seitenwand}
 If frau.Left < 5  then frau.Left := 6;
 If frau.Left > 487 then frau.Left := 486;

end;

procedure TAC1.ItemXK;
var I: integer;
begin
I:= 1;
while I<10 do
begin
item.Left := round(random(487));
if item.Left < 5 then item.Left := 6;
if item.Left > 487 then item.Left := 486;
i := i+1;
item.Visible := true;
end;
end;

procedure Tac1.ItemYK;
begin
item.Top := item.Top + 14;
If item.Top > 300 then item.visible := false;
If item.Visible = false then item.Top := 40 ;
If item.Visible = false then itemtimer.Enabled := true;
label2.caption := Inttostr(frau.left);
label3.Caption := Inttostr(item.left);
label4.caption := Inttostr (item.Top);
end;

procedure Tac1.Itemauswahl;
var Itemzahl : integer;
begin
Itemzahl := round(random(7));
If Itemzahl = 0 then Item.Picture.LoadFromFile ('apfel2.ico');
If Itemzahl = 1 then Item.Picture.LoadFromFile ('Mona Lisa.ico');
If itemzahl = 2 then Item.Picture.LoadFromFile ('auto.ico');
If Itemzahl = 3 then Item.Picture.LoadFromFile ('gitarre.ico');
If Itemzahl = 4 then Item.Picture.LoadFromFile ('Kaputter Apfel.ico');
If Itemzahl = 5 then Item.Picture.LoadFromFile ('apfel2.ico');
If Itemzahl = 6 then Item.Picture.LoadFromFile ('apfel2.ico');
end;

procedure TAC1.Punktezählung;
var Kollision : Integer ;
begin
If Punkte > 0 then Punkte := Punkte else Punkte := 0;
while  item.Top > 299 do
if item.Left > frau.left then kollision := item.Left - frau.left ;
if item.Left < frau.Left then kollision := frau.Left - item.Left ;
If Kollision < 20 then Punkte := Punkte+1;
label1.caption := Inttostr(Punkte);
end;
procedure TAC1.ItemtimerTimer(Sender: TObject);
begin
Itemauswahl;
Itemxk;
itemtimer.enabled := false;
end;

procedure TAC1.Button1Click(Sender: TObject);
begin
itemtimer.enabled := true;
end;

procedure TAC1.ItemyTimer(Sender: TObject);
begin
 Itemyk;
 punktezählung;
end;

procedure TAC1.FormCreate(Sender: TObject);
begin
punkte := 0;
end;


end.


Ich würde mich freuen, wenn mir einer helfen könnte. Zudem bin für eventuelle Verbesserungen offen.

Mfg wolverine78

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt.


alias5000 - So 11.09.05 12:56

Hi und :welcome: im DF!
Ich sag mal so was mir auffällt.
-Benutze bitte statt der Code-Tags die Delphi-Tags, dann kann man den Source-Code besser lesen.
-
user profile iconWolverine78 hat folgendes geschrieben:


Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TAC1.Punktezählung;
var Kollision : Integer ;
begin
If Punkte > 0 then Punkte := Punkte else Punkte := 0;
...


das kannst du weglassen, da Punkte ja dann nicht verändert wird. Wenn du negative Punkte verhindern willst schreibe doch einfach

Delphi-Quelltext
1:
if Punkte < 0 then Punkte := 0;                    



user profile iconWolverine78 hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure Tac1.ItemYK;
begin
...
If item.Top > 300 then item.visible := false;
If item.Visible = false then item.Top := 40 ;
...



schreib doch einfach:


Delphi-Quelltext
1:
if item.Top > 300 then item.top := 40;                    



user profile iconWolverine78 hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TAC1.Punktezählung;
var Kollision : Integer ;
begin
...
while  item.Top > 299 do


also irgenwie versteh ich die Logik dahinter noch net ganz. Entweder das muss while item.Top < heißen oder ich komm net ganz drauf.

also bis dann Gruß alias5000

//EDIT: User-Tags verbessert

achso und nocwas, versuch bitte, nur den notwendigen Source-Code zu posten->Übersicht


wolverine78 - So 11.09.05 13:32

Danke, für die Vorschläge, aber mein Problem ist damit schliesslich net gelöst.


alias5000 - So 11.09.05 13:37

stimmt. Hatte es vergessen hinzuschreiben, zu deinem Hauptproblem war eigentlich die letzte Bemerkun gedacht... :oops:
Wie siehts da aus
Mit der Schleife?
Ansonsten ist mir noch nix aufgefallen.


Christian S. - So 11.09.05 13:42

Hallo!

Hier mal eine Prozedur aus Deinem Programm, richtig eingerückt:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TAC1.Punktezählung;
var Kollision : Integer ;
begin
  If Punkte > 0 then Punkte := Punkte else Punkte := 0;
  while  item.Top > 299 do
    if item.Left > frau.left then kollision := item.Left - frau.left ;
  
  if item.Left < frau.Left then kollision := frau.Left - item.Left ;
  If Kollision < 20 then Punkte := Punkte+1;
  
  label1.caption := Inttostr(Punkte);
end;


Zum einen: Bei der Schleife fehlt doch bestimmt ein begin und ein end. Und zum anderen: In der Schleife wird item.top doch nirgendwo geändert, oder? Wenn er also in die Schleife reingeht, wird er sie nie wieder verlassen.

Grüße
Christian

P.S.: Du siehst aber hoffentlich, dass das Einrücken von Quelltext sehr wichtig ist :-)
P.P.S.: :welcome: im DF

//edit: Die allererste if-Anweisung in der von mir geposteten Prozedur ist auch irgendwie merkwürdig. Wieso nicht einfach if punkte < 0 then punkte :=0; ?


wolverine78 - So 11.09.05 13:51

Ich hab den Code jetzt etwas verändert.
Mal ne andere Frage: Ist die Formel überhaupt richtig?
Denn ich will ja das er abfragt ob die figur unter dem apfel ist, damit der apfel ja in den Korb der Figur fällt. Dann kann man ja noch xkoordinate +- 20 nehmen, da dann der Apfel trotzdem noch reinfällt.

PS: Ich bin eben noch net son Pro, jeder hat mal angefangen :)


alias5000 - So 11.09.05 14:01

user profile iconWolverine78 hat folgendes geschrieben:

PS: Ich bin eben noch net son Pro, jeder hat mal angefangen :)


Logisch! Genau deswegen versuchen wir dir so gut wie möglich zu helfen.

user profile iconWolverine78 hat folgendes geschrieben:


Delphi-Quelltext
1:
2:
  while  item.Top > 299 do
    if item.Left > frau.left then kollision := item.Left - frau.left ;


Ja, aber das Problem liegt nicht direkt im logischen, sondern dreht sich vor allem um diese Schleife erst einmal.
Diese Schleife wird NIE ausgeführt, wenn item.top <= 299
Sie wird aber nie enden, wenn item.top > 299, weil item.top innerhalb der schleife immer gleich bleibt und somit immer item.top > 299

Moderiert von user profile iconChristian S.: Quote-Tag repariert


wolverine78 - So 11.09.05 14:07

AH ok, und wie sollte ich das machen das sie einmal ausgefügrt wird und dann endet.
Ich will ja, dass derdie Punkte erst zählt wenn der Apfel erst kurz vorm Korb ist. In dem Fall eben 299 ykoordinate. Aber es ist ja so, wenn die Figur eine bestimmte x-koordinate hat, zählt je einen Punkt pro 1ms, egal wo der Apfel ist.


NCortex - So 11.09.05 19:50

also, am besten definierst du eine "hitbox" (den Korb der FRau)

wenn der Apfel sich in dem Korb befindet, dann gilt er als gefangen.


Delphi-Quelltext
1:
2:
gefangen := ((((item.left + item.width) > Frau.left) and (item.left < (Frau.left + Frau.width)))
   and (((item.top + item.height) > Frau.top) and (Item.top < (Frau.top + Frau.height))));


dadurch hast du in gefangen schon mal gespeichert, ob der Ball im korb war.

du musst den Apfel "löschen", wenn er einmal in dem korb war, weil er sonst immer weiter addiert.

also entweder du tust ihn oben wieder an baum oder nimmst ihn komplett raus...

zum beispiel würd gehen:


Delphi-Quelltext
1:
if (gefangen) then item.top := -100;                    


wolverine78 - So 11.09.05 21:13

VIELEN DANK an alle, aber besonders an NCORTEX. Die Punktezählung läuft nun einwandfrei und die Grundtechnik funktioniert jetzt. Ich muss nun nurnoch die Optik anpassen und dem Spiel den letzten Schliff verpassen(Highscore usw.) dann bin ich soweit mit der ersten Version feddig. :D

Ich freu mich so.

MFG wolverine78