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 procedure ItemXK; procedure Itemauswahl; procedure ItemYK; procedure Punktezählung; var Punkte : Integer;
public
end;
var AC1: TAC1;
implementation
{$R *.dfm}
procedure TAC1.FormKeyPress(Sender: TObject; var Key: char);
var Buchstabeklein : char; var Buchstabegroß :char; begin
buchstabeklein := (key); buchstabegroß := upcase(key);
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; 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
Christian 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.
-
Wolverine78 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; |
Wolverine78 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; |
Wolverine78 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
Wolverine78 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.
Wolverine78 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
Christian 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
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!