Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Welt bewegt sich um Spieler (https://www.delphipraxis.net/155751-welt-bewegt-sich-um-spieler.html)

RedShakal 6. Nov 2010 11:40

Welt bewegt sich um Spieler
 
Hallo, ich habe eine Frage. Ich möchte gern ein kleines Netzwerkspiel programmieren. Nichts besonderst tolles aber ich hatte vor kurzem die Idee und möchte mal schauen ob ich diese Umsetzen kann. Das Spiel soll so in der art wie die alten Pokemon Gameboy spiele werden. Ein Spieler läuft in der mitte, kämpft gegen Monster und sammelt Items ein. Dazu der Gedanke: Jedes Feld (ca. 25x25 Pixel) ein Schritt. Das Problem hierbei: Nicht der Spieler soll sich in der Welt bewegen, sondern die Welt soll sich um den Spieler bewegen. Da das Spiel aber zusätzlich auchnoch Netzwerk fähig werden soll brauche ich also zwingend Koordinaten. Ein Kumpel hat mir empfohlen ich soll die Weltkarte einfach zeichnen in Paint oderso die nicht begehbaren Punkte in einer Procedure markieren. Das ist aber schwachsinn. Wenn die Karte größer wird haben ältere Rechner enorme Ladezeiten. Ausserdem ist das viel zu aufwendig (Ich will mir später einen Map Editor schreiben). Ausserdem ist es unsinnig bei jedem Schritt eine Procedure durchzurattern die 50000 Koordinaten mit meiner vergleicht. Das frisst viel zu viel Rechenleistung. Ich hatte mir das so vorgestellt das die ich die Map Feldweise lade. Wenn ich einen Schritt nach oben mache, werden die Tiles (25x25) die in der untersten Reihe sind entladen, alle geladenen Tiles werden eins nach unten Versetzt und die obere Reihe wird geladen.

Ist das überhaupt so möglich? Gibt es bessere Methoden? Wie aufwendig wäre das?

Den Mapeditor habe ich mir so vorgestellt. Eine Map Datei enthält: 21(X Koordinate)|43(Y Koordinate)|1(Begehbar, nicht Begehbar, Teleporter)|0(Wenn Teleporter dann X)
|0 (Wenn Teleporter dann Y)|gras3(Textur)

Also das Schema so: 21|43|1|0|0|gras3@22|43|1|0|0|gras3

so in etwa hatte ich mir die Map dann vorgestellt.

Medium 6. Nov 2010 17:13

AW: Welt bewegt sich um Spieler
 
Wenn du die Map aus Tiles zusammen setzt, brauchst du doch gar nicht mehr die Nachladestrategie (welche prinzipiell natürlich möglich ist, und auch oft praktiziert wird). Die Map-Datei wird klein genug, um sie komplett zu laden. Wenn du ohnehin eine Map mit fester und rechteckiger Form hast, brauchst du auch die Koordinaten nicht zu speichern, wenn du sie quasi wie bei Bitmaps die Pixel einfach hintereinander weg schreibst. Noch schneller wird die Verarbeitung, wenn du kein Klartext-basiertes Format nimmst, dann fallen etliche Konvertierungen weg, und man spart in der Regel so 30-50% an Speicherplatz.
Die Tiles sollten ja auch alle recht handlich ausfallen, so dass diese auch locker am Stück ins RAM können, und dann eben immer nur den sichtbaren Bereich zeichnen.
Was die Kollision angeht: Wenn sich der Spieler immer in einzelnen Schritten fortbewegt, brauchst du im Grunde nur eine kleine Abbildung der 8 Felder um ihn herum, und musst pro Schritt nur maximal 8 Mal testen, wenn man es geschickt macht sogar nur ein Mal. Dafür macht es dann Sinn die Map in eine quasi 2D-Verkettete Liste zu packen, wo jeder Knoten jeweils einen Verweis auf seine 8 Nachbarn hat. Dann kann man da super komfortabel durchtraversieren.

Blup 8. Nov 2010 09:53

AW: Welt bewegt sich um Spieler
 
Dieser Mapeditor wird zwar nicht mehr weiter entwickelt, ist aber zumindest einen Blick wert:
http://www.mapeditor.de.vu/

fui-tak 11. Nov 2010 14:17

AW: Welt bewegt sich um Spieler
 
Ich würde das ganze ähnlich wie Medium beschrieben hat angehen, nur anstatt der speziellen Liste einfach ein Zweidimensionales Array nehmen, etwa so:
Delphi-Quellcode:
level: array of array of TFeldElement;
Ein Objekt des Typs FeldElement (oder wahlweise statt Klasse ein Record nehmen) beinhaltet, dann die einzelnen Eigenschaften

Hier mal mit einem Record:
Delphi-Quellcode:
TFeldElement = record
  teleporterXPos, teleporterYPos: integer;//speichert, wo hingesprungen werden soll
  inhalt: byte;//begehbar, nicht begehbar oder Teleporter
  textur: string;//den Namen der Textur
end;

Zeichnen würde ich dann irgendwie so:
Delphi-Quellcode:
   for i := 0 to high(level) do
     for k := 0 to high(level[0]) do
       case level[i,k].inhalt of
        1: ..... //begehbares Feld an der Position (i * Breite eines Feldes + xLevel/ k * Breite eines Feldes + yLevel)
        ...
       end;
xLevel und yLevel sind dann die Koordinaten des Levels.
Wenn du deine Figur bewegts, muss du dann beispielsweise beim nach unten gehen folgendes machen:
Delphi-Quellcode:
figur.yPos := figur.yPos + 25;//der Spieler wird nach unten verschoben
yLevel := yLevel - 25; //das Level wird nach oben verschoben
Insgesamt hat sich nun also deine Karte nach oben gescrollt und deine Figur ist immer noch in der Mitte des Bildschirms

s.h.a.r.k 11. Nov 2010 14:28

AW: Welt bewegt sich um Spieler
 
Such hier im Forum mal nach Andorra. Ich glaube, das dürfte etwas für dich sein.

Memnarch 11. Nov 2010 16:09

AW: Welt bewegt sich um Spieler
 
Fui-Tak's Methode ist schon ganz gut, Aber ich würde zb anstatt Texturname, ne ID verwenden oder direkt XY koordinaten für die Tile, da es bei Tilefgames für gewöhnlich gebräuchlich ist, eine Datei zu haben, in der alle für den/das Level benötigten statischen grafiken sind.

Hinzu kommt noch, dass es vielleicht praktischer wäre, anstatt die map zu scrollen, eine neue Komponennte abzuleiten.

z.B. von TImage(nehm ich immer fürs zeichnen :P).
Die nennst du VIEW, und die besitzt auch gleichzeitig die zwei neuen Attribute Pos_X/Pos_Y.
Alle Views werden in einer Liste gespeichert.

Dann bastellst du dir eine Render routine. Dieser Routine wird der View übergeben(also pro zyklus ein aufruf pro View in der liste). Die routine zeichnet dann in Abhängigkeit der View Attribute Pos_X/Pos_Y die Map und deren Objekte auf den Übergebenen View. Das gibt dir z.B. automatisch die Möglichkeit Splitscreens zu erstellen(vielleicht brauchst dus jetzt nicht, aber mal nen denkanstoss).
Anhand der View Position und der Größe der View in Pixeln kannst du mithilfe der Tile größe ersteinmal unter anderem bestimmen, wieviele Tiles überhaupt in den View passen UND darauf einfach die angegebenen tiles um die Viewposition zum rendern abfragen und Somit jedemenge rechenleistung sparen.

Dank des 2d Arrays aus dem die Map erstellt wurde, sind auch automatisch die nachbarfelder bekannt, was das suchen nach Soliden blöcken unter anderem für Kollision erleichtert.

Gleichzeitig sollte deine Map nocheinmal in grobe regionen unterteilt werden(z.B. 32*32 Tiles, jenachdem wie gross ein tile ist). Wenn ein Objekt erstellt wird(item oder sonstiges dass sich zur laufzeit ändert, also auch spielerfigur) Wird es anhand seiner Position in die Region eingeordnet(jede region hat zb ne liste mit den beinhaltenden objekten), so ist es leichter und performanter nach dynamischen beweglichen objekten zu suchen, um events oder kollision auszulösen)
Verlässt ein Objekt seine aktuelle region, muss es selbstverständlich in die neue eingeordnet und aus der alten entfernt werden.

Und jetzt habe ich wieder von allem und nichts erzählt :lol:

Also wiegesagt, das obrige sind nocheinmal ein paar techniken die es dir vereinfachen sollten das Spiel zu verwalten, und somit sogar ne kleine enginen Bilden(DAs obige sind zb Strukturen die ich nutze wenn ich 2d/ 2dTileengines Schreibe)


MFG
Memnarch

RedShakal 15. Nov 2010 18:53

AW: Welt bewegt sich um Spieler
 
Das heißt wenn ich deine Methode richtig verstehe, erstelle ich mir die entsprechenden Map files und muss dann über den Record nurnoch das entsprechende Feld mit den angegebenen X Y Koordinaten aus der Map Datei laden? Oder habe ich das falsch verstanden?

Memnarch 15. Nov 2010 20:12

AW: Welt bewegt sich um Spieler
 
Liste der Anhänge anzeigen (Anzahl: 1)
So ungefähr.
Gehen wir davon aus du hast wie gesagt eine 2DPosition(camera genannt).

Die position ist direkt in PIxel angegeben.

Wenn du jetzt Tiles von 32p größe hast, teilst du die Position der camera durch 32, und bekommst so die position der camera auf dem tilegrid.


Danach renderst du die Tiles die sich in einem definierten Radius um die Camera befinden, der rest is ja eh nicht sichtbar ;)

Hiernochmal nen Schaubild:

Anhang 32584

Das schwarze gitter stellt deine gesammte Map dar. Der blaue punkt die momentane Position der Camera in PIXELN. Teils du dass durch die größe der Tiles, bekommst du die Tile Position der Camera. Von dort aus renderst du nur die tiles die auch sichtbar wären(der rote rahmen zeigt den Bildschirm, alles was außerhalb ist muss nicht gezeichnet werden)

DU lädst also ALLES(von einer welt), zeigst aber nur was dur brauchst ;)

RedShakal 15. Nov 2010 21:25

AW: Welt bewegt sich um Spieler
 
Das führt mich dann aber wieder zu dem Problem das ich die gesamte Map mit einem Schlag laden müsste was bei kleinen Maps Problemlos funktioniert, bei größeren Maps später aber nichtmehr unbedingt so vorteilhaft. Gerade bei älteren Rechnern würde die Ladezeit hochschießen. Oder irre ich mich da?

mkinzler 15. Nov 2010 21:29

AW: Welt bewegt sich um Spieler
 
Ein derrtiges Level sollte eigentlich nicht allzuviel Speicher belegen

http://sourceforge.net/projects/jedi-isoax/
http://code.google.com/p/delphi-dire...tric-2dmmorpg/


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:45 Uhr.
Seite 1 von 2  1 2      

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