Nouron: Mai 2012 (2) – Ein Achievementsystem für Nouron

… auch wenn sie schon lange nix neues mehr sind: Meiner Meinung nach sind Achievements toll! Sie bereichern Spiele um eine weitere Komponente zum kompetitiven Vergleich zwischen Spielern.. Sonst gibt es ja nur diverse Highscorelisten.

Das tolle an Achievements ist, dass die Motivation vieler Spieler dadurch erhöht werden kann. Ich sprech da etwas aus Erfahrung.. so ist es durchaus schon vorgekommen, dass ich Spiele nur nochmal wegen bestimmter Achievements angespielt habe. Es gibt natürlich auch Spieler denen Achievements scheißegal sind. Trotzdem ist diese Art der „Belohnung“ im Allgemeinen natürlich spieltriebfördernd.

Aus Programmierersicht sind Achievements auch toll: Sie sind – wenn die Basis stimmt – mit relativ wenig Aufwand erstellbar und können jederzeit erweitert werden.

Der Einbau eines Achievementsystem in Nouron (und damit verbunden ein grundlegendes Eventsytem) brennt mir schon länger unter den Fingernägeln.Es gibt da nur ein Problem: für das Zend Framework gibt es keine offizielle Erweiterung für ein Event-System. Zwar ist für das Zend Framework 2 durchaus eines in Entwicklung – leider ist ZF2 aber immernoch im Beta-Stadium.. (Und der ganze Umbau von Nouron auf die Verwendung von ZF2 wird wohl auch nochmal eine richtig aufwendige Angelegenheit).

Achievement

Ich habe auch geraume Zeit gegoogelt und nach bestehenden Lösungen für Achievement-Systeme gesucht aber leider war nichts brauchbares dabei: Entweder es waren reine Lösungen für die Anzeige von Achievements oder der Funktionsumfang war einfach nur rudimentär und damit ungenügend für meine Ansprüche.

Zur Definition meiner Ansprüche: Das beste Achievement-System was ich bisher gesehen habe befindet sich im Starcraft2/Battlenet. Hier sind diverse Sammel- bzw. Teilachievements in verschiedensten Kategorien möglich und zur Belohnung bekommt man neben hunderten von Portraits, Decals und Abzeichen auch wunderschön animierte Erfolgsmeldungen. Mir ist durchaus bewusst, dass mir etwas KnowHow und ManPower fehlt ein vergleichbar gutes System zu bauen und daher technisch aber vor allem grafisch starke Abstriche machen muss.

Zurück zur technischen Umsetzung: Da ich nun aber das Event- und das Achievementsystem trotzdem erstmal einbauen wollte, habe ich auf eine Komponente des Symfony-Frameworks zurückgegriffen: den EventDispatcher. Der EventDispatcher ist eine Implementierung des Event-Observer-Entwurfsmuster. Also genau das was ich für mein Event-System und mein Achievement-System brauche.

Ich will darauf jetzt nicht so genau eingehen aber ich habe beim Einbau auch einige Nachteile feststellen müssen: so kann ich beim Auslösen eines Events nicht einfach Parameter an eine Callback-Funktion übergeben – was ich aber dringend brauche.


$achievementsGw = new Achievements_Model_Gateway();

// closure function to execute achievements check for the given event:
$function = function($event) { /* closure */
    $achievementsGw->checkAchievements($event);
};

// get all available achievements (even already unlocked)
$achievements = $achievementsGw->getAchievements();

// extract the event names from the achievement objects:
$dispatcher = new sfEventDispatcher();
$events = array();
while ($achievements->valid()) {
    $events += explode($achievements->sEvents,',');
    $achievements->next();
}

$events = array_unique($events); // remove duplicates
foreach ($events as $e) {
    // register events to the dispatcher with the closure function
    // to execute when event is triggered:
    $dispatcher->connect($e, $function);
}

Doch eine Möglichkeit gibt es da doch: Closures. Man kann dem Event ein Callback übergeben oder eben eine Funktion als Variable (Closure). Und das hat mir wirklich geholfen, denn jetzt kann ich ohne Problem den Eventnamen übergeben und abfragen (es gab keinen einfachen Weg das aktuell aktive Event abzufragen).
Somit war das ganze eine gute Gelegenheit Closures – von denen ich bisher immer nur theoretisch gehört hatte – einmal praktisch anzuwenden. Yippieh!

So da Du nun wirklich bis zum Ende gelesen hast würde ich mich über einen Kommentar mit Feeback sehr freuen:  War das Thema interessant für Dich? War es ausführlich genug oder möchtest du mehr Details wissen? usw.

Bis dann, have fun!😀

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s