PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 2D Tile Game [Hobbyprojekt]



Cystasy
05.12.2015, 16:21
Hey,
Heute möchte ich euch einmal zeigen was ich derzeit so Nebenbei mit Javascript werkle.
Ziel ist es, ein eigenes Spiel zu erstellen das sich dann vom Grafikstyle an Spiele wie Pokemon,
Harvest Moon - Friends of Mineral Town, Zelda & co. orientiert.

Ich nutze für das ganze eine Art "Engine" die ich selbst entwickle - diese "Engine" habe ich "Cygine" genannt :rolleyes:
Diese Engine ist sogesehen eine Struktur die verschiedene Kernelemente enthält, die dann dafür
sorgen das man darauf aufbauend ein Spiel bauen kann.

Ein paar Kernelemente der "Cygine"

- core.js (Haupt-Element)
Die core.js ist sogesehen das, was alles zusammen hält.. quasi das, was ich "Cygine" getauft habe.
Über diese File lassen sich alle Komponenten von Cygine ansprechen (Beispiel: Cygine.TBox(), Cygine.Debug(), Cygine.state, Cygine.Map, etc).

- init.js (Initialisiert & Läd alles)
Läd die benötigten Files und Initialisiert die einzelnen Funktionen damit man auf sie Zugriff hat.
Pro: Weitere Elemente leicht einbindbar (per Js File & Init Function) -> Modding & co. ist dadurch leicht möglich

- map_proc.js ("Map Engine")
Sorgt dafür das man Maps (eigenes Dateiformat, extra für Cygine erdacht) in die Engine laden kann.
Zusätzlich rendert die Map Engine auch gleichzeitig die Map (bzw stellt Funktionen dafür bereit).Die Maps sind in Tiles aufgebaut, die aus dem jeweiligen Tileset (im Map Ordner) der Map zusammengesetzt werden.

- key_proc.js (Keyboard Processing)
Verarbeitet alles was mit der Steuerung des Games zu tun hat.. Tastaturanschläge werden hier
registriert & in die richtigen Aktionen umgesetzt.

- textboxes.js (RPG Maker ähnliche Textboxen)
Stellt Funktionen bereit um Textboxen und Dialoge im Spiel anzeigen zu können.
Pausiert während dessen den Render-Prozess der restlichen Elemente (Map, Animationen).

- object_proc.js (Object Processing)
Auf der Map können Events & Objekte plaziert werden, die dann durch die Spielfigur getriggert werden können.
Diese einzelnen Events und Objekte werden von diesem Kernelement verarbeitet.

Die Art der Events und Objekte sind folgende (nur ein paar aufgezählt):
- Teleporter (Betreten von neuen Maps um in Häuser oder Höhlen rein und rausgehen zu können)
- Textboxen (Schilder, Beschreibungen von Interaktiven Objekten)
- Dialoge mit NPC's (Questtexte, Händler & co.)
- Spielbereiche die beim betreten Schaden zufügen (Lavabecken, Zauber von Gegnern wo man nicht drinstehen soll etc.)
- Spielbereiche die beim betreten Heilung zufügen (eigene Zauber, Wasser aus Quellen und weiteres)

Das ist zumindestens das was ich bisher habe.
Das ist das erstemal das ich so etwas komplexes wie ein Spiel bzw eine "Spiele Engine" bastel, daher dauert das ganze entsprechend lange.
Ich versuche dabei alles so zu konstruieren, das es nicht nur spezifisch auf das Spiel angepasst ist sondern individuell auch in anderen Projekten
benutzt werden kann.

Was für ein Spiel genau ich damit schlussendlich entwickle, weiß ich noch nicht zu 100% - bevor ich mit der entwicklung des ganzen noch nicht weit genug vorangeschritten bin,
möchte ich dies auch nicht so exakt festlegen da sich einzelne Entscheidungen immer noch ändern können & werden.

Dinge die bisher feststehen:

- Es wird ein 2D Game das auf Tilesets basiert (Maps die aus einzelnen Tiles bestehen;Top Down Ansicht)

- Ich möchte nicht das mein Spiel zu einem "Ich schnätzel mich durch die Gegner" Game wird.
Das Game wird wenn, dann nur wenige Gegner enthalten.

Diese Gegner werden sofern ich dies umsetzen kann dann auch eigene kleine Mechaniken / spezielle Fähigkeiten haben bei denen man aufpassen muss, sonst verreckt man :rolleyes:
Ich mag es nicht das in den meisten Games die Gegner immer so zum Kanonenfutter mutieren wo man sich Brainafk durchboxt bis man einen bestimmten Drop oder Level hat.
Inwiefern ich das ganze dann umsetzen kann, weiß ich aber nicht - wie gesagt, ist das erste Game was ich entwickle.. muss mir also alles Wissen bezüglich Game Entwicklung
erst aneignen.

- Es wird eine Singleplayer Sandbox sein. Offene Spielwelt -> man kann überall hin sofern es die eigenen Skills & Gegner ermöglichen.
Ähnlich wie Zelda, Pokemon und Harvest Moon - Friends of Mineral Town.
Ein Multiplayer wäre jedoch zu Overkill. Vorallem da ich erstmal damit klar kommen muss ein einigermaßen Spielbares Singleplayer hinzubekommen.
Müsste mich sonst auch noch mit Dingen wie dem einzelnen Sync. von einzelnen Clienten, Entwicklung des Servers usw beschäftigen.

- Genre -> RPG / Abenteuer, Fantasy Orientiert

Screen eines Tests (Schauen wieviele Tile Wechsel man im Browser ohne Lag machen kann):

http://i.imgur.com/rEEajS9.png

Hier wird zunächst eine normale Map geladen, und dann wird Tile für Tile Zufallsbasiert gewechselt (test für spätere animationen).
Nutze für die Entwicklung derzeit noch Pokemon Tilesets, diese werden aber später durch eigene ersetzt.
Achja, auch zu sehen ist meine "Stylische" Dialogbox wo grade ein Dialog zwischen dem Spieler und einem nicht existierenden NPC stattfindet.
Dialog ist an den Pokemon Startdialog angelehnt, also nicht für das "Prof Cy" bashen ja? :rolleyes::P

Um es anders zu sagen - Ich habe mir da ein ziemlich großes und komplexes Freizeit Projekt rausgesucht :black_eyed:
Ich muss noch Dinge wie Collision Detection, Animationen, eine Spielbare Figur, NPC's & co. implementieren.. was erstmal ne harte Nuss wird.
Ich weiß nicht ob ich das Projekt stemmen werden kann, aber das Ziel und die Motivation ist zumindestens da.. und es macht mir auch spaß immer wieder
daran weiter zu arbeiten. Das ganze ist als Langzeitprojekt angelegt da ich schon immer mal ein eigenes Spiel entwickeln wollte..
Anders gesagt hatte ich oft den Gedanke "Die ganzen Games sind doch kacke, ich wills selbst besser machen.." - Let's Try it..

Würde diesen Thread hier gerne nutzen dürfen um meinen jeweiligen Fortschritt
dokumentieren zu dürfen sofern das okay geht :)

wacked
05.12.2015, 17:54
Source or GTFO!

Ich hab weder Ahnung von Spieleprogrammierung noch von JS, aber setz es mal auf github oder sowas - du kriegst ne Versionskontrolle und manche Leute hier können dir besser Tips geben.

Cystasy
05.12.2015, 19:04
@wacked
Im jetzigen Stadium ist der Code noch ziemlich Messy.. viele hier die Javascript besser als ich können würden da sicher
einiges finden was man bemängeln könnte. Möchte da erstmal "aufräumen" und weiterentwickeln bis es einen Punkt erreicht hat,
an dem es vorzeigbar ist^^ So das man dann auch einige Dinge (Schilder lesen, Map Wechsel etc.) testen kann.
Weiß nicht ob ichs im jetzigen Stadium schon anderen Personen zugänglich machen möchte.
Werde da erstmal einige Dinge überdenken & umbauen, den Messy Code bisschen aufräumen und dann kann man nochmal
drüber nachdenken.

EDIT:
Screw it, habs jetzt bisschen aufgeräumt und werds online packen.
Wehe jemand meckert weil der Code noch derbe Messy ist :P

Source & Online Demo: https://dl.dropboxusercontent.com/u/5004539/FH/Cygine/index.html
Git: Kommt wenn ich Git ans laufen bekomme *hust*.. klappt nicht so wirklich mit den kacks SSH Schlüsseln


p.s: Falls jemand die Tastenbelegung wissen möchte.. Der A-Knopf ist für das, was bei Gameboys ebenfalls die A-Taste war.. Dialoge weiterklicken und so ;P

grüße

wacked
05.12.2015, 23:03
Alles scheiße.

Ich hab keinen Bock mich mit dem Graphic scheiß auseinanderzusetzen aber ein paar Vorschläge hab ich ja schon.
1) Geb deinen states Namen. Bei 4 States kann man sich das gerade noch merken aber das werden noch viel mehr (zB. Karte wird gerade geladen, im Kampf, im Inventar, Spielstand speichern, ...)
2) Einfach generell weniger Magic Values. ObjectProc_Prototype ist nicht gerade selbsterklärend.
3) Es macht nicht so viel Sinn eine Funktion namens "XYZ_Protoype" zu schreiben. Du kannst doch einfach direkt zuweisen oder nicht?
4) Ich hab mir mal die textboxes.js genauer angeguckt.
4.1) Wofür ist dialogue_counter? Warum speicherst du nicht dadrin welcher Teil des momentanen Dialoges gerade ausgegeben werden soll? Du musst zugeben dass dialogue[dialogue_counter][0] schon offensichtlicher ist.
4.2) Was machst du denn wenn du mal mehr als einen Dialog hast? Du musst ja diese Fälle betrachten:
a) Im momentanen Dialog noch nicht fertig -> Ausgeben und nächste Zeilen finden
b) Mit momentanen Dialog fertig -> nächsten finden
c) Am Anfang ersten Dialog setzen
Momentan ersetzt du einfach die dialogue variable (also würd ich sie currentDialogue nennen) aber wo speicherst du denn alle Dialoge?

Ich würde es zu einer Klasse machen, z.B. so

/** * Dialogue class
* \param speaker Who speaks
* \param text Array of tuple(FirstLine, SecondLine)
*/
var Dialogue = function (speaker, text) {
this.speaker = speaker;
this.text = text;
this.currentText = 0;
};


/**
* Returns the current line of text and gets the next line
* \return false if there is no more text or an array with the keys "speaker" and "text"
*/
Dialogue.prototype.next = function() {
if(this.currentText >= this.text.length)
return false;

var t = this.text[this.currentText];
this.currentText++;

return {speaker: this.speaker, text: t};
}


var currentDialogue = new Dialogue('Alice', [['Zeile 1', 'Zeile 2'], ['1', 'aaaaa']]);


Und benutzt würde es dann iwie so:


/*
This File is Processing Keyboard Inputs
*/


Cygine.ProcKeys = function(evt)
{
// If the engine isn't running no key does anything
if(Cygine.state < 3)
return;

// Action key?
if(evt.key === Cygine.KeyLayout.resume || evt.key === Cygine.KeyLayout.cancel) {
var d = currentDialogue.next();
if(d === false) {
currentDialogue = new Dialogue('Game', [['Fehler', 'An dieser Stelle gibt es keinen Dialog']]);
d = currentDialogue.next();
}

// fixme: Display dialogue here
alert(d.speaker + ' says ' + d.text);
}
// Movement with arrow keys?
else if(evt.key >= 37 && evt.key <= 40) {
// if next to NPC
// currentDialogue = new Dialogue('NPC', [['Hey', 'bla bla bla']]);
}
}

Cystasy
05.12.2015, 23:32
1) Naja, ich hatte eigendlich nicht vor für so extrem viele Fälle States zu haben, aber wenn das mehr geworden wäre hätte ich ihnen ohnehin Namen gegeben.
Bot sich nur an weil es noch nicht viele waren.

2) Problem beim ganzen ist, das ich zur Zeit noch am rumwurschteln bin. Ich habe bisher noch nie eine Lib in Javascript gebaut,
daher habe ich es so gelöst. Die XYZ_Prototype Funktionen sind wie der Name schon sagt Prototypen, die dann im Main-Part der Engine zugewiesen werden.
Ist halt dazu da, das ich dann die einzelnen Funktionen mit Cygine.FUNKTIONSNAME() aufrufen kann. Hatte bisher noch keine bessere Möglichkeit
gefunden / gesehen die da besser wäre (so, das ichs auf einzelne Dateien auslagern kann)

3) Müsste mal schauen ob ich das ganze besser gelöst bekomme, jedoch wollte wie ich in 2) gesagt einen Globalen Zugriff, wenn du weißt wie ich das besser löse nur raus damit^^
Glaube mich zu erinnern das es da Probleme bezüglich dem laden der einzelnen Files gab als ich es anders probiert hatte weil es eine gewisse Zeit benötigt bis alles geladen ist etc.
Schaue ich mir definitiv nochmals näher an, wär gut das besser gelöst zu bekommen.

4) textboxes.js = Messy aus Hell. Die Dialogbox wird definitiv nicht so bleiben. (ein Grund weshalb ich den Source unter anderem noch nicht wirklich zeigen wollte)

4.1) Ist derzeit nur eine "Messy Lösung" -> Steht als nächstes an diese Funktion komplett abzuändern da ich sie selbst ziemlich besch...eiden finde.

4.2) Die Dialoge werden später in der Map zugewiesen als Event. Dort wird jenach Objekt & Event dann der Dialog zugewiesen und aufgerufen.
Zumindestens war es so geplant, das die Dialoge & Texte Schlussendlich später als Event in der Map Datei stehen werden.
Die derzeitige Variable mit dem Hardcodet Dialog dient nur als Test zum debuggen ob alles funktioniert.
Da die Funktion entstanden ist bevor ich die Map-Funktionen gescripted habe, ist sie da noch nicht wirklich drauf angepasst.

Allgemein muss man halt sagen, das die Dialog Funktion noch nicht wirklich.. fertig ist.
Hatte die geschrieben als ich Schlafentzug hatte und wollte mir sie die Tage vornehmen (komplett neu schreiben, diesmal besser).

Aber siehs so - jetzt weißt du weshalb ichs eig noch nicht zeigen wollte.. ist noch ziemlich viel Messy im Code.
Bin halt noch am rumwerkeln & probieren wie ich verschiedene Dinge am besten löse.
Hatte bisher eher kleinere Dinge in Javascript gemacht, ist sogesehen für mich auch ein Lernprojekt.

p.s: Keyboard Input ist auch noch nicht wirklich gut gelöst von mir, hab mich da noch nicht näher befasst weil ich noch keine Spielfigur zum steuern habe.

Danke jedenfalls für die Tipps, werde sie mir mal näher zu Gute führen und schauen das ich die Dialog Funktion mal abändere (ja, sie ist schrott - da hast du Recht ;))

grüße