AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Tutorials Delphi Hausgemachte Pixelgenaue Kollisionsabfrage

Hausgemachte Pixelgenaue Kollisionsabfrage

Ein Tutorial von braingrenade · begonnen am 10. Mär 2003
Antwort Antwort
Benutzerbild von braingrenade
braingrenade
Registriert seit: 30. Okt 2002
Jo , im Forum wude ja vor ner Weile die Frage gestellt wie man ne Kollisions-Abfrage machen könnte , und da ich gerade an nem Spiel dran bin und schon eine habe werd ich's halt hier mal reintun!

Vom Grundprinzip her ist diese KA (Kollisions Abfage) nach volgendem Prinzip aufgebaut :

Mit einem separaten Programm werden alle Punkte die aussen herum um
das Raumschiff bzw. das Bild davon liegen in eine Datei geschrieben
und im Spiel dann eingelesen und auf die Graphik gelegt.

Das Programm das die Dateien schreibt funktioniert folgendermaßen:

Die bmp des Raumschiffs wird eingeladen und soll nun so ausgewertet werden :
Code:
    +
   +-+
  +---+
  +---+
 +-----+ 
+-------+
+ = Pixel die gelesen werden
- = Pixel die ignoriert werden

Außerdem muss es noch die punkte die ein Paar sind kennzeichnen.

wir brauchen :
3 Buttons
2 edits
2 images
1 memo


und hier der Code :
Delphi-Quellcode:

type kolfile = record // der record in dem alles wichtige drin ist
    x,y : integer ;
    paar : bool;
    end;


implementation

{$R *.dfm}


procedure TForm1.Button1Click(Sender: TObject);
begin
 Image1.Picture.LoadFromFile(edit1.Text); // bild einladen
end;

//jetzt kommt das komplizierte :

procedure TForm1.Button2Click(Sender: TObject);
var
 position : kolfile ;
 datei : file of kolfile ;
 start : bool;
begin
memo1.Clear;
position.paar := false; // erst mal alles vordefinieren
position.x := 0;
position.y := 0;
start := false;
assignfile(datei,edit2.text); // ist war veraltet, aber am einfachsten
rewrite(datei);

//Nun zu den Innereien
 
repeat

  if image1.Canvas.Pixels[position.x,position.y] <> clwhite then
//unterscheidet sich der erste Pixel von der HintergrundFarbe des Bmp's
// in dem fall weiss dann :
  begin
   write(datei,position); //schreib den pixel in die datei
   memo1.text:=memo1.Text+('x: '+inttostr(position.x)+' , '+'y: + 'paar: '+booltostr(position.paar)+' | ') ; //und in's memo
   start := false;
    
    if image1.Canvas.Pixels[position.x+1,position.y] <> clwhite then
     // ist der nachfolgende Pixel auch nicht weiss dann sucht das Programm solange nach weiter bis es einen weißen pixel findet und schreibt dann der
     // vorherigen Pixel in die Datei aber mit paar :'= true , d.h. das nun das erste Pixel-Paar in der Datei steht.
     
   begin
      while start = false do
       begin
       if image1.Canvas.Pixels[position.x+1,position.y] = clwhite then
        
         begin
        
         position.paar:=true;
         write(datei,position);
         position.paar:=false;
         start:=true;
         end;
         inc(position.x);
       
         if position.x = Image1.Width then
         begin
           
            if image1.Canvas.Pixels[position.x+1,position.y] <> clwhite then
            begin
            
             position.paar:=true;
             write(datei,position);
             position.paar:=false;
           end;
        position.x := 0;
        inc(position.y);
        start:=true;
       end;
     end;
   end;
  end;

   inc(position.x) ;


 if position.x = Image1.Width then // position.x das den Bildrand erreicht spring die Zeile eins weiter nach unten.
  begin
   position.x := 0;
   inc(position.y);
  end;


until position.y = Image1.Height; // das ganze macht er solange bis alle Pixel des Bilds abgearbeitet sind.

closefile(datei);
end;
So , nun haben wir eine kol-Datei in der alle Pixel-Paare des bmp's gespeichert sind , nun müssen wir nur noch das gnze ins spiel einbringen.

Delphi-Quellcode:

type tpunkt = record
    x: integer ;
    y : integer;
end;

//als erstes ein Object in dem alle wichtigen Procedure und Variablen enthalten sind:

type Tkol = Object
      kol : array of Tkolfile; // hier herein kommen die eingelesen Daten.
      koord : Tpunkt ; //die Koordinaten der Grafik bzw. des Raumschiffs
     enabled : bool;
  procedure kolladen(pfad : string); //hier wird die Kol-Datei geladen
  procedure kolvar(Sender:Tobject); //hier wird der Kollisionsrahmen auf die Grafik gelegt
  procedure antikolvar(Sender:Tobject); // und hier wieder entfernt.
end;

var
gegner : Tkol ;
schiff : Tkol ;

implementation

{$R *.dfm}


procedure Tkol.kolladen(pfad:string);
var pos : Tkolfile;
var datei : file of Tkolfile ;
var i : Integer;
var i2 : Integer ;
begin
 try
  assignfile(datei,pfad);
  reset(datei);
  i:=0;
  i2:=0;
   while not eof(datei) do
    begin
     read(datei,pos);
     inc(i);
    end;
  setlength(kol,i);
  reset(datei);

 while not eof(datei) do
  begin
   read(datei,kol[i2]);
  inc(i2);
  end;

close(datei);

except
 begin
   showmessage('Leider gab es einen Fehler!(HaHa)');
 end,
end;
end;

procedure Tkol.kolvar(Sender:Tobject);
var i: integer;
begin
 for i := 0 to high(kol) do //für jeden Punkt wird die Position angeglichen
  begin
   if enabled = true then
    begin
     kol[i].x := kol[i].x + koord.x; // eigentlich ganz simpel!
     kol[i].y := kol[i].y + koord.y;
   end;
 end;
end;


procedure Tkol.antikolvar(Sender:Tobject);
var i: integer;
begin
 for i := 0 to high(kol) do //hier bekommt jeder Pixel seinen alten Wert
  begin
   if enabled = true then
     begin
       kol[i].x := kol[i].x - koord.x;
       kol[i].y := kol[i].y - koord.y;
     end;
  end;
end;


Das tragt ihr in die Form.Create oder in eine Initialisierungsprocedure ein ,
Delphi-Quellcode:
gegner.kolladen('C:/gegner.kol'); //Achtung der Schrägstrich ist falsch herum ! Hab keine Ahnung wo der andere beim Mac ist !)
 schiff.kolladen('C:/gegner.kol'); //hier genauso!

So , nun zu der eigentlichen abfrage :

Delphi-Quellcode:


procedure kollision(Sender : Tobject);
begin
 gegner.kolvar(Sender) ;
 schiff.kolvar(Sender);

if gegner.enabled = true then
  for i := 0 to high(gegner.kol) do
    if (gegner1.kol[i-1].paar = false) and (gegner.kol[i].paar = true) then
       for i2 := 0 to high(schiff.kol) do
        if (gegner.kol[i-1].x < schiff.kol[i].x) and (gegner.kol[i].x > schiff.kol[i2].x) and
           (gegner.kol[i].y = schiff.kol[i2].y) then
             begin
                 beep;
                 end ;


gegner.kolvar(Sender);
 schiff.kolvar(Sender);

end;
In der Abfrage wird einfach nur gefragt ob irgendein Punkt der Schiffs kol-Datei zwischen einem Punkt-Paar der kol-Datei des Gegners liegt und das wars !


So, das wahr mein erstes Tutorial , ich wollt's eigentlich ein bischen besser machen , aber leider muss ich grad an nem Mac arbeite wo ich den Code nur Text Datei bearbeiten kann , aber ich schau mal das ich noch ne überarbeitete Version hier poste!


Viel Spaß beim Ausprobieren !
Let the sun beat down upon my face
Stars fill my dream
I am a traveller of both time and space
To be where I have been ________________ Such A Surge
 
Themen-Optionen Tutorial durchsuchen
Tutorial durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2020 by Daniel R. Wolf