Grober Leitfaden durch den Code:
Bei Bedarf gebe ich gerne noch den Code zum dazugehörigen MapEditor,
evtl muss dort jedoch der Pfad, inwelchen die map 2Darrays gespeichert werden,
auf windows spezifische Pfade geändert werden da ich unter mac entwickle.
zur Android app:
meine App strukturiert sich im package android.railwanderer.mapwindowtest wie folgt:
game framework:
/generics
/implementation
/interfaces
meine Codes:
Assets (Klasse)
LoadingScreen(Klasse)
MainActivity (Klasse und MainActivity)
MainMenueScreen(Klasse)
/TopDownTile
/PlayerStuff
das gameframework habe ich aus dem buch, ich habe es fast komplett übernommen,
aber bin es Zeile für Zeile mit Haufen text im buch durchgegangen. Lediglich
kleine Veränderungen habe ich vorgenommen, z.b eine beenden Funktion implementiert,
oder die scaled bitmap draw function verändert, um mit anderen filtern zu scalieren.
Es arbeitet wie folgt:
im ordnet /interfaces wird ein grober plan festgelegt, was das spiel braucht
die interfaces werden dann durch die Klassen
im ordner /implementation
für android implementiert. der Vorteil ist dass man später weniger aufwand
beim Porten für reine desktop Anwendungen haben soll, da man einfach die
jeweiligen Interfaces für die Nutzung als java Applikation schreibt.
im ordner /generics habe ich die pool klasse abgelegt, da ich diese <> liste
noch nicht 10000% verstanden habe

eigl. gehört sie zur implementation unter
android, da sie mit der AndroidInput Klasse zu tun hat. Es geht hier um die wiederbenutzung der Input events um Garbage Collector Probleme zu vermeiden.
Im Buch ist das alles sehr ausführlich erläutert.
In der Klasse AndroidGame
läuft dann alles zusammen, es wird ein FrameBuffer erstellt, bei mir eben 608/416 festgelegt, da das mit der Anzahl an angezeigten Tiles auf dem Screen
gut passt. Auf diesen FrameBuffer wird dann gezeichnet und das Bild hochskaliert. Das zeichnen u skalieren passiert in der Klasse FastRenderView.
Diese View wird gesetzt sobald der Constructor der AndroidGameKlasse abschliesst.
In dieser FastRenderView läuft der Gameloop.
game.getCurrentScreen().update(deltaTime);
game.getCurrentScreen().present(deltaTime);
das AndroidGame (Klasseninstanz) gibt bei getCurrentScreen() den screen zurück,
da dieser im Constructor durch getStartScreen() zugewiesen wurde.
die methode getStartScreen() ist jedoch nur im Interface deklariert.
Daher wird diese in der MainActivity meiner App überschrieben. Das ist neben Settingsladen
auch das einzige was in die MainActivity geschrieben wird. Somit kann das
Framework schnell übernommen werden.
in der MainActivity wird in der getStartScreen Methode ein new LoadingScreen zurück gegeben, und der GameLoop läuft.
Dabei werden eben getcurrentScreen.update() und .present() aufgerufen.
diese Methoden beschreibe ich dann in meinen ScreenKlassen.
Die anderen Klassen des Gameframeworks bieten eben Funktionen um auf
den Canvas zu zeichnen, Input events abzufragen etc.
Bisher hin ist alles sehr professionell gelöst, und schön geordnet bzw getrennt.
Und hier, im LoadingScreen fängt nun mein Part an, alles ausserhalb der 3 gameframework packages ist mein code:
im loadingscreen werden in der update Methode, die nur einmal durchgegangen wird, alle bilder etc geladen. die present Methode zeigt eigl ein logo auf schwarzem
hintergrund an aber es geht so schnell die Bilder zu laden, dass man es nicht wirklich sieht.
chaotischerweise wird in der present Methode der Screen auf einen anderen (Mainmenü) gesetzt sobald die update Methode alle assets geladen hat....fällt mir grad auf, gehört wohl auch eher in die update Methode.
danach gehts im MainMenueScreen weiter.
in der update methode check ich nur nach Input events, schalte sound off wenn
der sound button geklickt wird, ansonsten lade ich die MaplayerViews (mapLayer)
und Zeichne dabei den LadeBalken. Im thread stelle ich fest ob alles geladen wurde (GameScreen) und wenn ja ist die run Methode fertig und ich
jump in die GameScreen Klasse ( /topDownTile).
Diese GameScreenKlasse hat einen MapHandler, der die 40 Mapstücke der Insel lädt (im Constructor). Dieser ruft den Maploader auf
und in der lademethode dort Steigere ich den Ladebalken, dass man sieht wie weit er ist.
es sind also nicht die Bilder die lange vorladen müssen aber meine Maps,
die 10 Layer pro Map haben, und 20x20 tiles pro layer
dort im gamescreen wird nun die spielwelt gezeichnet u geupdated, je nach State.
Sie ruft den MapHandler auf (/TileStuff).
dieser wiederum hat die 40 geladenen Maps und eine welche die aktuelle ist,
auf der sich der Spieler befindet.
Diese wird je nach state gezeichnet:
StateRunning = rumlaufen
StateBackground = Insel karten ansicht.
die einzelnen Maps sind MapBoundle Instanzen, und bestehen aus der Map-Klasse
der unteresten Ebene Bilder, und der LayerMap Klasse,
welche die 10 Layer darüber bilden, also bäume, Felsen etc etc
Die Namensgebung (Map für eine Schicht der map) ist unglücklich gewählt,
so ne Sache wie viele die ich ändern muss
die Map- und LayerMaps- haben jeweils eine MapView oder 10 LayerViews.
in dieser wird abhängig v Spieler gecheckt, welche ausschnitte des [][]Tileobjects
Layer gezeigt werden müssen, da das Sichtfeld ja nur einen ausschnitt der aktuellen karte zeigen kann (17?,8?)
Dazu wird geschaut wo der Spieler ist, und der Offset berechnet, den die karte braucht
um auf dem Bildschirm zu bleiben

denn bewegt sich der Spieler bewegt sich die karte,
zumindest bis zu gewissen rändern, an denen dann diese CenterX u CenterY Variablen (Mittelpunkt des Ausschnittes, wo der Spieler läuft) "festgesetzt" werden, damit die karte zb bündig mit dem linken bildschirmrand stehen bleibt.
sobald der spieler in diese ecke geht kann er sich frei bewegen.
Ansonsten würde sich die kartenecke zum mittelpunkt des Bildschirms verschieben.
die verschiedenen layer können das tileobject zeichnen, oder später zeichnen lassen,
damit ich gewisse Sachen je nach position des Spielers über ihn zeichnen kann.
um sich die tiles anzuschauen muss man die klasse tiles öffnen und tilesobject, welche von tiles erbt.
in tiles ist die Beschreibung für jedes tile, je nachdem welches layersheet (int)
der layer hat, wird ein gewisses bild ausgesucht, allerdings muss ich das auch mit
weniger code hinbekommen können...es ist dort noch sehr chaotisch da alte
Sachen noch halb mit drin hängen. aber wenn man sich im kopf behält das die
layer 2d Arrays aus tiles oder tileobject Instanzen haben welche je nach übergebenen
layersheet gewisse Eigenschaften haben, und diese zeichnen lassen,
kann man verstehen wie mein tilemap engine versuch funktioniert
Grassground und layer 1-8 sind die benutzen tileobjects, testlayer ist nur da
um meinen apath versuch zeichnen zu lassen.
im ordner GUIs sind die Elemente wie steuerkreutz minimap hotkeys etc gehandelt.
/MapCodes/MapProperties/ kann eigl ignoriert werden, das stammt noch aus der zeit vor dem Mapeditior,
und ist dummerweise noch teils verflochten ( die layersheets als int) was ich wie gesagt
noch bereinigen muss, damit ich meine Layersheets auch austauschen kann.
Die ganze Sache wie die Tiles die layersheets zugeordnet bekommen macht
mich noch nicht so glücklich

schön wär es natürlich noch den mapeditor ein stück zu erweitern,
dass er bilder öffnen kann und diese als bytearray? speichert und die app das wie die tilecodes lädt.
dazu fehlt mir aber das wissen um Grundlagen wie buttons, popup windows, filepaths öffnen unter java.
ich könnte es über das Terminal hardcoden aber naja nicht das wahre

...kommt noch alles.
auch eine option ein tile im mapeditor gleich die Eigenschaften (toptile etc) zuzuweisen...
oder eine ingame cosonsole zum späteren ordentlichen testen.
zur zeit kann man "cheaten" bzw sich an einen begehbaren ort bringen falls es buggt, wenn man
auf dem handy den eigenedateien ordnet öffnet und gamnom.txt modifiziert.
ist leicht rauszulesen was x und y ist
das war jetzt mal eine grober überblick und ausschnitt aber erstmal das grundgerüst dass man ein bissl
versteht.
andere Sachen wie Sprites, etc sind dann schon wieder neue Spielereien, die auch nur funktionieren aber
noch nicht weiter verbessert wurden, bzw effizient geschrieben sind
