![]() |
Collisionserknnung:problem
Hallo,
ich habe lauter rechtecke und möchte nun wissen ob mein player(auch ein rechteck) mit einem obj zuammen gestoßen ist oder nicht. eigetnlich ganzs einfach, problem ist dabei folgendes: ich habe meine karte auf der sind jetzt z.b. folgende objekte eingetragen: x: 50 y: 285 w: 20 h: 90 PX:=20 py:=305 pw:=20 ph:=20; der player macht jetzt immer 20 schritte nach lingx oder rechts. ich dachte mir jetzt das ich einfach wenn es zu einer collision kommt die entfernung messe(x) und dann vergleiche(mit den player werten) das funktioniert auch soweit nur wenn ich jetzt das obj verschiebe z.b. um paar pixl nach oben so das unter dem objekt der player duchgehen kann gehts nicht mehr. die objekte sind so angeordnet:
Code:
p = player
p -----
---------------------- die lange line ist ein obj un die kleine auch und um die geht es auch die haben im moment alle die gleiche höhe. meine funktionen sehen so aus:
Delphi-Quellcode:
function TGame.GetPlayerDir(x,y,x1,y1:Integer):Integer;
begin if obj.player.x <= x then result:=isLings else if obj.player.x >= x1 then result:=isRechts; end; function TGame.GetObj(x,y:Integer):TOBJTyp; var i,dir:Integer; begin for i:=0 to HIGH(OBJ.Walls) do begin if (x >= OBJ.Walls[i].x ) and (y >=OBJ.Walls[i].y) and ( x<=OBJ.Walls[i].x+ OBJ.Walls[i].w) and (y <=OBJ.Walls[i].y+ OBJ.Walls[i].h) then begin dir:=GetPlayerDir(OBJ.Walls[i].x,OBJ.Walls[i].y,OBJ.Walls[i].x+OBJ.Walls[i].w,OBJ.Walls[i].y+OBJ.Walls[i].h); result.index:=i; result.typ:=OBJ.Walls[i].typ; result.f:=True; if dir = isLings then result.e:=OBJ.Walls[i].x-(obj.player.x+obj.player.w); if dir = isRechts then result.e:=obj.player.x-(OBJ.Walls[i].x+OBJ.Walls[i].w); exit; end; end; for i:=0 to HIGH(OBJ.MoveWalls) do begin if (x >= OBJ.MoveWalls[i].x ) and (y >=OBJ.MoveWalls[i].y) and (x <=OBJ.MoveWalls[i].x+ OBJ.MoveWalls[i].w) and (y <=OBJ.MoveWalls[i].y+ OBJ.MoveWalls[i].h) then begin result.index:=i; result.typ:=OBJ.MoveWalls[i].typ; result.f:=True; exit; end; end; if (x >= OBJ.player.x ) and (y >=OBJ.player.y) and (x <=OBJ.player.x+ OBJ.player.w) and (y <=OBJ.player.y+ OBJ.player.w) then begin result.index:=0; result.typ:=player; result.f:=False; exit; end; result.index:=None; result.typ:=None; result.f:=False; result.e:=None; end; // KeyDown: if KEYS[VK_LEFT] = True then begin // Lings ist kein obj o:=GetObj(px-20,obj.player.y); if o.typ <> MovePlatte then begin if o.f = False then px:=px-20 else if (GetObj(px+o.e,obj.player.y).f = False) and (o.e <= 20) and (o.e > 0) then px:=px-o.e; end else px:=px-20; end; if KEYS[VK_Right] = True then begin // Rechts ist kein obj o:=GetObj(px+40,obj.player.y); if o.typ <> MovePlatte then begin if o.f = False then px:=px+20 else if (GetObj(px+o.e,obj.player.y).f = False) and (o.e <= 20) and (o.e > 0) then px:=px+o.e; end else px:=px+20; end; if v = True then begin if (obj.player.isLeiter = True) and (GetObj(px,obj.player.y+20).typ = wall) then begin obj.player.x:=obj.player.x+px; obj.player.isNoLeiter:=True end; if obj.player.isLeiter = False then begin obj.player.x:=px; end; end; |
Re: Collisionserknnung:problem
[OT]
Zitat:
Also das ist wirklich eine der schlimmsten Entstellungen der deutschen Sprache die ich je gesehen habe. :? [/OT] |
Re: Collisionserknnung:problem
Zitat:
Er kann nix dafür, er hat ne Rechtschreibschwäche hab ich mal gelesen. |
Re: Collisionserknnung:problem
Delphi-Quellcode:
function RectinRect(rect1,rect2: Trect): boolean;
begin result := true; if (rect1.Left > rect2.BottomRight.x) then result:=false; if (rect1.top > rect2.BottomRight.y) then result:=false; if (rect2.Left > rect1.BottomRight.x) then result:=false; if (rect2.top > rect1.BottomRight.y) then result:=false; end; |
Re: Collisionserknnung:problem
mache ich doch(so änlich) auch so bei mir
|
Re: Collisionserknnung:problem
ich habe die ursache gefunden für das problem leider doch nicht die lösung :(
und zwar: ich speicher das objekt was unter dem player ist in einem recrod vom typ TObTyp(eigner). und ich durchlaufe ja in der collisions funktion alle array und sobalt ich eins(ein objekt) gefunden habe höhrt er ja auf zu suchen bzw. meldet collision also habe ich folgende funktion geschrieben:
Delphi-Quellcode:
Ich glaube das diese funktion in diesr forum auch funktioneirt doch leider verwendet ich sie warscheinlich falsch:
function TGame.GetObj(x,y,w,h:Integer):TOBJTyp;
var i,dir:Integer; o:TOBJTyp; temp,r1,r2:TRect; begin o.index:=None; o.typ:=None; o.f:=False; o.xe:=None; for i:=0 to HIGH(OBJ.Walls) do begin r1.Left:=x; r1.Top:=y; r1.Bottom:=y+h; r1.Right:=x+w; r2.left:=OBJ.Walls[i].x; r2.top:=OBJ.Walls[i].y; r2.Bottom:=OBJ.Walls[i].y+OBJ.Walls[i].h; r2.Right:=OBJ.Walls[i].x+OBJ.Walls[i].w; if IntersectRect(temp,r1,r2) = True then begin dir:=GetPlayerDir(OBJ.Walls[i].x,OBJ.Walls[i].y,OBJ.Walls[i].x+OBJ.Walls[i].w,OBJ.Walls[i].y+OBJ.Walls[i].h); o.index:=i; o.typ:=wall; o.f:=True; if dir = Lings then begin o.xe:=OBJ.Walls[i].x-(obj.player.x+obj.player.w); end; if dir = Rechts then begin o.xe:=obj.player.x-(OBJ.Walls[i].x+OBJ.Walls[i].w); end; o.ye:=OBJ.Walls[i].y-obj.player.y; end; end; for i:=0 to HIGH(OBJ.MoveWalls) do begin r1.Left:=x; r1.Top:=y; r1.Bottom:=y+h; r1.Right:=x+w; r2.left:=OBJ.MoveWalls[i].x; r2.top:=OBJ.MoveWalls[i].y; r2.Bottom:=OBJ.MoveWalls[i].y+OBJ.MoveWalls[i].h; r2.Right:=OBJ.MoveWalls[i].x+OBJ.MoveWalls[i].w; if IntersectRect(temp,r1,r2) = True then begin dir:=GetPlayerDir(OBJ.MoveWalls[i].x,OBJ.MoveWalls[i].y,OBJ.MoveWalls[i].x+OBJ.MoveWalls[i].w,OBJ.MoveWalls[i].y+OBJ.MoveWalls[i].h); o.index:=i; o.typ:=MovePlatte; o.f:=True; if dir = Lings then begin o.xe:=(obj.player.x+obj.player.w)-OBJ.MoveWalls[i].x; end; if dir = Rechts then begin o.xe:=(OBJ.MoveWalls[i].x+OBJ.MoveWalls[i].w)-obj.player.x; end; o.ye:=OBJ.MoveWalls[i].y-obj.player.y end; end; result:=o; end;
Delphi-Quellcode:
die var px ist nur ein tempe variable sie wird später zu gewiesen.
py:=obj.player.y;
px:=obj.player.x; if KEYS[VK_LEFT] = True then begin // Lings ist kein obj o:=GetObj(px+20,obj.player.y+20,20,20); if (o.typ = MovePlatte) or(o.f = False) or ((o.index = obj.player.UnderObj.index) and (obj.player.UnderObj.typ = Wall)) then px:=px-20 end; if KEYS[VK_Right] = True then begin // Rechts ist kein obj o:=GetObj(px+20,obj.player.y,20,20); if ((o.typ = none) and (o.f = False)) and ((o.index = obj.player.UnderObj.index) or (o.index = obj.player.UnderObj.index) and (obj.player.UnderObj.typ = Wall)) then px:=px+20; end; ich möchte einfach das man nur nach linx und rechts gehen kann und wenn dort eine collsions ist sollst nicht weiter gehen ich du kannst auch runter fallen:
Delphi-Quellcode:
das hat auch noch leider problme(gehört aber zur gleichen frage)
obj.player.UnderObj:=GetObj(obj.player.X, obj.player.y,20,20+1);
if obj.player.isLeiter = FALSE then begin if (obj.player.UnderObj.ye > 1) or (obj.player.UnderObj.f = False) then begin if obj.player.FTime >= obj.player.FTimeCount then begin obj.player.FTime:=0; obj.player.y:=obj.player.y+1; end else inc(obj.player.FTime); end; end; |
Re: Collisionserknnung:problem
*nach oben verschieben*G*)
|
Re: Collisionserknnung:problem
Liste der Anhänge anzeigen (Anzahl: 1)
ich habe eine lösung für das problem gefunden weiß aber nicht genau wie ich sie umsetzen soll mein erster versuch ist fehlgeschlagen und ich weiß einfach nicht weiter(hier ist mal mein erster versuch:
Delphi-Quellcode:
die lösung liegt darin die seite zu finden mit den angeben werten(x,y,w,h) welche mit einem andren objekt colldiert(wißt ihr was ich meine?)
function TGame.GetObj(x,y,w,h,s:Integer):TObjTyp;
var i:Integer; begin for i:=0 to High(obj.walls) do begin // für Lings if (x-s <= obj.walls[i].x+obj.walls[i].w) and (obj.walls[i].x >= x) and (y <= obj.walls[i].y+obj.walls[i].h) then begin result.Typ:=Wall; result.index:=i; result.f:=True; break; end; end; end; da mein spiel aus lauter Vieecken aufgebaut ist wollte ich das jetzt so lösen: ich schreibe mir eine funktion die ich mit einem vieeck aufrufe und die schritte die gegangen werden soll. Diese Funktion prüft in einer for schleife welche seite vom angeben vieeck mit einem andren objek zusammen stößt denn in meinem Spiel kann das player obj von allen seiten zusammen stöße bekommen und das ist die lösung(würde ich sagen) im anhang ist ein beispiel bild. Das blaue Vieeck ist der player. wie zu sehen ist sind die seiten Lings und Unten blegt und rechts und oben ist frei. ich hoffe ihr versteht was ich meine..... |
Re: Collisionserknnung:problem
Ich habe in der letzten Woche eine funktion geschrieben die soll mir dises seiten zurückgeben doch leider funktioniert sie nur in meinem test projekt aber nicht in meinem eigentlichen projekt.
so sieht die funktion aus:
Delphi-Quellcode:
das ziel dieser funktion ist es herrauszufinden welche seite zusammenstößt mit den angeben position angaben(x,y,w,h,s)
for i:=0 to High(obj.walls) do begin
// Rechts if (x+w+s > obj.walls[i].x) and (y > obj.walls[i].y) and (x+w+s < obj.walls[i].x+obj.walls[i].w) and (y < obj.walls[i].y+obj.walls[i].h) then result.WRechts:=True; // Lings if (x-s > obj.walls[i].x) and (y > obj.walls[i].y) and (x-s < obj.walls[i].x+obj.walls[i].w) and (y < obj.walls[i].y+obj.walls[i].h) then result.WLings:=True; // Unten if (x > obj.walls[i].x) and (y+h+1 >obj.walls[i].y) and(x < obj.walls[i].x+obj.walls[i].w) and (y+h+1< obj.walls[i].y+obj.walls[i].h) then result.WUnten:=True; // Oben if (x > obj.walls[i].x) and (y > obj.walls[i].y) and(x < obj.walls[i].x+obj.walls[i].w) and (y<obj.walls[i].y+obj.walls[i].h ) then result.WOben:=True end; doch leider gibt sie mir immer nur unten als seite raus aber nicht lings bzw. rechts..... ich finde einfach keine lösung für das problem..... |
Re: Collisionserknnung:problem
Hast du Result auch initialisiert? Wäre meine Vermutung, da es ja nur ein Codeschnippsel ist.
Delphi-Quellcode:
function ...
begin Result.Wlinks:=false; Result.WRechts:=false; Result.WOben:=false; Result.WUnten:=false; ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:04 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz