Zuhause

Im Archiv: September


Farm, die Zweite  

Coobico: Farm

Eine Farm stellt nach wie vor die wichtigste Nahrungsquelle einer Siedlung dar und ist daher eines der ersten Gebäude, die man bauen sollte—keine Änderungen zur alten Version soweit; wir haben aber das Gebäudemodell ausgetauscht gegen das obige, welches ein wenig charakteristischer und detailreicher ist. 


Gelehrter  

Coobico: Gelehrter

Gelehrte leben ein mehr oder weniger zurückgezogenes Leben in einem Gelehrtenhaus oder in einer Universität um sich ihren Studien und Lehren zu widmen. Auf diese Weise hilft ein Gelehrter dabei, den Bildungsgrad einer zugehörigen Siedlung anzuheben und die negativen Auswirkungen benachbarter Friedhöfe auszugleichen.


Bauten: Gelehrter  

Coobico: Scholar

Ein wichtiges Attribut jeder Siedlung ist der Grad an Bildung, welcher die öffentliche Ordnung und die allgemeine Zufriedenheit positiv beeinflußt. Bildung wird durch einen Gelehrten (siehe oben links) “produziert”—oder in gesteigertem Maße durch eine Universität (oben rechts). Ein Gelehrtenhaus ist eines der Gebäude, das erst später im Spiel zugänglich ist, da es als Voraussetzung ein Gildenhaus benötigt.


Zunftmeister  

Coobico: Zunftmeister

Ein Zunftmeister steht Werkstätten und Zunfthäusern vor und hebt den Handwerks-Grad einer Siedlung an. Er vergibt außerdem Mini-Jobs und sendet ab und zu Abenteurer zu Erfüllung von Questen aus.


Bauten:Werkstatt  

Coobico: Zunfthaus

Dies hier ist die Werkstatt, handwerkliches Zentrum beinahe jeder Siedlung. Eine Werkstatt ist mehr oder weniger unverzichtbar, auch wenn sie den Grad der Verschmutzung einer Siedlung anhebt, denn eine ausgebaute Werkstatt (ein sogenanntes “Zunfthaus”) dient als Vorraussetzung zum Bau diverser anderer wichtiger Bauten, wie z.B. den Heiler. Zudem werden in einem Zunfthaus nützliche Minijobs angeboten.


Nachgebloggt: Computerspieler im Profil  

Die internationale Forschungsgesellschaft Wiley hat vor kurzem ihre Studie “Who plays, how much, and why? Debunking the stereotypical gamer profile” kostenlos zur Verfügung gestellt, eine sehr lesenswerte Analyse. Da sich zur Zeit beinahe jeder Entwickler im Bereich virtueller Welten auf den Markt für Kinder und Jugendliche konzentriert, ist es besonders interessant, daß die Mehrheit aller Computerspieler im Alter über 30 ist.

Wir haben dies übrigens bereits vor einem Jahr vorhergesagt—es ist immer nett, Recht zu behalten… wink


Back-End: Parsing von VRML-Dateien  

Hier eine kleine Erläuterung zur Verarbeitung von VRML für die gängigen Open-Source 3D-Engines wie Away3D, Papervision oder Sandy3D. Um genauer zu sein, der Verarbeitung von VRML2 (.WRL), welches von jeder 3D-Software exportiert werden kann. Leider exportieren einige 3D-Programme VRML Geometry-Nodes lediglich als IndexedFaceSets, einer langen Liste von Knotenpunkten, die für die hier vorgestellte Methode der Verarbeitung ungeeignet ist. Cinema4D erzeugt z.B diese Art von VRML-Code, es sit daher empfohlen z.B. auf 3DMax zurückzugreifen, wenn möglich. 

Der Ablauf des Parsings ist keine Raketentechnik; da VRML ein Textformat ist, geht es eigentlich nur um den Einsatz von String-Operationen innerhalb einer Array-Filter Schleife. Hier ein kurzer Blick auf typische VRML-Syntax:


#VRML V2.0 utf8
# Produced by 3D Studio MAX VRML97 exporter, Version 9, Revision 1
# MAX File: level.max, Date: Sat Sep 6 8:00:00 2008

DEF myTestBox Transform {
  translation 317 100 -57
  children [
      Transform {
        translation 0 11.5 0
        children [
          Shape {
            appearance Appearance {
              material Material {
                diffuseColor 0.03137 0.2392 0.5412
              }
            }
            geometry Box { size 20 23 20 }
          }
    ] }
  ]
}

Im obigen Beispiel kann man leicht die nötigen Eckdaten ersehen, die man herausfischen muß, um sie in Actionscript3 wiederum in eine 3D-Szene zu übersetzen. Hier der nötige Ansatz dazu:


private var container:TransformGroup;
/*for Away3D change TransformGroup to ObjectContainer3D*/
private var vrmlString:String;

/*return-type TransformGroup is for Sandy3D, 
for Away3D choose ObjectContainer3D instead*/
private function parseVRML( $vrmlString:String ) : TransformGroup
{
   this.vrmlString = $vrmlString;
   var nodesInclCamera:Array = vrmlString.split( ‘DEF ‘ );
   /* remove VRML-header */
   nodesInclCamera.shift();
  /*exclude camera-node*/
  var nodesExclCamera:Array = nodesInclCamera.filter( filterCamera );

  container = new TransformGroup( ‘container’ );
  /*Away3D: container = new ObjectContainer3D();*/
  /*iterate over all geometry-nodes*/
  nodesExclCamera.forEach( processNode );
  
  return container;
};

private function filterCamera( element:*, index:int, arr:Array ):Boolean 
{
  return ( element.match( ‘Camera’ ) == null ); 
};

private function processNode( element:*, index:int, arr:Array ) : void 
{
  var helperArray:Array = element.split( ‘geometry ‘ );
  var primitive:String = helperArray[ 1 ].substr( 0, helperArray[ 1 ].indexOf( ‘ ‘ ) );
  var properties:Object = new Object();
  properties.name = element.substr(0, element.indexOf( ‘ ‘ );

  /*parse size*/
  var sizeSub:String = element.substr( element.indexOf( ‘size’ )+5, element.length);
  var sizeSplit:Array = sizeSub.split( ‘ ‘ );
  properties.width = sizeSplit[ 0 ];
  properties.height = sizeSplit[ 1 ];
  properties.depth = sizeSplit[ 2 ];

  /*parse position*/
  var transSub:String = element.substr( element.indexOf( ‘translation’ )+12, 
   element.indexOf( ‘ children’ ) );
  var transSplit:Array = transSub.split( ‘ ‘ );
  properties.x = transSplit[ 0 ];
  properties.y = transSplit[ 1 ];
  properties.z = transSplit[ 2 ];	

  /*parse rotation*/
  /*properties are called rotateX, rotateY and rotateZ in Sandy
  Away3d: change to rotationX, rotationY and rotationZ*/
  if ( element.match( ‘rotation’ )  != null)
  {
    var rotSub:String = element.substr( element.indexOf( ‘rotation’ )+9, 
    element.indexOf( ‘ children’ ) );
    var rotSplit:Array = rotSub.split( ‘ ‘ );
    properties.rotateX= Number( rotSplit[ 0 ] ) * Number( rotSplit[ 3 ] ) * 100;
    properties.rotateY= Number( rotSplit[ 1 ] ) * Number( rotSplit[ 3 ] ) * 100;
    properties.rotateZ= Number( rotSplit[ 2 ] ) * Number( rotSplit[ 3 ] ) * 100;
  } 

  container.addChild( this[ ‘_create’ + primitive ]( properties ) ); 			
};

/*return-type for Away3D is Cube instead*/
private function _createBox( properties: Object ) : Box
{
  var shape:Box = new Box();
  /*Away3D: var shape:Cube = new Cube();*/
  for( var p:String in properties ) shape[ p ] = properties[ p ];
  return shape;
};

Der erste Filter-Befehl trennt die Kamera von den restlichen Nodes. Man kann diesen Eintrag löschen, wie in unserem Beispiel, oder an dieser Stelle sogar seine 3D-Kamera dynamisch erzeugen.


var nodesExclCamera:Array = nodesInclCamera.filter( filterCamera );

private function filterCamera( element:*, index:int, arr:Array ):Boolean 
{
  return ( element.match( ‘Camera’ ) == null ); 
};

Die zweite Schleife durchläuft alle Geomtry-Nodes; hier kann man den Code zum Erzeugen der 3D-Szene einfügen—dazu wird jeweils eine dynmische Funktion aufgerufen anhand der Art von 3D-Objekt. Das funktioniert natürlich nur mit den 3D-Objekten, die auch von der gewählten 3D-Engine unterstützt werden. Außerdem sollte man im Hinterkopf behalten, daß die verschiedenen Körper unterschiedliche Klassennamen in den 3D-Engines haben. So wird ein rechteckiger Körper in Away3D “Cube” genannt, und in Sandy3D “Box”. Generell entsprechen die Bezeichnungen in Sandy3D denen von VRML (gute Arbeit, Jungs):


container.addChild( this[ ‘_create’ + primitive ]( properties ) ); 	

Der Funktionsaufruf übergibt alle nötigen Eigenschaften zum Erzeugen des 3D-Primitve als Objekt. Die Funktion gibt den fertigen 3D-Körper zurück.


/*return-type for Away3D is Cube instead*/
private function _createBox( properties: Object ) : Box
{
  var shape:Box = new Box();
  /*Away3D: var shape:Cube = new Cube();*/
  for( var p:String in properties ) shape[ p ] = properties[ p ];
  return shape;
};

Das ist der Ansatz zum Parsen von VRML—ich werde hier nicht weiter in die Details gehen, z.B. dem Setzen von Texturen, welche in VRML in Appearance- und Material-Nodes abgelegt werden. Das Verarbeiten dieser Daten läßt sich ähnlich dem oben vorgestellten Beispiel handhaben. Ich denke, daß sollte als Anstoß reichen.


Heiler  

Coobico: Healer

Heiler finden sich (wie überraschend) in einer Heilerpraxis oder in einem Hospital. Ihre Aufgabe ist es, die medizinische Versorgung der zugehörigen Siedlung anzuheben. Gelegentlich beauftragt ein Heiler auch Abenteurer mit kleinen Questen (wie dem Sammeln von Heilkräutern für seine Tinkturen).