PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ATF: "Wände" in 2D



YoshiGreen
15.01.2005, 19:55
ATF steht fürt "allgemeine theoretische Frage" und soll heißen, dass dies eine Frage ist, die sich nicht auf eine spezielle Programmiersprache bezieht, sondenr für jeden interessant sein kann!

Zur Frage: Wie programmiert man in einer 2D Welt "Wände", sprich Stellen, die das Heroevent nicht betreten kann. Stellt euch die Grafik vom RPG-Maker vor. Ich habe mir schon Gedanken gemacht, kam aber auf kein vernünftiges Ergebnis!

MuadDib
15.01.2005, 20:04
Nun, du wirst deine Welt wohl in Kacheln organisieren. Also hübsch Feld für Feld. Das kannst du prima in einem Array speichern. Dieses Array hat nun verschiedene Werte, nehmen wir 0 für begehbaren Grund, 1 für "Wände". Dein "HeroEvent" hat immer eine aktuelle Position. Bei jeder Eingabe ändert sich die Position deines Helden. Bevor er allerdings die Position ändert, überprüfst du, ob dein Held im Array nun auf einer 1 wäre.

Grobes Beispiel:



int gamefield[][] = {{0, 0, 1},
{0, 0, 1},
{0, 0, 1}};
int hero_pos_x = 0;
int hero_pos_y = 0;


Das wäre also ein 9-Feld großes Spielfeld, mit einer Wand rechts. Der Held ist in der linken oberen Ecke. Angenommen der Benutzer drückt nach links, so wird überprüft, ob gamefield[x+1][y] 0 bzw. 1 wäre. Je nach Ergebnis darf nun der Spieler vorrücken... uhm, klar soweit?

Jesus_666
17.01.2005, 17:35
Es hängt stark davon ab, wie die Welt organisiert ist - wenn du bei der Bewegung fest mit Kacheln arbeitest (wie der Maker) kannst du MuadDibs Technik benutzen. Wenn sich der Spieler aber freier bewegen kann (wie beispielsweise in Secret of Mana), so wirst du schon komplexer arbeiten müssen... Wahrscheinlich mit einer Kollisionsabfrage.

BTW, ich hätte das, was MuadDib vorgeschlagen hat, wohl anders gelöst; bei mir wäre jedes Feld ein Objekt, das eine Variable bUnpassierbar hat, die angibt, ob man durch kann oder nicht. Die Überprüfung wäre also:

// Held läuft nach rechts
if (Kachel[Hero.x][Hero.y + 1].bUnpassierbar != true) Hero.move_xy(0,1);Ob meine oder MuadDibs Art besser paßt hängt davon ab, wie objektorientiert man programmiert.

Rolus
17.01.2005, 18:25
Wenn sich der Spieler aber freier bewegen kann (wie beispielsweise in Secret of Mana), so wirst du schon komplexer arbeiten müssen... Wahrscheinlich mit einer Kollisionsabfrage.

Gibt's dazu vielleicht auch ein kleines, rein theoretisches Beispiel, um das Prinzip zu erkennen? Oder ist das zu komplex, um es in einigen Zeilen zu demonstrieren. Müsste man die Abfrage dann nach Pixeln machen (um eine möglichst genaue Kollisionserkennung zu erreichen) oder wie?
freundliche Grüße, Rolus

Jesus_666
17.01.2005, 19:24
Das kommt auf die Art der Kollisionsabfrage an; du kannst auch mit Kollisionsboxen arbeiten. Allerdings ist Kollisionsabfrage wirklich etwas zu aufwendig, um es hier zu erläutern.

Allenfalls den einfachsten Fall könnte ich vorstellen: Du willst prüfen, ob zwei Sprites miteinander kollidieren; dabei wird nicht pixelweise sondern kastenweise gearbeitet; beide Sprites sind also, was die Kollisionsabfrage angeht, Rechtecke.
Des Weiteren enthalten die Variablen, die die Position der Sprites speichern, die Position des jeweiligen oberen linken Pixels (das muß nicht so sein; ich definiere das hier mal so); sie heißen Sprite*.PosX und Sprite*.PosY (Das * steht dabei für 1 oder 2). Die Höhe und Breite der beiden Sprites gebe ich mit Sprite*.Höhe, bzw. Sprite*.Breite an.
Dann prüft man einfach, ob folgendes zutrifft:
((Sprite1.PosX + Sprite1.Breite >= Sprite2.PosX) UND (Sprite1.PosX < Sprite2.PosX + Sprite2.Breite)) UND
((Sprite1.PosY + Sprite1.Höhe >= Sprite2.PosY) UND (Sprite1.PosY < Sprite2.PosY + Sprite2.Höhe))

Rolus
17.01.2005, 21:44
Okay, danke.
Das hat mir das schon etwas klarer gemacht, aber ich denke ich informiere mich nochmal über andere Möglichkeiten, wenn ich sowas mal brauchen sollte. Aber eine Frage noch: Ich kann mir sowas irgendwie nur so richtig für Rechtecke, wie in deinem Beispiel, vorstellen. Werden komplexere Formen also bei genaueren "kollisionsboxenbasierten" Kollisionsabfragen denn in kleine Rechtecke unterteilt? Also ne Pixel-Abfrage kann ich mir bei unförmigen Gegenständen (z.B. nem Tier) garnicht vorstellen. Nagut wenn's dann 3D ist, wird einem sowas wohl von DirectX oder OpenGL o.ä. vereinfacht und man macht das ganze auf Vertex-Basis, nehme ich an. Aber 'n Haufen Arbeit ist es imho trotzdem. Ich glaube, ich bleibe erstmal bei einfacheren Dingen, wie Minesweaper ;)
freundliche Grüße, Rolus

Jesus_666
17.01.2005, 21:57
Um ehrlich zu sein habe ich nicht die geringste Ahnung, da ich mich mit Grafikprogrammierung noch praktisch gar nicht befaßt habe.

regnad
18.01.2005, 15:58
Bei pixelgenauer Kollisionsabfrage im 2D-Bereich arbeitet man am besten mit Bitmasken, 0 für durchlässig und 1 für undurchlässig. Für jeden Kacheltyp und für jeden Spritetyp hat man dann eine Bitmaske die man gegenseitig ANDen kann, geht schnell, einfach und ist genau.

Jesus_666
18.01.2005, 16:59
Hmm, stimmt. Mal wieder eine dieser einfachen Ideen, die einem erst mal kommen müssen...