Autor Beitrag
wolverine78
Hält's aus hier
Beiträge: 5



BeitragVerfasst: So 11.09.05 12:39 
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.

ausblenden volle Höhe 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2145

WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
BeitragVerfasst: 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:

ausblenden 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
ausblenden Delphi-Quelltext
1:
if Punkte < 0 then Punkte := 0;					



user profile iconWolverine78 hat folgendes geschrieben:
ausblenden 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:

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



user profile iconWolverine78 hat folgendes geschrieben:
ausblenden 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

_________________
Programmers never die, they just GOSUB without RETURN
wolverine78 Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: So 11.09.05 13:32 
Danke, für die Vorschläge, aber mein Problem ist damit schliesslich net gelöst.
alias5000
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2145

WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
BeitragVerfasst: 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.

_________________
Programmers never die, they just GOSUB without RETURN
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: So 11.09.05 13:42 
Hallo!

Hier mal eine Prozedur aus Deinem Programm, richtig eingerückt:
ausblenden 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; ?

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
wolverine78 Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2145

WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
BeitragVerfasst: 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:

ausblenden 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

_________________
Programmers never die, they just GOSUB without RETURN
wolverine78 Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 126

WIN 2000
D7 Enterprise
BeitragVerfasst: 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.

ausblenden 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:

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

_________________
"...by all means, do not use a hammer." (aus einer IBM Technikerdokumentation ca. 1920)
--->außer es kam von Microsoft<---
wolverine78 Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: 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