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 !