[DelphiX] Kollision
Hi zusammen! :)
Ich weiß, das Thema hatten wir schon oft, aber mir helfen die Suchergebnise nicht. Folgender Code wird ausgelöst, wenn eine Kollision stattfindet (2D):
Delphi-Quellcode:
Hier möchte ich abfragen, ob sich eine Figur in eine bestimmte Richtung bewegen kann, in dem Beispiel, nach links.
TAnimation = class(TImageSprite)
public procedure DoMove(MoveCount: Integer); override; procedure DoCollision(Sprite: TSprite; var Done: Boolean); override; end; ... procedure TAnimation.DoCollision(Sprite: TSprite; var Done: Boolean); var InCollision: boolean; begin //Bewegung nach links (ich müsste noch die Y Koorinaten überprüfen) if (X < TGegenstand(Sprite).X + Gegenstand.Width) then cangoleft := false; end; So überprüfe ich auch die anderen benachbarten Koorinaten, das Problem ist nur, dass diese Prozedur ausgelöst wird, wenn man sich in einem Gegenstand befindet, und nicht, wenn man danaben ist. Hier ist eine Kollisionsabfrage beschrieben, die mich jedoch nicht weiter bringt. Ich habe schon versucht, die Kollisions-Prozedur einfach neu zu schreiben und keine von TAnimation zu nehmen, doch das hat nicht geklappt, da, da z.B. "Sprite" nicht bekannt ist. Kann mir da evtl jemand behilflich sein? :roll: |
Re: [DelphiX] Kollision
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab jetzt mal weiter Probiert, so weit bin ich gekommen:
Im Anhang die gepackte exe, damit ihr seht, wie "seltsam" sich die Figur verhält" und hier der ausschlaggebende Source:
Delphi-Quellcode:
Ich habe absichtlich nicht den restlichen Quelltext angehängt, weil er Dinge enthält, die ich noch nicht unbedingt veröffentlichen möchte. :roll:
//////////////////////////////////////////
// DOCANGO ////////////////////////////////////////// procedure TAnimation.DoCanGo(Enabled: Boolean); begin cangoleft := Enabled; cangoright := Enabled; cangoup := Enabled; cangodown := Enabled; end; ////////////////////////////////////////// // BEWEGUNG DER ANIMATION ////////////////////////////////////////// procedure TAnimation.DoMove(MoveCount: integer); begin inherited DoMove(MoveCount); If cangoup and (isUp in Form1.DXInput1.States) Then if not Jump then begin DoCanGo(true); Y := Y - Step; end; If cangodown and (isDown in Form1.DXInput1.States) Then begin DoCanGo(true); end; If cangoleft and (isLeft in Form1.DXInput1.States) Then begin DoCanGo(true); X := X - Step; if not Duck then Form1.AnimBild('Girl1left'); end; If cangoright and (isRight in Form1.DXInput1.States) Then begin DoCanGo(true); X := X + Step; if not Duck then Form1.AnimBild('Girl1right'); end; Collision; end; ////////////////////////////////////////// // KOLLISIONS-ABFRAGE ////////////////////////////////////////// procedure TAnimation.DoCollision(Sprite: TSprite; var Done: Boolean); begin DoCanGo(true); if (X < TGegenstand(Sprite).X - Step) then begin X := X - Step; cangoright := false; end; if (X > TGegenstand(Sprite).X + Step) then begin X := X + Step; cangoleft := false; end; if (Y + Animation.Height > TGegenstand(Sprite).Y + Step) then begin Y := Y + Step; cangoup := false; Jump := false; end; if (Y < TGegenstand(Sprite).Y + TGegenstand(Sprite).Height - Step) then begin Y := Y - Step; Hoehe := 0; cangodown := false; end; end; ////////////////////////////////////////// // TIMER ////////////////////////////////////////// procedure TForm1.DXTimer1Timer(Sender: TObject; LagCount: Integer); begin DXInput1.Update; DXSpriteEngine1.Move(1); DxDraw1.Surface.Fill(0); DXDraw1.Surface.Draw(0, 0, FSurface.ClientRect, FSurface, TRUE); DXSpriteEngine1.Draw; if Jump then begin InJump := true; Animation.Y := Animation.Y - Step; inc(Hoehe); if Hoehe = 30 then Jump := false; end else begin if cangodown then begin Animation.Y := Animation.Y + Step; end else InJump := false; end; DXDraw1.Flip; end; ////////////////////////////////////////// // FORM KEY DOWN ////////////////////////////////////////// procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if (key = vk_up) and not InJump and (Hoehe <= 30) then begin Jump := true; InJump := true; end; if key = vk_down then begin if not Duck then Bild := Animation.Image.Name; Ducken(true); end; end; ////////////////////////////////////////// // FORM KEY UP ////////////////////////////////////////// procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin if key = vk_up then begin Jump := false; cangodown := true; end; if key = vk_down then Ducken(false); end; Dass man in der Luft bleibt, wenn man Pfeil-Hoch klickt, wird noch behoben. ;) |
Re: [DelphiX] Kollision
ja ist klar das die figur in der "Mauer" ferst hängt um das zu behben müste ein if x +1 > .... reichen in der collisions funktion dabei musst du halt ermitteln in welche richtung dein player läuft und dann if x + player.dir nehmen wobei player.dir einen wert von -1 und +1 haben solle.
ich hoffe du weißt wie ich das meine, wenn nicht:
Delphi-Quellcode:
du musst einfach nur einen fehlt vor bzw. zurück schauen :-D
if (X-1 < TGegenstand(Sprite).X - Step) then
begin X := X - Step; cangoright := false; end; if (X+1 > TGegenstand(Sprite).X + Step) then begin X := X + Step; cangoleft := false; end; |
Re: [DelphiX] Kollision
Danke Mimi!
Nur besteht das problem teilweise weiterhin, in der exe von oben ist es z.B. so, dass man durch die 2 aufeinandergestelten ästen durchlaufen kann, da sie Figur irgendwie im den Boden versinkt.... |
Re: [DelphiX] Kollision
ich habe eine collisions funktion vom delphiForum bekommen, evtl. hilft sie dir ja weiter:
Delphi-Quellcode:
musst du noch anpassen dann sollte es gehen.... aber du musst immer schauen ob sich das objekt hintern den objekten befindet oder vordem objekt *G*
function TDX.kollision(nr1,nr2,nr1x,nr1y,nr2x,nr2y, pat1,pat2:integer):boolean;
var ueberlapp_breite, ueberlapp_hoehe:integer; ueberlapp_nr1_x, ueberlapp_nr1_y, ueberlapp_nr2_x,ueberlapp_nr2_y:integer; x,y:integer; nr1_breite, nr2_breite, nr1_hoehe, nr2_hoehe:integer; farbenr1,farbenr2:tcolor; begin farbenr1:=clBlack; farbenr2:=clBlack; ueberlapp_nr1_x:=-1; ueberlapp_nr1_Y:=-1; ueberlapp_nr2_x:=-1; ueberlapp_nr2_Y:=-1; if (DXImageList1.Items[nr1].PatternWidth = 0 ) then begin nr1_breite := DXImageList1.Items[nr1].Width; nr1_hoehe := DXImageList1.Items[nr1].Height; end else begin nr1_breite := DXImageList1.Items[nr1].PatternWidth; nr1_hoehe := DXImageList1.Items[nr1].PatternHeight; end; if (DXImageList1.Items[nr2].PatternWidth = 0 ) then begin nr2_breite := DXImageList1.Items[nr2].Width; nr2_hoehe := DXImageList1.Items[nr2].Height; end else begin nr2_breite := DXImageList1.Items[nr2].PatternWidth; nr2_hoehe := DXImageList1.Items[nr2].PatternHeight; end; kollision := false; if nr1x < nr2x then ueberlapp_breite := (nr1x + nr1_breite) - (nr2x) else ueberlapp_breite := (nr2x + nr2_breite) - nr1x; if nr1_breite > nr2_breite then if ueberlapp_breite >= nr2_breite then ueberlapp_breite := nr2_breite; if nr1y < nr2y then ueberlapp_hoehe := (nr1y + nr1_hoehe) - (nr2y) else ueberlapp_hoehe := (nr2y + nr2_hoehe) - (nr1y); if nr1_hoehe > nr2_hoehe then if ueberlapp_hoehe > nr2_hoehe then ueberlapp_hoehe := nr2_hoehe; if (ueberlapp_breite > 0) and (ueberlapp_hoehe > 0) then begin if nr1_breite >= nr2_breite then begin if (nr2x+nr2_breite) >= (nr1x+nr1_breite) then begin ueberlapp_nr1_x := nr1_breite - ueberlapp_breite; ueberlapp_nr2_x := 0; end; if ((nr2x+nr2_breite) < (nr1x+nr1_breite)) and (nr2x >= nr1x)then begin ueberlapp_nr1_x := (nr2x-nr1x); ueberlapp_nr2_x := 0; end; if (nr2x) < (nr1x) then begin ueberlapp_nr1_x := 0; ueberlapp_nr2_x := nr2_breite - ueberlapp_breite; end; end; if nr1_breite < nr2_breite then begin if (nr1x+nr1_breite) >= (nr2x+nr2_breite) then begin ueberlapp_nr2_x := nr2_breite - ueberlapp_breite; ueberlapp_nr1_x := 0; end; if ((nr1x+nr1_breite) < (nr2x+nr2_breite)) and (nr1x >= nr2x)then begin ueberlapp_nr2_x := (nr1x-nr2x); ueberlapp_nr1_x := 0; end; if (nr1x < nr2x)then begin ueberlapp_nr2_x := 0; ueberlapp_nr1_x := nr1_breite - ueberlapp_breite; end; end; if nr1_hoehe >= nr2_hoehe then begin if (nr2y+nr2_hoehe) >= (nr1y+nr1_hoehe) then begin ueberlapp_nr1_y := nr1_hoehe - ueberlapp_hoehe; ueberlapp_nr2_y := 0; end; if ((nr2y+nr2_hoehe) < (nr1y+nr1_hoehe)) and (nr2y >= nr1y)then begin ueberlapp_nr1_y := (nr2y-nr1y); ueberlapp_nr2_y := 0; end; if (nr2y) < (nr1y) then begin ueberlapp_nr1_y := 0; ueberlapp_nr2_y := nr2_hoehe - ueberlapp_hoehe; end; end; if nr1_hoehe < nr2_hoehe then begin if (nr1y+nr1_hoehe) >= (nr2y+nr2_hoehe) then begin ueberlapp_nr2_y := nr2_hoehe - ueberlapp_hoehe; ueberlapp_nr1_y := 0; end; if ((nr1y+nr1_hoehe) < (nr2y+nr2_hoehe)) and (nr1y >= nr2y)then begin ueberlapp_nr2_y := (nr1y-nr2y); ueberlapp_nr1_y := 0; end; if (nr1y < nr2y)then begin ueberlapp_nr2_y := 0; ueberlapp_nr1_y := nr1_hoehe - ueberlapp_hoehe; end; end; for x := 0 to (ueberlapp_breite-1) div 4 do for y := 0 to (ueberlapp_hoehe -1)div 4 do begin if (pat1 = 0) and (DXImageList1.Items[nr1].PatternWidth = 0 ) then begin farbenr1:=DXImageList1.Items[nr1].picture.Bitmap.Canvas.Pixels[ueberlapp_nr1_x+x*4,ueberlapp_nr1_y+y*2]; end; if (pat2 = 0) and (DXImageList1.Items[nr2].PatternWidth = 0 )then begin farbenr2:=DXImageList1.Items[nr2].picture.Bitmap.Canvas.Pixels[ueberlapp_nr2_x+x*4,ueberlapp_nr2_y+y*2]; end; if (pat1 >= 0) and (DXImageList1.Items[nr1].PatternWidth > 0 ) then begin farbenr1:=DXImageList1.Items[nr1].PatternSurfaces[pat1].Canvas.Pixels[ueberlapp_nr1_x+x*4,ueberlapp_nr1_y+y*2]; end; if (pat2 >= 0) and (DXImageList1.Items[nr2].PatternWidth > 0 ) then begin farbenr2:=DXImageList1.Items[nr2].PatternSurfaces[pat2].Canvas.Pixels[ueberlapp_nr2_x+x*4,ueberlapp_nr2_y+y*2]; end; if ( farbenr1 <> DXImageList1.Items[nr1].TransparentColor) and (farbenr2 <> DXImageList1.Items[nr2].TransparentColor) then kollision := true; end; DXImageList1.Items[nr1].Restore; DXImageList1.Items[nr2].Restore; end; end; |
Re: [DelphiX] Kollision
Danke, das ist die, die ich im ersten Post erwähnt habe.
Welche Parameter werden denn da übergeben? |
Re: [DelphiX] Kollision
also wenn ich das noch richt weißt folgende:
kollision(1,2,x1,y1,x2,y2,0,0); 1 und 2 sind die objekte aus der DXImageList die Verlichenwerden sollen x1 und y1 und x2 und Y2 sind die objekte positionen und 0 und 0 ist der PatterIndex für beide objekte eine kleine bitte: sollts du diese funktion optimieren, könntes du sie mir dann auch nochmal senden ??? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:13 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