Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Spiel (Aspirin): Spieler kurzzeitig unverletzlich machen (https://www.delphipraxis.net/171094-spiel-aspirin-spieler-kurzzeitig-unverletzlich-machen.html)

Premaider 19. Okt 2012 18:42

Spiel (Aspirin): Spieler kurzzeitig unverletzlich machen
 
Delphi-Quellcode:
//Auszug aus Timer1 (der regelt bei mir alles)

//Kollision Spieler und Gegner
For k:= low(gegner) to high(gegner) do
  begin
    if ((IsCollision(Gegner[k].BoundsRect, Spieler.BoundsRect)) and (Gegner[k].Cooldown<=0))Then
      begin
        Spieler.Verletzbar:=False;
        If Herzen>=2 then
          begin
            Herzen:=Herzen-1;
            If ((Herzen=4) and (Spieler.Verletzbar=True)) Then
              begin
                Spieler.Verletzbar:=False;
                Abwarten2.Enabled:=True;
                Herz5.picture.loadfromfile(Pfad+'\Datein\Herz_Leer.jpg');
              end;
            If ((Herzen=3) and (Spieler.Verletzbar=True)) Then
              begin
                Spieler.Verletzbar:=False;
                Abwarten2.Enabled:=True;
                Herz5.picture.loadfromfile(Pfad+'\Datein\Herz_Leer.jpg');
                Herz4.picture.loadfromfile(Pfad+'\Datein\Herz_Leer.jpg');
              end;
            If ((Herzen=2) and (Spieler.Verletzbar=True)) Then
              begin
                Spieler.Verletzbar:=False;
                Abwarten2.Enabled:=True;
                Herz5.picture.loadfromfile(Pfad+'\Datein\Herz_Leer.jpg');
                Herz4.picture.loadfromfile(Pfad+'\Datein\Herz_Leer.jpg');
                Herz3.picture.loadfromfile(Pfad+'\Datein\Herz_Leer.jpg');
              end;
            If ((Herzen=1) and (Spieler.Verletzbar=True)) Then
              begin
                Spieler.Verletzbar:=False;
                Abwarten2.Enabled:=True;
                Herz5.picture.loadfromfile(Pfad+'\Datein\Herz_Leer.jpg');
                Herz4.picture.loadfromfile(Pfad+'\Datein\Herz_Leer.jpg');
                Herz3.picture.loadfromfile(Pfad+'\Datein\Herz_Leer.jpg');
                Herz2.picture.loadfromfile(Pfad+'\Datein\Herz_Leer.jpg');
              end;
          end;
        If Herzen<=1 then
          begin
            Verloren;
            Herz1.Picture.LoadFromFile(Pfad+'\Datein\Herz_leer.jpg');
          end;
      end;
  end;
...

procedure TForm1.Abwarten2Timer(Sender: TObject);
begin
Spieler.Verletzbar:=True;
Abwarten2.Enabled:=false;
end;
Es gibt insgesammt 5 Herzen (leben). Immer wenn der Spieler einen Gegner berührt soll eins abgezogen werden. Bis man schließlich bei 0 Herzen stirbt. Leider wurden immer alle 5 Herzen abgezogen, sobald man den Gegner (der sich bewegt) berührte, da der Spieler den Gegner ja noch berührte als ein Herz abgezogen wurde. Also wurden eins nach dem anderen Abgezogen. Ich dachte ich mache den Spieler für kurze zeit unverwundbar, denn der Gegner bewegt sich ja und ist dann "weg". 1000ms müssten locker reichen. Leider funktioniert das irgendwie nicht. Kann mir jemand sagen warum und mir helfen ?

himitsu 19. Okt 2012 18:49

AW: Spiel (Aspirin): Spieler kurzzeitig unverletzlich machen
 
Sowas wie
Delphi-Quellcode:
if (Spieler.Verletzbar=True) then
solltest du dringen mal ausbauen.
Delphi-Quellcode:
if Spieler.Verletzbar then
oder das Gegenteil
Delphi-Quellcode:
if not Spieler.Verletzbar then
.


Und nun zu deinem Problem:

Du stellst zwar die Herzen-Bilder entsprechend (falsch) dar,
aber eigentlich solltest, aber eigentlich solltest du die Herzen-Variable nicht verändern, wenn sie nicht verändert werden soll :zwinker: (not Spieler.Verletzbar)

"falsch", da deine Bilder nicht zur Variable passen.

Premaider 19. Okt 2012 18:53

AW: Spiel (Aspirin): Spieler kurzzeitig unverletzlich machen
 
Zitat:

Zitat von himitsu (Beitrag 1187653)
Sowas wie
Delphi-Quellcode:
if (Spieler.Verletzbar=True) then
solltest du dringen mal ausbauen.
Delphi-Quellcode:
if Spieler.Verletzbar then
oder das Gegenteil
Delphi-Quellcode:
if not Spieler.Verletzbar then
.


Und nun zu deinem Problem:

Du stellst zwar die Herzen-Bilder entsprechend (falsch) dar,
aber eigentlich solltest, aber eigentlich solltest du die Herzen-Variable nicht verändern, wenn sie nicht verändert werden soll :zwinker: (not Spieler.Verletzbar)

"falsch", da deine Bilder nicht zur Variable passen.

Hä? Aber sie soll doch verändert werden. Es soll doch ein Herz abgezogen werden. Sorry verstehe dich nicht :S

P.s. Wieso soll ich das denn ausbauen ? Hat das irgendeine auswirkung ??

Progman 19. Okt 2012 19:09

AW: Spiel (Aspirin): Spieler kurzzeitig unverletzlich machen
 
Spieler.Verletzbar ist doch vom Typ Boolean.
Daher erübrigt sich die Abfrage nach True oder False.
Daher der Hinweis:
Zitat:

Sowas wie if (Spieler.Verletzbar=True) then solltest du dringen mal ausbauen.
if Spieler.Verletzbar then oder das Gegenteil if not Spieler.Verletzbar then .
Das ist eben sauberere Programmierung :P

Premaider 19. Okt 2012 19:15

AW: Spiel (Aspirin): Spieler kurzzeitig unverletzlich machen
 
Zitat:

Zitat von Progman (Beitrag 1187656)
Spieler.Verletzbar ist doch vom Typ Boolean.
Daher erübrigt sich die Abfrage nach True oder False.
Daher der Hinweis:
Zitat:

Sowas wie if (Spieler.Verletzbar=True) then solltest du dringen mal ausbauen.
if Spieler.Verletzbar then oder das Gegenteil if not Spieler.Verletzbar then .
Das ist eben sauberere Programmierung :P

Ich werds mir abgewöhnen :D
Jetzt aber wieder zum eigendlichen Problem..

himitsu 19. Okt 2012 19:22

AW: Spiel (Aspirin): Spieler kurzzeitig unverletzlich machen
 
Ja, es ist sauberer, aber auch Fehlerunanfälliger.

Ein Boolean hat eben nicht nur zwei Zustände wie True und False, sondern mindestens 256. (Boolean = 1 Byte und z.B. LongBool = 4 Byte)

Ganz genau ist es so definiert:
False = 0
True <> 0

Aber da eine Konstante nur einen Wert haben kann, ist in Delphi das True als 1 definiert. (in C-Sprachen dagegen meist als -1)

=True kann daher eine falsches Ergebnis liefern.

Das ist so ähnlich, wie bei den Floats (Fließkommazahlen ala Single oder Double), walche man auch nicht unbedingt auf "Gleichheit" prüfen sollte.

Delphi-Quellcode:
var B: Boolean;

B := Boolean(2);

if B = True then
  ShowMessage('B = True');
if B = False then
  ShowMessage('B = False');

if B then
  ShowMessage('B');
if not B then
  ShowMessage('not B');




Das Herz soll doch aber nur abgezogen werden, wenn man verletzbar ist. :zwinker:
Ist man nicht verletzbar, dann darf auch nichts abgezogen werden, sonst stirbt man ja dennoch.
Und wieviele Leben die Bilder anzeigen ist ja egal ... es kommt doch auf die Variable drauf an.
Abgesehn davon, daß die Bilder besser mit der Variable übereinstimmen sollten, sonst sieht man ja was Falsches.

Du mußt also die Variable abhängig von "Verletzbar" verändern, oder eben nicht.
Aber die Bilder dennoch das anzeigen lassen, was in der Variable steht.


PS: Wenn du etwas OOP-iger werden willst, dann erstell dir eine Komponente "THerzen", welche ein Property Herzen (Integer) besitzt, worüber man diesen Wert setzen und auslesen kann.
Und diese Klasse kümmert sich "intern" auch um die Anzeige ihrer Herz-Bildchen, entsprechend dem Wert.

Premaider 19. Okt 2012 19:27

AW: Spiel (Aspirin): Spieler kurzzeitig unverletzlich machen
 
Zitat:

Zitat von himitsu (Beitrag 1187659)
Ja, es ist sdauberer, aber auch Fehlerunanfälliger.

Ein Boolean hat eben nicht nur zwei Zustände wie True und False, sondern mindestens 256. (Boolean = 1 Byte und z.B. LongBool = 4 Byte)

Ganz genau ist es so definiert:
False = 0
True <> 0

Aber da eine Konstante nur einen Wert haben kann, ist in Delphi das True als 1 definiert. (in C-Sprachen dagegen meist als -1)

=True kann daher eine falsches Ergebnis liefern.

Das ist so ähnlich, wie bei den Floats (Fließkommazahlen ala Single oder Double), walche man auch nicht unbedingt auf "Gleichheit" prüfen sollte.

Delphi-Quellcode:
var B: Boolean;

B := Boolean(2);

if B = True then
  ShowMessage('B = True');
if B = False then
  ShowMessage('B = False');

if B then
  ShowMessage('B');
if not B then
  ShowMessage('not B');

Okay werd ich machen danke
" aber eigentlich solltest du die Herzen-Variable nicht verändern, wenn sie nicht verändert werden soll (not Spieler.Verletzbar)" meinst du damit das die herzen verringert werden sollen wenn der Spieler unverletzlich wird ?

Dann werd ich das dann machen wenn mein eigendliches Problem gelöst ist.

himitsu 19. Okt 2012 20:01

AW: Spiel (Aspirin): Spieler kurzzeitig unverletzlich machen
 
:oops: wenn verletzlich dann verändern :wink:

Delphi-Quellcode:
if Spieler.Verletzbar then Dec(Herzen);



Gut, wenn man den "unverletzbarkeits"-Modus als solchen ansieht, dann

wenn nicht unverletzlich dann verändern :wink:

Delphi-Quellcode:
if not Spieler.Unsterblich then Dec(Herzen);

Premaider 19. Okt 2012 20:39

AW: Spiel (Aspirin): Spieler kurzzeitig unverletzlich machen
 
Jo danke es geht :D

Premaider 20. Okt 2012 11:39

AW: Spiel (Aspirin): Spieler kurzzeitig unverletzlich machen
 
Delphi-Quellcode:
//Kollision Spieler und Gegner
For k:= low(gegner) to high(gegner) do
  begin
    if ((IsCollision(Gegner[k].BoundsRect, Spieler.BoundsRect)) and (Gegner[k].Cooldown<=0)) Then //hier wird die Zugriffsverletzung angzeigt
          begin
            If Spieler.Verletzbar Then Dec(Herzen);
            If ((Herzen=4) and (Spieler.Verletzbar)) Then
              begin
                Spieler.Verletzbar:=False;
                Abwarten2.Enabled:=True;
                Herz5.picture.loadfromfile(Pfad+'\Datein\Herz_Leer.jpg');
              end
            Else If ((Herzen=3) and (Spieler.Verletzbar)) Then
              begin
                Spieler.Verletzbar:=False;
                Abwarten2.Enabled:=True;
                Herz4.picture.loadfromfile(Pfad+'\Datein\Herz_Leer.jpg');
              end
            Else If ((Herzen=2) and (Spieler.Verletzbar)) Then
              begin
                Spieler.Verletzbar:=False;
                Abwarten2.Enabled:=True;
                Herz3.picture.loadfromfile(Pfad+'\Datein\Herz_Leer.jpg');
              end
            Else If ((Herzen=1) and (Spieler.verletzbar)) Then
              begin
                Spieler.Verletzbar:=False;
                Abwarten2.Enabled:=True;
                Herz2.picture.loadfromfile(Pfad+'\Datein\Herz_Leer.jpg');
              end;
          end
        Else If ((Herzen=0) and (Spieler.verletzbar)) then //hier müsste die Zugriffsverletzung eigendlich stehen oder ?
          begin
            Verloren;
            Spieler.verletzbar:=false;
            Abwarten2.Enabled:=True;
            Herz1.Picture.LoadFromFile(Pfad+'\Datein\Herz_leer.jpg');
          end;
  end;
Leider bekomme ich jetzt manchmal eine Zugriffsverletzung. Wenn nur wenige Gegner exsistieren dann ist alles ganz normal. Doch sobald es mal ein paar mehr sind(Ich weiß leider nicht wieviele es dafür sein müssen) bekomme ich eine Zugriffsverletzung sobald man verliert. (Verloren-Procedure)
Weiß jemand warum ?


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:33 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz