Wie erstellt man eine map für ein Browsergame? |
| Veröffentlicht von Administrator am Jan 02 2020 |
Eigentlich habe ich nur ein paar Geschwindigkeitstests mit der php-mysqli Erweiterung machen wollen. Dabei ist dann dieses kleine Tutorial einer map für ein Browsergame rausgekommen.
Ich brauchte eine Menge Datensätze, die ich in die Datenbank schreiben konnte. Warum also nicht sinnvolle Daten benutzen? Eine Map mit 100 mal 100 Feldern ergibt 10000 Datensätze. Bei 200 mal 200 Feldern sind es dann schon 40000 Datensätze. Damit kann man eine Datenbank schon beschäftigen.....
Aber nun zum eigentlichen Thema:
-Wie sieht so eine Karte aus und welche Daten sind nötig?
-Wie sie die dazugehörige Datenbanktabelle aus?
-Welche Felder gibt es?
Dies sind die 3 Fragen die wir hier klären werden.
Vorüberlegung:
Wie stellen wir die Karte dar?
Da wir ja 2-dimensional arbeiten wollen, benutzen wir ein Koordinatensystem mit einer x-Achse und einer y-Achse. In meinem Fall habe ich eine Fläche von 100 mal 100 Feldern benutzt. Dies bleibt jedem aber selbst überlassen, je nach dem wie er seine Map benötigt.
Die Datenbanktabelle für die map wird sehr klein gehalten. Alle relevanten Daten werden in einer anderen Tabelle verwahrt. Diese Andere enthält dann die Daten zu den vorhandenen Gebäuden,Ressourcen oder auch Einheiten. Unsere Tabelle "map" besitzt nur 4 Felder :
id um die Inhalte zu unterscheiden
x Die X-Koordinate
y Die Y-Koordinate
status Hier geben wir an was dort zu finden ist.
Wir erstellen eine Schleife , die uns die einzelnen Daten generiert und in die db einträgt
Nun zu den einzelnen Feldern.Was können wir darstellen?
Strategiespiele würden sowas nehmen:
-unbewohnte Dörfer status =0
-bewohnte Dörfer status =1
-Berge status=2
-Seen status=3
RPG's wiederum:
-leer status=0
-Monster A status=1
-Monster B status=3
-Monster C status=3
-item 1 status=4
-item 2 status=5
-item 3 status=6
-item 4 status=7
usw.. Ihr seht hier ist alles noch sehr flexibel.
Fangen wir also an!
Zuerst erstellen wir die Datenbanktabelle. Dazu nehmen wir folgenden Code und fügen ihn in phpMyAdmin oder dem db-client eurer Wahl ein:
CREATE TABLE IF NOT EXISTS `map` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`x` int(15) NOT NULL,
`y` int(15) NOT NULL,
`status` int(2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1
Nun brauchen wir noch ein script welches uns die Datenbank füllt.
<?php
// Neues Datenbank-Objekt erzeugen
$db = @new mysqli( 'localhost', 'user', passwd', 'datenbank' );
// Variablen
$values = '';
$x=1;
$y=1;
$status=0;
// Pruefen ob die Datenbankverbindung hergestellt werden konnte
if (mysqli_connect_errno() == 0)
{
while($x<101){
$y=1;
while($y<101){
$values .= '('.$x.','.$y.','.$status.'),';
$y++;
}
$x++;
}
//Letztes Zeichen abschneiden
$values = substr($values, 0, -1);
$sql = 'INSERT INTO `map` (`x`, `y`, `status`) VALUES '.$values;
$eintrag = $db->prepare( $sql );
$eintrag->execute();
// Pruefen ob der Eintrag efolgreich war
if ($eintrag->affected_rows == 1)
{
echo 'Die Einträge wurde hinzugefügt.';
}
else
{
echo 'Die Einträg konnten nicht hinzugefügt werden.';
}
}
else
{
// Es konnte keine Datenbankverbindung aufgebaut werden
echo 'Die Datenbank konnte nicht erreicht werden. Folgender Fehler trat auf: ' .mysqli_connect_errno(). ' : ' .mysqli_connect_error(). ;
}
?>
Gehen wir das script einmal durch.
Zuerst erstellen wir ein Datenbankobjekt um mit der db kommunizieren zu können und setzen dann ein paar Variablen um einen Startpunkt für unser script festzulegen.Ansonsten kann es sein , dass php hier eigene Werte einträgt , was zu unerwünschten Ergebnissen führen kann.
War die Datenbankverbindung erfolgreich, starten wir die Schleife, die uns die Daten generieren soll.
HALT STOP!!!!
Hier fallen wir von unserem ursprünglichen Plan ab und generieren genau eine Query anstatt 10000!
mysqli gibt uns die Möglichkeit dazu , was uns mysql(ohne i) leider nicht bietet.Der Geschwindigkeitsvorteil ist enorm.
Anstatt 8,5sec braucht unser script nurnoch 0,5sec.
Unsere Schleife generiert uns also alle Koordinaten für unsere Map uns hängt sie an die Variable"$values". Somit können wir alle Werte zusammenfassen und in einem Statement an die Datenbank schicken. Die einzelnen Werte müssen eingeklammert werden und durch Kommas getrennt werden. Wenn die Schleife durchgelaufen ist und alle Werte aneinander gereiht sind, haben wir am Ende ein Komma zuviel , welches wir mit substr() entfernen. Nun generieren wir unser Statement und schicken es mit $db->prepare() an unsere Datenbank. Somit weiss die Datenbank welche Werte ankommen aber es wird noch nichts an der Datenbank verändert. Dies ist ein Schutzmechanismus von mysqli der uns vor SQL-Injection schützt.Denn ist das Statement einmal bekannt, kann es nicht mehr verändert werden. In unserem Fall nicht ganz so wichtig da unsere Werte alle im schript generiert werden aber gerade wenn man mit Usereingaben aus Formularen arbeitet sollte man immer vorsichtig sein.Hierbei sollten dann die Werte mit db->bind_param() verifiziert werden.Darauf gehe ich nicht weiter ein , weil wir es hier nicht verwenden. So zurück zum script. Mit $db->execute() führen wir nun endlich das Statement aus und schreiben die Daten in die Datenbank und unsere Karte wird dadurch erstellt. Im Anschluss wird dann noch geprüft ob das Schreiben der Daten erfolgreich war.
Die Karte ist erstellt aber alle Felder noch leer.
Nun fehlt uns noch eine kleine Funktion in der wir unsere Landschaft gestalten indem wir Berge Wälder und Seen per Zufall verteilen
//* Waelder und Berge erstellen*//
function createLand($val,$limit){
$db = @new mysqli( 'localhost', 'user', 'passwd', 'datenbank' );
$a=0;
$result=$db->query("SELECT id FROM map WHERE `status`=0 ORDER BY rand() LIMIT ".$limit);
while($row=$result->fetch_row()){
$rid=$row[0];
$res=$db->query("UPDATE SET `status`='$val' WHERE `id`='$rid'" );
$a++;
}
/* free result set */
$result->close();
}
Ein paar Zeilen mit großer Wirkung.
Was macht also diese Funktion?
Die Funktion erwartet 2 Werte.
Wenn wir nun unser Listing von oben benutzen:
-unbewohnte Dörfer status =0
-bewohnte Dörfer status =1
-Berge status=2
-Seen status=3
$val legt fest welcher Art dieser Teil der Karte ist
$limit legt fest wieviele wir erstellen möchten.
Zuerst wird wieder eine Datenbankverbindung aufgebaut. Danach holen wir uns die Menge an zufälligen Daten ,die wir mit $limit festgelegt haben(z.B 100). Danach nehmen wir den Wert aus $val und verändern das Feld status in der Datenbank . Am Ende geben wir den Speicher wieder frei.
Die Funktion sollte üblicherweise aus einem Formular aus dem ACP(AdminControlPanel) heraus aufgerufen werden, ansonsten kann man die Funktion auch mit statischen Werten in einem Script aufrufen.
<?php
$erg=createLand(1,100);
?>
So das war schon alles.......
Zuletzt geändert am: Jan 02 2020 um 12:35 AM
Zurück zur Übersicht


