Programmieren - alles kontrollieren 4.940 Themen, 20.676 Beiträge

Delphi: Das Spiel

Tommy22 / 11 Antworten / Baumansicht Nickles

Hab vor wenigen Wochen mit dem Programmieren eines Spiels begonnen. Es handelt sich um eine Art Breakball/Pong und funktioniert auch soweit ganz gut, jedoch gibt es da noch 2 Probleme:

Problem 1:
Ich brauche einen Zähler, der bei 10 anfängt und für jeden verlorenen Ball um 1 verringert wird. Das Problem ist, dass 10 lediglich der Startwert ist und keine Konstante sein soll, entweder er bleibt immer auf 10 oder er springt zwischen 9 und 10 hin und her.

Problem 2:
Wenn der Ball am Paddle vorbeifliegt soll eine neue Runde beginnen, dabei darf aber nicht das ganze Programm resettet werden, stattdessen soll lediglich kurz unterbrochen werden und der Ball soll wieder ins Feld kommen.

Allzu kompliziert darf/kann die Lösung ja nicht sein, da wir ja nicht allzu komplex arbeiten, das Spiel funktioniert über ein begrenztes Panel und einem beweglichen Image als Ball und einem Shape als Paddle, welches per Maus gesteuert wird.

Hey Dr. Kleiner - Ja Gordon? - Guck mal! Ist das nicht ne schöne Brechstange!? Fass sie mal an!
bei Antwort benachrichtigen
Andreas42 Tommy22 „Delphi: Das Spiel“
Optionen

Hi!

Das klingt ja nach zwei ganz speziellen "Problemen", die aber bestimmt lösbar sind. Allerdings müsste man dazu etwas mehr über das bisher realisierte Programm wissen. Kannst du uns zumindest schreiben, welche Klassen du verwendest bzw. abgeleitet hast und wie die bisherige Spiellogig funktioniert?

Du musst ja (wenn ich das richtig verstehe) in Delphi ein Timerelement verwenden, damit die Spieleelemente gezeichnet werden und die Mausabfrage erfolgt. Zudem wird es einen Start-Button geben müssen, mit dem das Spiel beginnt. Die Methoden dahinter sind interessant, weil dein erstes Problem natürlich erfordert, dass der Zähler einmal initialisiert wird (z.B. wenn der Button "Neues Spiel" geklinkt wird und dnan rückzählt, wenn der ball aus dem Bildbereich läuft.

Bis dann
Andreas

Hier steht was ueber mein altes Hard- und Softwaregedoens.
bei Antwort benachrichtigen
Tommy22 Andreas42 „Hi! Das klingt ja nach zwei ganz speziellen Problemen , die aber bestimmt...“
Optionen

Ja, das ganze funzt über einen Timer, allerdings ohne Startbutton, das Spiel startet sofort. Theoretisch kann ich doch diese Timerfunktion als Click.Button ausführbar machen, oder? Allerdings startet das Spiel dann immer noch von vorne siehe Problem #2...

Hey Dr. Kleiner - Ja Gordon? - Guck mal! Ist das nicht ne schöne Brechstange!? Fass sie mal an!
bei Antwort benachrichtigen
Borlander Tommy22 „Ja, das ganze funzt über einen Timer, allerdings ohne Startbutton, das Spiel...“
Optionen

Die TTimer kannst Du AFAIR über timer.enabled := true; zu einem beliebigen Zeitpunkt starten. Also z.B. auch im Eigenishandler für Klicken auf einen Button ;-)

bei Antwort benachrichtigen
Borlander Tommy22 „Delphi: Das Spiel“
Optionen

Problem 1 liest sich für mich so als ob Du eine lokale Variable verwendet hättest. Die wird dann bei jedem Aufruf der Function/Procedure mit dem Startwert initialisiert. Du bräuchtest entweder eine globale Variable, oder eine statische (ich weiß allerdings spontan nicht ob Object-Pascal sowas kennt und wie die ggf. heißen würden)...

Gruß
Borlander

bei Antwort benachrichtigen
Tommy22 Borlander „Problem 1 liest sich für mich so als ob Du eine lokale Variable verwendet...“
Optionen

Hier nun mal ein Ausschnitt:

procedure TForm1.FormCreate(Sender: TObject);
begin
randomize;
vx:=-20+Random(40);
vy:=-20+Random(40);
Panel1.DoubleBuffered:=true;
end;



procedure TForm1.Timer1Timer(Sender: TObject);
begin
Image1.Left:=Image1.Left+vx;
Image1.Top:=Image1.Top+vy;
if(Image1.Left<Panel1.Left)
then vx:=vx*-1;
if (Image1.Top<Panel1.Top) OR (Image1.Top>Panel1.Height-Image1.Height-1)
then vy:=vy*-1;
mid:=Image1.BoundsRect.BottomRight;
mid.y:=mid.y-Image1.Height DIV 2;
if PtInRect(Shape1.BoundsRect, mid) then
vx:=vx*-1;
if PtInRect(Shape1.BoundsRect, mid) then
hit_counter:=hit_counter+1;
Label1.Caption:=IntToStr(hit_counter);
end;



procedure TForm1.Shape1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button=mbLeft then
begin
move:=true;
mouse_y:=Y;
end
end;

procedure TForm1.Shape1MouseMove(Sender: TObject; Shift: TShiftState; X, Y:
Integer);
begin
if move then Shape1.Top:=Shape1.Top-(mouse_y-Y);
end;


procedure TForm1.Shape1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
move:=false;
end;



procedure TForm1.Button1Click(Sender: TObject);
begin
close;
end;

Hey Dr. Kleiner - Ja Gordon? - Guck mal! Ist das nicht ne schöne Brechstange!? Fass sie mal an!
bei Antwort benachrichtigen
Borlander Tommy22 „Hier nun mal ein Ausschnitt: procedure TForm1.FormCreate Sender: TObject begin...“
Optionen

Sehe ich das richtig, daß hit_counter der angesprochene Zähler ist? Wo und wie wir der Initialisiert? Bist Du sicher, daß dieser Code nicht mehrfach durchlaufen wird?

bei Antwort benachrichtigen
Tommy22 Borlander „Sehe ich das richtig, daß hit_counter der angesprochene Zähler ist? Wo und wie...“
Optionen

Genau, er wird mehrfach durchlaufen und das soll er nicht. Aber wohin sonst damit?

Hey Dr. Kleiner - Ja Gordon? - Guck mal! Ist das nicht ne schöne Brechstange!? Fass sie mal an!
bei Antwort benachrichtigen
Borlander Tommy22 „Genau, er wird mehrfach durchlaufen und das soll er nicht. Aber wohin sonst damit?“
Optionen

Also ich Deinem Code-Auszug finde ich keine Stelle an der diese Variable Initialisiert wird. Nur die beiden folgenden Zeilen:
hit_counter:=hit_counter+1;Label1.Caption:=IntToStr(hit_counter);
Da wird hochgezählt...

bei Antwort benachrichtigen
Tommy22 Borlander „Also ich Deinem Code-Auszug finde ich keine Stelle an der diese Variable...“
Optionen

Dabei handelt es sich lediglich um einen Zähler für die Treffer, also wie oft sich Ball und Paddle berühren.

Ich hab in etwa folgendes versucht:

counter: Integer

if(Image1.Left>Panel1.Width-Image1.Width-1), sprich der Ball aus dem Panel fliegt, was ja die richtige Voraussetzung ist, then counter:=counter-1;

Nur: Wie gebe ich counter die vorgegebene Größe (10) an? Und außerdem ist die obige Bedingung ja auch das Kriterium für eine neue Runde, ansonsten zählt er nämlich immer weiter. Und die neue Runde krieg ich nicht hin :/

Die Variablen sind alle unter "public" als Integer oder Boolean deklariert.

Hey Dr. Kleiner - Ja Gordon? - Guck mal! Ist das nicht ne schöne Brechstange!? Fass sie mal an!
bei Antwort benachrichtigen
ChrE Tommy22 „Dabei handelt es sich lediglich um einen Zähler für die Treffer, also wie oft...“
Optionen

Hallo!

Benutze den Counter so:

procedure FormBlaBla;
const
Counter: Integer = 10;
begin
//irgendwas machen

Counter:=Counter-1;
end;

Habe gelesen, die Variable ist dann static und bleibt
über den einmaligen Aufruf der Prozedur erhalten...

Hoffe, das hilft.

Gruss

ChrE


bei Antwort benachrichtigen
Tommy22 ChrE „Hallo! Benutze den Counter so: procedure FormBlaBla const Counter: Integer 10...“
Optionen

Danke erstmals, ich werd's versuchen

Hey Dr. Kleiner - Ja Gordon? - Guck mal! Ist das nicht ne schöne Brechstange!? Fass sie mal an!
bei Antwort benachrichtigen