Einführung in die Spiele­ Entwicklungsumgebung  Blade3D 
   
   

Lars Bilke, 06MIM, HTWK Leipzig, Fb IMN 
01.08.2007 
 

Inhaltsverzeichnis 
1.  Einführung ....................................................................................................................................... 4  1.1.  1.2.  1.3.  Was ist Blade3D ....................................................................................................................... 4  Architektur  .............................................................................................................................. 4  . Funktionalität .......................................................................................................................... 5  Interface zur direkten Manipulation ............................................................................... 5  Visuelle Logik‐Diagramme ............................................................................................... 5  Dynamisches Material‐System ........................................................................................ 5  Skript‐System ................................................................................................................... 5  Comunity‐Integration ...................................................................................................... 5  Modell‐Import ................................................................................................................. 6  Physik‐Sytem ................................................................................................................... 6  Partikel‐System ................................................................................................................ 6  Post‐Processing‐Effekte ................................................................................................... 6 

1.3.1.  1.3.2.  1.3.3.  1.3.4.  1.3.5.  1.3.6.  1.3.7.  1.3.8.  1.3.9. 

1.3.10.  Terrain ............................................................................................................................. 6  1.3.11.  Makros ............................................................................................................................. 6  1.3.12.  Trigger  ............................................................................................................................. 6  . 1.3.13.  Sound‐System .................................................................................................................. 6  2.  Programmoberfläche / Allgemeine Bedienung ............................................................................... 7  2.1.  Werkzeugleisten und Menüs ................................................................................................... 7  Szenen‐Werkzeugleiste ................................................................................................... 8  Transformations‐Werkzeugleiste (Spatial) ...................................................................... 8  Material‐Werkzeugleiste ................................................................................................. 9  Beleuchtungs‐Werkzeugleiste (Lighting) ......................................................................... 9  Kamera‐Werkzeugleiste .................................................................................................. 9  Physik‐Werkzeugleiste (Dynamics) ................................................................................ 10  Text‐Werkzeugleiste ...................................................................................................... 10  Community‐Werkzeugleiste .......................................................................................... 10  Hilfe‐Werkzeugleiste ..................................................................................................... 10 

2.1.1.  2.1.2.  2.1.3.  2.1.4.  2.1.5.  2.1.6.  2.1.7.  2.1.8.  2.1.9.  2.2.  2.3.  2.4.  2.5.  2.6.  3.   

Objektbrowser ....................................................................................................................... 11  Eigenschaften‐Inspektor ........................................................................................................ 11  Szeneneditor  ......................................................................................................................... 12  . Skripteditor ............................................................................................................................ 13  Tastaturkürzel ........................................................................................................................ 14 

Mit Szenen arbeiten ...................................................................................................................... 15 
  2 

3.1.  3.2. 

Standard‐Kamerasteuerung .................................................................................................. 15  Szenenobjekte manipulieren  ................................................................................................ 16  . Verschiebung ................................................................................................................. 16  Skalierung ...................................................................................................................... 16  Rotation ......................................................................................................................... 16 

3.2.1.  3.2.2.  3.2.3.  3.3. 

Werkzeuge zum Dupli‐zieren und Anordnen ........................................................................ 17  Duplicate Grid ................................................................................................................ 17  Duplicate SRT ................................................................................................................. 18  Duplicate Around  .......................................................................................................... 19  .

3.3.1.  3.3.2.  3.3.3.  4. 

Materialien und Effekte  ................................................................................................................ 20  . 4.1.  4.2.  4.3.  Unterschied zwischen Material und Effekt ........................................................................... 20  Einen Effekt erstellen ............................................................................................................ 20  Ein Material erstellen ............................................................................................................ 22 

5. 

Verhalten integrieren .................................................................................................................... 24  5.1.  5.2.  5.3.  Logik‐Diagramme................................................................................................................... 24  Skripte  ................................................................................................................................... 25  . Makros ................................................................................................................................... 25 

6. 

Soundsystem ................................................................................................................................. 27  6.1.  6.2.  Samples und Sounds erstellen .............................................................................................. 27  Sounds in der Szene verwenden ........................................................................................... 28  Sound‐Trigger ................................................................................................................ 28  Sound‐Skript .................................................................................................................. 28 

6.2.1.  6.2.2.  7.  8.  9. 

Blade3D‐Funktionalität erweitern ................................................................................................. 30  Online‐Hilfe ................................................................................................................................... 32  Tutorial: Pong‐Spiel ....................................................................................................................... 33  9.1.  9.2.  9.3.  9.4.  9.5.  9.6.  Das Spielbrett ........................................................................................................................ 33  Schläger erstellen .................................................................................................................. 35  Schläger bewegen ................................................................................................................. 38  Ball erstellen .......................................................................................................................... 42  Ball bewegen ......................................................................................................................... 43  GUI erstellen .......................................................................................................................... 48 

Quellen: ............................................................................................................................................. 50     

 

 

  3 

1. Einführung 
1.1.
  Blade3D  von  Digini  Inc.  ist  eine  neue  3D‐Spieleentwicklungsumgebung,  die  einen  WYSIWYG‐ Szeneneditor,  eine  shaderbasierte  Render‐Engine,  eine  C#‐basierte  Skript‐Engine,  einen  fort‐ schrittlichen  Texteditor,  HLSL‐basierte  Materialien  und  Effekte  und  eine  Physik‐Simulation  in  einer  einfach zu bedienenden Umgebung nahtlos vereint.  

Was ist Blade3D 

Wichtiger Hinweis:    Blade3D ist ein recht junges Produkt und befindet sich noch im  Beta‐Stadium. Die  vorliegende  Arbeit  bezieht  sich  auf  die  Version  Blade3D  Beta  1  Refresh  (Build  2213).  Die  Version  kann  unter  www.blade3d.com  heruntergeladen  werden.  Es  kann  also  sein,  dass  bestimmte  Funktionen  in  neueren  Versionen  nicht  mehr  funktionieren oder andere Auswirkungen als die hier beschriebenen haben.    Blade3D  hieß  ehemals  XNAMagic.  Der  alte  Name  war  aber  bereits  rechtlich  gesichert und das Produkt wurde deswegen umbenannt.
   

1.2.

Architektur 
  Blade3D  ist  eine  .Net‐Anwendung  aufbauend  auf  dem  XNA‐Framework  von  Microsoft  und  bisher  lauffähig  auf  Windows  XP  SP2  oder  Windows  Vista  (Unterstützung  für  die  Xbox  360 ist in Entwicklung).  Blade3D  verfügt  über  eine  erweiterbare,  objekt‐orientierte  Architektur.  Das  dyna‐ mische  Objektmodell  ermöglicht  die  Erstel‐ lung neuer Typen (Klassen) zur Laufzeit, bietet  Serialisations‐Dienste  (um  z.B.  konkrete  Typ‐ Instanzen zur späteren Verwendung speichern  zu  können),  Mehrfach‐Vererbung  und  ein  Benachrichtigungssystem  (um  Daten  bei  Ereignissen  zwischen  den  einzelnen 

XNA­Framework von Microsoft:    XNA  (XNA’s  Not  Acronymed)  ist  eine  Technologie für die Spieleentwicklung für  Windows  XP/Vista  und  Xbox  360  von  Microsoft  und  baut  auf    Teilen  der  DirectX‐Schnittstelle  und  des  .Net  Frameworks  2.0  auf.  Es  vereint  wichtige  Funktionen der Spieleprogrammierung in  einem    einfach  zu  programmierendem  Framework  und  bietet  erstmals  die  Möglichkeit  ein‐  und  denselben  Quellcode sowohl auf dem PC als auch auf  der  Konsole  Xbox  360  ausführen  zu  können. 

Programmteilen  und  Typen  austauschen  zu  können).  Dieses  Objektmodell  ermöglicht  die  Interaktion zwischen den einzelnen, isolierten Untersystemen.  Das  Objektmodell  kann  über  Skripte  gesteuert  werden  und  stellt  eine  API  für  den  Programmierer  bereit, um auf alle Komponenten zugreifen zu können. So können z.B. Eigenschaften von mehreren   
  4 

Objekten gleichzeitig verändert werden, Anfragen können gestellt werden, um an alle Objekte eines  bestimmten  Typs  zu  kommen  und  Felder  und  Basisklassen  können  zur  Laufzeit  hinzugefügt  und  entfernt werden.  Um  die  Funktionalität  von  Blade3D  zu  erweitern  braucht  man  nur  einen  neuen  Typ  in  Blade3D  definieren  oder  eine  .Net‐Klasse  schreiben.  Die  Klasse  wird  dann  automatisch  in  die  Entwicklungs‐ umgebung  integriert.  Wenn  man  nur  einen  Operator  für  ein  Logikdiagramm  schreiben  will,  dann  brauch man nur eine statische .Net‐Funktion zu schreiben.   

1.3.
 

Funktionalität 

Hier folgt eine Kurzbeschreibung der Hauptfunktionalitäten von Blade3D.  1.3.1. Interface zur direkten Manipulation  In  der  Entwicklungsumgebung  können  alle  Objekteigenschaften  in  Echtzeit  geändert  werden.  Veränderungen an Objekten über Eigenschaftseditoren werden unverzüglich an den Szenendesigner  übermittelt.  Alle  Änderungen  werden  sofort  sichtbar  gemacht.  Die  Umgebung  verfügt  über  Undo/Redo‐Funktionen  ohne  auf  eine  Neukompilierung  angewiesen  zu  sein,  wie  es  in  der  herkömmlichen Software‐Entwicklung der Fall ist.  1.3.2. Visuelle Logik­Diagramme  Neben der Unterstützung für traditionellere Wege Spiel‐Logik zu implementieren, wie C#‐basiertem  Skripting  und  Integration  mit  anderen  .Net‐Programmiersprachen,  verfügt  Blade3D  über  visuelle  Logik‐Diagramme.  Diese  stellen  den  Datenfluss  zwischen  Objekten  visuell  dar  und  werden  halbtransparent über die Szene gelegt, sodass Änderungen sofort sichtbar werden. Objekte werden  einfach  per  Drag&Drop  in  das  Diagramm  gezogen  und  mithilfe  von  Operatoren  miteinander  verbunden.  1.3.3. Dynamisches Material­System  Die  Rendering‐Engine  von  Blade3D  gründet  sich  auf  GPU‐basierten  Shadern.  Blade3D  verfügt  über  einen  Editor  für  Shader  in  HLSL  mit  Syntaxhervorhebung  und  Echtzeit‐Kompilierung  bei  gemachten  Änderungen. Alle Änderungen sind sofort in der Szene sichtbar.  1.3.4. Skript­System  Blade3D verfügt über ein C#‐basiertes Skripting‐System. Die Umgebung stellt einen Skript‐Editor mit  Syntaxhervorhebung und Code‐Vervollständigung bereit.  1.3.5. Comunity­Integration  Blade3D  integriert  die  Online‐Community  in  die  Desktop‐Applikation.  Man  kann  direkt  in  der  Umgebung  Screenshots  an  die  Community‐Webseite  schicken,  ganze  Projekte  oder  nur  einzelne  Assets, wie Texturen oder Modelle, mit anderen Nutzern teilen. Außerdem können entdeckte Fehler  im Programm in eine Bug‐Datenbank eingetragen werden. Das Blade3D‐Hilfesystem ist online‐basiert  und  wird  dynamisch  von  Digini  oder  Community‐Mitgliedern  erweitert.  Das  Hilfssystem  beinhaltet  eine Referenz‐Dokumentation, Beispiele, Assets und Video‐Tutorials. 

 

  5 

1.3.6. Modell­Import  Zum  Modell‐Import  werden  die  Formate  DirectX  (.x),  DarkBasic  (.dbo),  GameStudio  (.mdl),  Poser  (.bvh), BlitzBasic (.b3d), Quake2 (.md2), HalfLife (.mdl und .smd), HalfLife2 (.smd), MilkShape (.ms3d),  WaveFront (.obj) und 3ds Max (.3ds) unterstützt.  1.3.7. Physik­Sytem  Blade3D enthält ein einfaches Physik‐System, welches die Interaktion  zwischen festen Körpern und  auch die Interaktion mit Partikel‐Systemen, berechnet.  1.3.8. Partikel­System  Das Partikel‐System wird über Logik‐Diagramme definiert und gesteuert. Geometrische Grundkörper  dienen als Emitter und als Kollisionsobjekte für die Partikel. Die Eigenschaften der Partikel‐Systeme  können  über    vielzählige  Operatoren  miteinander  verknüpft  werden  und  sie  können  Eingaben  von  allen möglichen Objekten bekommen.  1.3.9. Post­Processing­Effekte  Post‐Processing‐Effekte  wie  Überzeichnung  (Bloom),  Sepia‐Tönung,  Radialer  und  Gauss‐Weich‐ zeichner  sind  schon  standardmäßig  enthalten.  Es  können  mehrere  Effekte  kombiniert  werden  und  neue durch HLSL‐Shader integriert werden.  1.3.10. Terrain  Die  Terrain‐Engine  arbeitet  auf  Grundlage  von  Höhentexturen  (height  maps)  und  benutzt  eine  Quadtree‐Implementierung,  um  Level‐Of‐Detail‐Unterstützung  anzubieten.  Ein  spezieller  Terrain‐ Shader  ermöglicht  die  Texturüberblendung  mit  mehreren  Texturen  (z.B.  für  Gras,  Schotter  und  Steine)  mithilfe einer  Kontrolltextur,  die festlegt wie die  einzelnen Texturen  an bestimmten Stellen  ineinander geblendet werden.  1.3.11. Makros  Makros können neben den Logik‐Diagrammen und Skripten benutzt werden, um Spiel‐Logik einfach  zu  erstellen.  Blade3D  stellt  eine  Vielzahl  an  Makro‐Typen  bereit,  um  Sounds  abzuspielen,  Animationen  auszulösen,  Werte  zu  interpolieren  oder  Ereignisse  auszulösen.  Mehrere  Makros  können in Verbund‐Makros (compound macros) zusammengefasst werden. Zufalls‐Makros (random  macros) erzeugen nicht deterministische Effekte.  1.3.12. Trigger  Ein Trigger wird durch einen Raum definiert (z.B. eine Kugel oder ein Quader). Kollidiert ein Objekt  mit dem Trigger, so wird eine bestimmte Aktion, wie z.B. Abspielen eines Sounds, ausgelöst.  1.3.13. Sound­System  Das in Blade3D integrierte Audio‐Systeme ermöglicht den Import von Sounddateien in dem Format  Wave (die Formate OGG, XM und MP3 sollen später noch unterstützt werden). Sounds werden durch  bestimmte Ereignisse oder Skripte ausgelöst und können mit Effekten wie Chorus, Flanger oder Hall  versehen werden, um eine realistische Soundkulisse zu erzeugen.   

 

  6 

2. Program mmoberfläche / Al llgemein ne Bedien nung 
2.1. Werkz zeugleiste en und Me enüs 
Nach  dem  Starten von  Blade3D  über  die  angeleg n  gte  Desktop p‐Verknüpfung  oder  über  den  Startmen nüeintrag wird man aufg gefordert seine Blade3D‐Accountdat ten einzugeb ben. Man mu uss einen  Account anlegen bev vor man Blade3D runter rladen kann. . Blade3D ve erbindet sich h nun mit de er Online‐ nity sofern e eine Verbindu ung mit dem m Internet verfügbar ist. A Abbildung 1 z zeigt das Sta artlayout.  Commun

 
Abbildung g 1 ‐ Startlayout 

Titelleist te  Zeigt den n Namen des geöffneten n Moduls an.  Dateime enü  Das Date eimenü öffn net sich beim m Klick  auf das Blade3D‐ ‐Symbol in d der oberen li inken Ecke.  Über  das  Menü ka ann man Pro ojekte (Modu ule) im XML‐Format spe eichern und l laden oder s sogenannte  Packages  in einem m optimierten Binärformat laden. We eiterhin zeig gt das Menü  eine Liste der zuletzt ge eöffneten  Module an.  Hauptem menü‐Tabs  Das  Hau uptmenü  ist  die  horizon ntale  Leiste  oben.  Ein  Klick  auf  ein bestimm nen  mten  Tab  bringt  die  b   zugehörige  Werkzeu ugleiste  zum Vorschein Man  kann z.B.  Grun m  n.  n  ndkörper  der  Szene  hin nzufügen,  Objekte  verschieben oder  das  Material  eines  Objektes  ändern.  Man  kann  außerdem  mit  dem  n  Scrollrad d der Maus d durch die unt terschiedlich hen Tabs nav vigieren. 

 

  7 

 
Abbildung g 2 ‐ Hauptmen nü 

Werkzeu ugleiste  Die  Wer rkzeugleiste  kann  über  e einen  Doppe elklick  auf  die  Tabs  ein‐ und  ausgeb blendet  werd den.  Jede  Werkzeu ugleiste  enthält  Buttons  für  die  a meisten  benutzten  Kommando in  der  je am  os  eweiligen  Kategori ie. So enthält t z.B. die Bel leuchtungs‐W Werkzeugleis ste (Lighting) ) Möglichkeiten der Szen ne Lichter  hinzuzuf fügen oder d die Farbe einer Lichtquell le zu ändern, , siehe auch Abbildung 3 3. 

 
Abbildung g 3 ‐ Werkzeugl leiste (Licht) 

2.1.1. Szenen­Werkzeug gleiste   

  Hier kan nn man geom metrische Pr rimitive wie  Kugel und Q Quader der S Szene hinzufügen. Um ei in Objekt  hinzuzuf fügen  reicht ein  Mausk t  klick  auf  de jeweiligen  Button.  D Objekt  erscheint  sofort  im  en  Das  s Szenene editor. Man k kann Modelle über  importieren n. Importierte Modelle w werden in ein ner Drop‐

Down‐Liste ausgewä ählt . De er Button   fügt eine Instanz des ausgewählte en Modells d der Szene  hinzu.  In der  Display n  y‐Spalte  kan man  die  Anzeige  der Selektions‐Box,  des  Sze nn  r  enenbodens  und  der  Lichter  a und  aus an‐  sschalten.  In der  Bound n  ds‐Spalte  kann  man  die Anzeige  de Umgebun e  er  ngsboxen  (boundin boxes)  d Objekte  an‐  und  au ng  der  usschalten.  Ein  Klick  au den  Mut uf  te‐Button  stoppt  die  Wiederg gabe von Sou unds.  2.1.2. Transfo ormations­W Werkzeugleiste (Spatial)   

  Hier sind d wichtige W Werkzeuge zu ur Objektma anipulation z zu finden. In  der Mode‐S Spalte wählt man die  Transfor rmationsart  aus  (Transla ation,  Skalie erung,  Rotat tion).  Die  dr folgende Spalten  enthalten  rei  en  e Eingabef fenster  zur  manuellen  n numerischen Einstellung der  Größe  (Scaling),  d Rotation  und  der  n  g  der  Lage  im  Raum  (Tran nslation).  Un nter  Tools  sind  nützliche Funktionen  zu  finden.  e  Kamera direkt auf da as Objekt.  ssiert  die    fokus  

 verschie ebt das gewä ählte Objekt direkt vor di ie Kamera. 

 

  8 

verschiebt  das  gewählte  Objekt direkt  nac unten  zur  Koordinate t  ch  enursprungs sebene  oder auf  das  r  eingefüg gte Terrain.   setzt alle Rotatione en des gewäh hlten Objekt ts auf Null zu urück. 

2.1.3. Materia al­Werkzeu ugleiste   

  Material‐Spal werden  f das  ausg lte  für  gewählte  Ob bjekt  das  Ma aterial,  die  d diffuse,  die  spekulare  s In  der  M und die Normal‐Text ture gesetzt. . Klickt man a auf einen Bu utton, so sieh ht man ein D Drop‐Down‐M Menü mit  verfügba aren  Materia alien und Te exturen.  Fäh hrt man  mit  der  Maus über einen  Eintrag so we erden die  Auswirku ungen  sofor angezeigt. Ein  Klick  auf  den  Eintrag  setzt  da Material  o rt  .  as  oder  die  Textur.  Die  Farben‐S Spalte (Color r) funktionie ert genauso,  nur das hier r die ambien nte, die diffuse und die s spekulare  Farbe für das Objekt t gesetzt wer rden.  2.1.4 Beleuch 4. htungs­Wer rkzeugleist te (Lighting g)   

  Spalte  kann  man  Lichtq quellen  erste ellen  (Punkt tlichter,  Spo otlichter,  dire ektionale  In  der  Insert‐Light‐S würfelförmig Projektio ge  onslichter).  H man  ein Lichtquell ausge‐ Hat  ne  le  Lichter,  Projektionslichter  und  w wählt  so kann  man in  der  Lic o  n  chtfarben‐Sp palte  (Light  Colors)  die  ambiente,  die  diffuse  und  die  spekular Lichtfarbe einstellen.  Beim  Ankli re  e  icken  bekom mmt  man  w wieder  eine  D Drop‐Down‐Liste  mit  mögliche Farben  inklusive  Ech en  htzeitvorscha Unter  Einstellungen  (Settings)  kann  man  die  Licht‐ au.  d Intensitä äts‐Abnahme (Attenuation)  und  d Licht‐Rei e  die  ichweite  (Ra ange)  einste ellen.  Hat  man  ein  Spotlicht t ausgewählt t, so kann man in der Winkel‐Spalte ( (Angles) den n inneren und d äußeren Ra adius des  Lichtes  e einstellen,  s sowie  unter  Falloff  den  Intensitätsu unterschied  zwischen  diesen  beiden Radien  n  einstelle en.  2.1.5. Kamera a­Werkzeug gleiste   

  sert kann ma an der Szene e eine Kamer ra hinzufüge en. Beim Klick auf den zw weiten Butto on (Select  Über Ins Camera) öffnet  sich  ein  Menü  m den  verf )  mit  fügbaren  Kameras.  Fähr man  mit  d Maus  üb einen  rt  der  ber  Eintrag  s sieht  man die  Szene  aus  Sicht  di so  n  ieser  Kamera  im  Szenen neditor.  Ein  Klick  auf  den  Eintrag  wählt die ese Kamera als Aktive au us. Der letzte e Button (Apply Lens Sha ader) fügt de er Kamera ein nen Post‐ Processing‐Effekt zu. Auch hier h hat man eine e Echtzeitvorschau aller v verfügbaren Lens‐Shader r.   

  9 

2.1.6. Physik­ ­Werkzeugl leiste (Dynamics)   

  Über  die e Physik‐Werkzeugleiste  kann  man O Objekte physikalische Eig genschaften zuweisen. D Der erste  Button (Make Active e Rigid Body) ) fügt dem O Objekt Eigens schaften wie e Masse oder r Geschwindigkeit zu.  em  as  nun  mit  and deren  Objek kten  kollidie eren  oder  v von  der  Sch hwerkraft  Außerde kann  da Objekt  n angezog gen werden. Der zweite B Button (Make e Static Rigid d Body) entfe ernt diese Eig genschaften wieder.  2.1.7. Text­W Werkzeugleiste   

  fügen‐Button  (Insert)  e erzeugt  ein  neues  Text tobjekt.  In  der  Size‐Sp palte  kann  man  die  Der  Einf Schriftgr röße  über  den  Slider  ein nstellen  und den  dargestellten  Text eingeben.  In  der  Family‐Spalte  d  t  kann ma an die Schrift tart mithilfe einer Echtze eit‐Vorschau einstellen. 2.1.8. Commu unity­Werk kzeugleiste     

  In der Co ommunity‐W Werkzeugleis ste kann man n sich ein‐ un nd ausloggen n, einen Scre eenshot mac chen, der  auf der  Blade3D‐We ebseite veröf ffentlicht wird oder eine en Bug meld den. Man kan nn den Bug  in einem  separate en Fenster be eschreiben u und dieser w wird dann in e einer Datenb bank gespeichert.  2.1.9. Hilfe­W Werkzeuglei iste   

  Ein  Klick auf  den  Fra k  agezeichen‐B Button  öffne die  Online et  e‐Hilfe.  Mit  d Pfeiltast kann  ma wie  in  den  ten  an  einem Browser vor‐ und zurückn navigieren.   

 

  10 

2.2.

Objektbrowser 

 
Abbildung 4 ‐ Der Objektbrowser  Abbildung 5 ‐ Objektfilter auf Textur gesetzt 

  Der Objektbrowser stellt einen visuellen Überblick über alle Objekte in einem Modul zur Verfügung.  Die  Objekte  sind  in  unterschiedliche  Kategorien  unterteilt,  die  durch  einzelne  Ordner  repräsentiert  werden. Über den Objekt‐Filter oben rechts kann man sich nur Objekte einer bestimmten Kategorie  anzeigen lassen.   Lässt  man  sich  z.B.  nur  die  Texturen  im  Browser  anzeigen,  so  sieht  man  eine  Vorschau  der  verfügbaren Texturen wie in Abbildung 5 dargestellt.,  Das  aktuell  ausgewählte  Objekt  ist  blau  hinterlegt.  Der  Name  des  Objekts  wird  außerdem  in  der  unteren Statusleiste angezeigt.  Man kann schnell die zuletzt benutzten Objekte im unteren Bereich des Objektbrowsers auswählen.  Je heller ein Objektname, desto öfter wurde es bisher benutzt.  Ein Doppelklick auf ein Objekt öffnet das jeweilige Eigenschaftenfenster.   

2.3.

Eigenschaften­Inspektor 

Alle  Objekte  in  Blade3D  verfügen  über  zahlreiche  Eigenschaften,  die  ihre  Erscheinung  oder  ihr  Verhalten  beeinflussen.  Am  leichtesten  lassen  sich  diese  Eigenschaften  über  den  Eigenschaften‐ Inspektor  bearbeiten.  Diesen  öffnet  man,  indem  man  auf  das  Objekt  rechtsklickt  oder  im   
  11 

Objektbr rowser  auf  das  Objekt doppelklick Es  ersch t  kt.  heint  nun  e neues  Fenster,  welc ein  ches  frei  positioniert werden kann (siehe Abbildung 6). 

 
Abbildung g 6 ‐ Der Eigens schaften‐Inspek ktor 

Oben  re echts  sieht  m den  Na man  amen  des  O Objektes  und kleine  Pfeile,  um  zwis d  schen  den  einzelnen  e Kategori ie‐Tabs zu na avigieren. Eig genschaften sind in Kateg gorien grupp piert.  Im  Haup ptbereich  we erden  die  Ei igenschaften Zeile  für  Zeile  aufgeführt.  Je  nach Art  der  Eig n  h  genschaft  werden verschiedene Eingabemö öglichkeiten wie z.B. Tex xtboxen, Slider, Farbwähler, Checkbo oxen oder  own‐Menüs, angeboten.  Drop‐Do Eigensch haften,  die  z zwei  Objekte verbinden  werden  Obj e  jektreferenz (ObjectR genannt So  sind  zen  Ref)  t.  z.B. Mat terialien Obje ekte. Wenn  man dann e ein Material  ändert, so ä ändern sich a auch alle Ob bjekte die  das  Mat terial  refere enzieren.  Ob bjektreferenz werden  im  Inspekto immer  orange  unter zen  or  rstrichen.  Wenn m man auf den L Link klickt, öf ffnet sich das Eigenschaf ften‐Fenster des verlinkte en Objektes. .  Wenn m man einen We ert über eine en Slider ver rändert, so k kann man die esen nur in v vorbestimmt ten Wert‐ Bereiche en verändern n, die bei der Erstellung des Objektes s festgelegt wurden. Ma an kann aber r über die  manuelle e Eingabe de es Wertes im m Textfeld ein nen beliebige en Wert eing geben.   

2.4.
 

Szenen neditor 

Nach  de Starten  von  Blade3D  nimmt  de Szenened em  er  ditor  den  größten  Teil  d Anwend der  dung  ein.  Standard dmäßig  wird ein  Bodengitter  angez d  zeigt,  um  die  Orientieru zu  erleichtern.  Die  globalen  ung  Szenene eigenschaften n erhält man n auf einen D Doppelklick auf den Scene e‐Ordner im  wser.   Objektbrow

 

  12 

In  der  Kategorie  Szene  (Scene)  kann  man  die  Materialien  einstellen  mit  denen  das  Bodengitter  gerendert werden soll und eine Standard‐Schriftart für eingefügte Text‐Objekte einstellen. Außerdem  kann man die Schwerkraft definieren, die auf Objekte mit physikalischen Eigenschaften wirken soll.  In  der  Kategorie  Kamera‐Grundeinstellung  (Camera  Base)  stellt  man  den  Typ  der  Standardkamera  und  weitere  wichtige  Eigenschaften  wie  Blickwinkel  und  Seitenverhältnis  ein  und  man  kann  der  Kamera einen Post‐Processing‐Effekt zuweisen.  In der Kategorie Viewport Base stellt man ein, welche Kamera für den Viewport, also die Ansicht des  Szeneneditors,  verwendet  wird,  welche  Hintergrundfarbe  verwendet  wird  (Clear  Color),  ob  das  Bodengitter gezeichnet werden soll (Draw Floor) und wie groß es sein soll (Floor Size und Grid Step)  und  ab  welchem  Knoten  im  Szenenbaum  die  Szene  gerendert  werden  soll  (Items,  um  bestimmte  Teile der Szene vom Rendering auszuschließen). 

  Man kann Objekte über einen Klick auf den entsprechenden Button in der Werkzeugleisten zur Szene  hinzufügen  oder  über  einen  Rechtsklick  auf  den  Scene‐Ordner  im  Objektbrowser  und  dann  Create/gewünschtes Objekt.   

2.5.
 

Skripteditor 

Das  Skript‐System  von  Blade3D  ermöglicht  das  Hinzufügen  von  Logik  durch  Skripte  geschrieben  in  einem C#‐Dialekt. Szenen‐Objekte und Teile des Objekt‐Modells können über Skripte angesprochen  werden und miteinander interagieren. Um einem Objekt ein Skript hinzuzufügen, klickt man mit der   

  13 

rechten Maustaste auf das Objekt im Objektbrowser und wählt im erscheinenden Menü Add Script.  Daraufhin  sieht  man  ein  Menü  mit  Eigenschaften  des  Objektes  und  Ereignissen  an  die  das  Skript  gebunden  werden  kann.  Ändert  sich  die  Eigenschaft  des  Objekts  oder  wird  das  Ereignis  ausgelöst,  so  wird  das  Skript  gestartet.  Wenn  man  z.B.  MouseClick  auswählt,  wird  das  Skript  gestartet  wenn  man  mit  der Maus das Objekt anklickt.  Man öffnet den Editor, indem man auf den Tab Script Editor am  unteren linken Rand der Anwendung klickt. Auf der linken Seite  des  Editors  sieht  man  eine  Liste  aller  erstellten  Skripte.  In  der  rechten Hälfte wird das Skript eingegeben. Das Skript wird auto‐ matisch gespeichert und kompiliert, wenn man in einen anderen  Bereich der Anwendung klickt oder durch Drücken von F12.  Der  Editor  ist  an  den  Editor  von  Visual  Studio  angelehnt  und  bietet  farbliche  Syntax‐Hervorhebung,  Code‐Vervollständigung  und Fehler‐Hervorhebung.   

2.6.
  Taste    F1  Strg +  F  Strg +  N  Strg +  O  Strg +  S      Strg +  D  Entf      F10  F3  F4  F5  B  F 

Tastaturkürzel 
Aktion  Globale Aktionen  Hilfe  Hauptmenü  Neues Modul  Modul öffnen  Modul speichern    Objektbrowser  Objekt duplizieren  Objekt löschen    Transformationstools  Zurücksetzen aller Transformation  Zurücksetzen der Skalierung  Zurücksetzen der Rotation  Zurücksetzen der Translation  Verschiebt das Objekt vor die  Kamera  Fokussiert die Kamera auf das  Objekt    G  T    V    W    S    A    D  C    W    S    A    D  X    W    S    A    D    Bewegt das Objekt auf das  Bodengitter  Bewegt das Objekt auf das Terrain    Aktiviert Translations‐Modus  Bewegt Objekt hoch  Bewegt Objekt runter  Bewegt Objekt nach links  Bewegt Objekt nach rechts  Aktiviert Rotations‐Modus  Rotiert Objekt vorwärts um die X‐ Achse  Rotiert Objekt rückwärts um die X‐ Achse  Rotiert Objekt links um die Z‐Achse  Rotiert Objekt rechts um die Z‐Achse  Aktiviert Skalierungs‐Modus  Skaliert das Objekt größer auf der Y‐ Achse  Skaliert das Objekt kleiner auf der Y‐ Achse  Skaliert das Objekt kleiner auf der X‐ Achse  Skaliert das Objekt größer auf der Y‐ Achse 

 

  14 

3. Mit Szenen arbeiten 
3.1.
 

Standard­Kamerasteuerung 

 
Abbildung 7 ‐ Standard‐Kamerasteuerung 

Erstellt  man  eine  neue  Szene,  so  ist  eine  Standard‐Kamerasteuerung  bereits  durch  ein  Logik‐ Diagramm  aktiv.  Zum  Verschieben  der  Kamera  nutzt  man  die  z.B.  für  einen  Shooter  typische  Steuerung über die WASD‐Tasten. Mit den Tasten  Q und E kann man die Kamera runter und hoch  bewegen. Hält man die mittlere  Maustaste gedrückt und bewegt man die  Maus, so verändert man  die Blickrichtung der Kamera.  Ist  ein  Xbox  360  Gamepad  angeschlossen,  so  kann  man  mit  dem  linken  Analog‐Stick  sich  nach  links/rechts  und  vorn/hinten  bewegen.  Mit  dem  rechten  Analog‐Stick  kontrolliert  man  die  Blickrichtung.  Hinweis:  Die  Standard‐Kamera  ist  außerdem  ein  Active  Rigid  Body,  d.h.  sie  kollidiert  mit  anderen  Objekten, denen physikalische Eigenschaften zugewiesen wurden, wie z.B. dem Bodengitter.  Man  kann  die  Steuerung  über  das  Logik‐Diagramm  DefaultControllerGraph  (siehe  Abbildung  7)  im  Ordner  Graphs  im  Objektbrowser  verändern  und  anpassen  oder  gleich  eine  komplett  neue  Kamerasteuerung implementieren.     
  15 

3.2.
 

Szenenobjekte manipulieren 

Um  ein  Objekt  zu  verändern  muss  man  es  erst  auswählen.  Dazu  reicht  ein  einfacher  Klick  auf  das  Objekt im Szeneneditor oder im Objektbrowser. Wenn ein Objekt ausgewählt ist, so wird es von einer  roten Box umgeben (dem Hüllquader).  Es ist möglich mehrere Objekte auszuwählen, indem man die Strg‐Taste gedrückt hält während dem   man die Objekte über Mausklicks auswählt.  3.2.1. Verschiebung  In  den  Translations‐Modus  gelangt  man  durch  Drücken  der  Taste  V  oder  durch  Anklicken  des  Translate‐Buttons  in  der  Spatial‐Werkzeugleiste.  Danach  erscheinen  farbige  Achsen‐Markierungen  (mit einem Pfeil am Ende) am ausgewählten Objekt.  Um das Objekt zu verschieben kann man die WASD‐Tasten oder die Maus benutzen. Mit der Maus  klickt  man  auf  das  Objekt  und  zieht  die  Maus  bei  gedrückt  gehaltener  Taste  an  die  gewünschte  Position.  Dabei  bleibt  die  Ursprungsposition  durch  die  Achsen‐Markierungen  sichtbar,  um  eine  bessere Vorstellung der Verschiebung zu erhalten (siehe Abbildung 8)  Klickt man beim Verschieben direkt auf eine Achse, so verschiebt man das Objekt nur entlang dieser  Achse.  3.2.2. Skalierung  In  den  Skalierungs‐Modus  gelangt  man  durch  Drücken  der  Taste  X  oder  durch  Anklicken  des  Scale‐ Buttons in der Spatial‐Werkzeugleiste.  Auch  hier  erscheinen  wieder  farbige  Achsen‐Markierungen  (mit  einer  Box  am  Ende)  am  ausgewählten  Objekt  und  man  skaliert  nun  analog  zur  Translation  über  die  WASD‐Tasten  oder  die  Maus. Man skaliert allerdings immer nur entlang einer Achse. Mit der linken Maustaste ist dies die X‐ Achse, mit der mittleren Maustaste die Y‐Achse und mit der rechten Maustaste die Z‐Achse.  3.2.3. Rotation  In den Rotations‐Modus gelangt man durch Drücken der Taste  C  oder  durch  Anklicken  des  Rotate‐Buttons  in  der  Spatial‐ Werkzeugleiste.  Im  Rotationsmodus  werden  die  Rotationsachsen  durch  farbige, kreisförmige Bänder dargestellt (siehe Abbildung 10).  Die  Rotation  erfolgt  analog  zur  Skalierung  über  die  einzelnen  Maustasten. 

Abbildung 8 ‐ Verschiebung 

 

  16 

 
Abbildung 9 ‐ Skalierung           Abbildung 10 ‐ Rotation 

Alternativ  kann  man  die  Transformationen  auch  numerisch  über  den  Eigenschaften‐Inspektor  des  jeweiligen Objektes in der Kategorie Local Transform und Spatial eingeben. Local Scale, Rotation und  Position  sind  dabei  immer  relativ  zum  übergeordneten  Objekt  in  der  Szenenhierarchie.  Wenn  Objekte  die  Eigenschaften  von  übergeordneten  Objekten  nicht  erben  soll,  so  muss  man  im  Eigenschaften‐Inspektor  in  der  Kategorie  Spacial  unter  Inherit  die  entsprechenden  Häkchen  entfernen.   

3.3.  

Werkzeuge  zum  Dupli­ zieren und Anordnen 

Blade3D  stellt  einige  Werkzeuge  zum  duplizieren  und  anordnen  von  Objekten  nach  bestimmten  Parametern  bereit.  Um  die  Werk‐ zeuge  zu  nutzen,  klickt  man  im  Szeneneditor  mit  der  rechten  Maustaste  auf  das  Objekt  und  wählt  im  aufklappenden  Menü  das  Werkzeug  aus.  3.3.1. Duplicate Grid  Dieses  Werkzeug  erzeugt  mehrere  Instanzen  von einem Objekt und platziert diese auf einem  Gitter. 

 

Abbildung 11 ‐ Duplicate Grid

  17 

Die  Parameter  Spalten  und  Zeilen  (Columns  und  Rows)  bestimmen  die  Anzahl  der  Duplikate.  Item  Spacing bestimmt den Abstand der einzelnen Duplikate. Über die verschiedenen Variation‐Parameter  kann man die Größe und die Rotation der erzeugten Objekte zufällig bestimmen. 

 
Abbildung 12 ‐ Duplicate Grid 5x5 mit Größenvariation 

3.3.2. Duplicate SRT  Dieses  Werkzeug  erzeugt  Instanzen  von  einem  Objekt  und setzt die Positions, Rotations‐ und Skalierungswerte  in Abhängigkeit der angegeben Schrittweite. Die Schritt‐ weiten werden jeweils zu der Position, der Rotation und  der  Skalierung  jeder  neuen  Instanz  hinzuaddiert.  Auch  hier  kann  man  die  Schrittweiten  über  die  Variation‐ Parameter variieren. Der Parameter Count bestimmt die  Anzahl der Instanzen. 

 
Abbildung 13 – Duplicate SRT mit 8 Instanzen und kleiner  werdender Skalierung 

   
Abbildung 14 ‐ Duplicate SRT 

  18 

3.3.3. Duplicate Around  Dieses Werkzeug erzeugt mehrere Instanzen eines Objekts und platziert sie zufällig um ein anderes  Objekt in der Szene. 

 
Abbildung 15 ‐ Duplicate Around mit 8 Instanzen (Kugeln) und Radius 4 um einen Kegel     

 

  19 

4. Materialien und Effekte 
4.1.
  Materialien werden in Blade3D genutzt, um Effekte zu konfigurieren. Ein Effekt kann von mehreren  Materialien  genutzt  werden.  Das  Material  definiert  Einstellungen,  um  mit  dem  Effekt  einen  bestimmten Look zu erzielen. So ist in Blad3D z.B. der Standard‐Shader VertexLit.fx enthalten. Dieser  Shader  kann  Objekte  in  einer  beliebigen  Farbe  zeichnen.  Ein  Material,  welches  nun  diesen  Effekt  benutzt,  gibt  die  zu  verwendende  Farbe  an.  Der  Shader  kann  nun  unter  Verwendung  der  Einstel‐ lungen im Material, der Objektdaten (also die Koordinaten der zu zeichnenden Vertizes) und weiterer  globaler Parameter das Objekt zeichnen. 

Unterschied zwischen Material und Effekt 

HLSL­Effekt:    Einem  Effekt  liegt  eine  .fx‐Datei  zugrunde.  Diese  Datei  enthält  einen  HLSL‐Shader  (High  Level  Shading  Language)  und  alle  seine  Parameter.  Shader  sind  kleine  Programme,  geschrieben  in  einer  C‐ähnlichen  Syntax,  die  direkt  auf  dem  Grafik‐ kartenprozessor  ausgeführt  werden.  Dadurch  kann  ein  Großteil  der  Berechnung  von Grafik auf die darauf spezialisierte Grafikkarte ausgelagert werden.    Heutzutage unterstützen fast alle Grafikkarten programmierbare  Shader. Das XNA‐ Framework  schreibt  sogar  eine  Grafikkarte  mit  Shaderunterstützung  vor.  Da  Blade3D  auf  dem  XNA‐Framework  aufbaut,  müssen  alle  Objekte  durch  Shader  gezeichnet  werden.  Die  in  älteren  Grafikkarten  implementierte  sogenannte  Fixed‐ Function‐Pipeline wird nicht mehr unterstützt.

  4.2.
  Um  einen  neuen  Effekt  zu  Erstellen,  klicke  im  Objektbrowser  mit  der  rechten  Maustaste  auf  den  Ordner Effects und wähle New Effect. Ein neuer Effekt mit dem Namen Effect.fx wurde nun in dem  Ordner erstellt. Mit einem Doppelklick auf den Effekt wird dieser im Effekteditor geladen.  Es  wird  bereits  standardmäßig  ein  recht  umfangreicher  HLSL‐Shader  geladen,  wie  man  im  Effekteditor  erkennen kann. Wir werden nun selber einen einfachen  Shader  schreiben und löschen  dazu  erstmal  den  gesamten  Shadercode  in  der  Effektdatei  Effect.fx.  Der  Shader  wird  am  Ende  ein  Objekt mit einer bestimmten Farbe und nicht schattiert zeichnen.  Hierzu benötigen wir als erstes eine Variable, die die Farbe, in der das Objekt gezeichnet wird, angibt: 
// Static Constants float3 DiffuseColor : DiffuseMaterialColor = {1.0f, 0.0f, 0.0f};

Einen Effekt erstellen 

Die Variable ist vom Typ float3 (also ein Vektor mit 3 Komponenten), heißt DiffuseColor, ist von der  Semantik  DiffuseMaterialColor  und  ist  standardmäßig  auf  (1,0,0),  also  Rot  (R,G,B)  gestellt.   

  20 

Semantiken  bieten  eine  Verknüpfung  von  Parametern  im  Shaderquellcode  mit  der  Blade3D‐ Oberfläche  und  internen  Prozessen.  So  hat  z.B.  die  Angabe  der  Farbe  als  DiffuseMaterialColor  zur  Folge,  dass  man  im  Material,  das  den  Effekt  nutzt  diese  Farbe  über  einen  Farbwähler  komfortabel  einstellen kann.  Für  die  Transformation  der  Vertizes  des  Objekts  auf  den  Bildschirm  benötigt  man  die  sogenannte  World View Projection‐Matrix, die Blade3D bereits fertig berechnet zur Verfügung stellt (sie wird aus  der Kamerablickrichtung und den Kameraeinstellungen berechnet): 
// Dynamic Constants float4x4 WorldViewProjection : WorldViewProjection;

Nun schreiben wir den Vertex‐Shader, der für jedes Vertize des Objektes ausgeführt wird. Vor dem  Vertex‐Shader muss man noch die Ausgabe des Shaders festlegen. In unserem Fall reicht die Ausgabe  der  transformierten  Position  des  Vertizes.  Dazu  legen  wir  eine  Struktur  mit  einem  Vektor  mit  4  Komponenten (vom Typ float4) mit dem Namen Pos  und der Semantik Position an. 
// Vertex Shader struct VS_OUTPUT { float4 Pos: Position; };

Der Vertex‐Shader bekommt als Eingabeparameter nur die Position des Vertize und soll eine Struktur  vom Typ VS_OUTPUT zurückgeben, die wir gerade definiert haben. 
VS_OUTPUT VertexShader(float4 inPos: Position)

Im  Vertex‐Shader  werden  wir  nur  eine  Variable  vom  Typ  VS_OUTPUT  anlegen  und  der  darin  enthaltene Vektor wird das Ergebniss einer Multiplikation der eingegebenen Position (inPos) mit der  anfangs definierten Matrix sein, d.h. die ursprüngliche Position des Vertizes wird auf den Bildschirm  transformiert. Diese transformierte Position wird zurückgegeben. 
{ VS_OUTPUT Out; Out.Pos = mul(inPos, WorldViewProjection); return Out; }

Nun  brauchen  wir  noch  den  Pixel‐Shader,  der  für  jedes  Pixel,  das  am  Ende  vom  Objekt  auf  dem  Bildschirm erzeugt wird, durchlaufen wird. Der Pixel‐Shader kann auch Eingabeparameter haben aber  dies  ist  in  unserem  einfachen  Beispiel‐Shader  nicht  nötig.  Der  Pixelshader  gibt  immer  einen  4‐ Komponenten‐Vektor zurück. Dieser bestimmt die Farbe (R,G,B) und als 4. Komponente den Alpha‐ Wert des Pixels, falls Alpha Blending aktiviert ist. Als Semantik wird hierfür COLOR0 verwendet. 
// Pixel Shader float4 PixelShader() : COLOR0

Der Pixel‐Shader gibt als Farbe, die nun auf dem Bildschirm gezeichnet wird nur die Farbvariable mit  einem Alpha‐Wert von 1 zurück: 
{ return float4(DiffuseColor, 1.0f);

 

  21 

}

Materialien  benutzen  immer  eine  bestimmte  Technik  eines  Effektes  und  eine  Technik  kann  aus  1  oder mehreren Passes bestehen. Ein Pass benutzt immer einen Vertex‐ und einen Pixel‐Shader und  setzt gegebenenfalls sogenannte Render States wie z.B. Alpha Blending.  Unser  Effekt  benötigt  nur  eine  Technik  mit  einem  Pass.  Die  Shader  werden  für  ein  bestimmtes  Shader‐Profil kompiliert. In unserem Falle der Vertex‐Shader für 1.1 (vs_1_1) und der Pixel‐Shader für  2.0 (ps_2_0). 
// Technique technique t0 { pass p0 { VertexShader = compile vs_1_1 VertexShader(); PixelShader = compile ps_2_0 PixelShader(); } }

Somit  ist  der  Effekt  fertig  und  er  sollte  fehlerfrei  kompilieren  (wird  automatisch  oder  explizit  über  Drücken von F12 gemacht). 

4.3.
 

Ein Material erstellen 

Nun muss man ein neues Material erzeugen, das den Effekt nutzt. Dazu klickt man mit der rechten  Maustaste  im  Objektbrowser  auf  den  Ordner  Materials  und  wählt  Create  und  klickt  im  nun  aufklappenden  Menü  den  soeben  erstellten  Effekt  Effect.fx  aus.  Das  nun  erstellte  Material  ist  im  Materialordner  sichtbar  und  heißt  verwirrenderweise  auch  Effect.fx.  Deshalb  ist  es  ratsam  es  umzubenennen, z.B. in MeinMaterial. Man kann nun ein neues Objekt erzeugen und im zugehörigen  Eigenschaften‐Inspektor in der Kategorie Material Info die Eigenschaft Material verändern  und hier  Mein Material einstellen. Sofort sieht man, wie das Objekt in roter Farbe im Szeneneditor gezeichnet  wird. Außerdem erscheint unter der Eigenschaft Material sofort die neue Eigenschaft Diffuse Color,  über die man die Farbe setzen kann, in der das Objekt gezeichnet werden soll. Die von uns erstellte  Technik mit dem Namen t0 ist auch unter der Eigenschaft Technique zu sehen. 

 
Abbildung 16 ‐ Der erstellte Effekt in Aktion 

 

  22 

Kompletter Shadercode des Effektes: 
// Static Constants float3 DiffuseColor : DiffuseMaterialColor = {1.0f, 0.0f, 0.0f}; // Dynamic Constants float4x4 WorldViewProjection: WorldViewProjection; // Vertex shader struct VS_OUTPUT { float4 Pos: Position; }; VS_OUTPUT VertexShader(float4 inPos: Position) { VS_OUTPUT Out; Out.Pos = mul(inPos, WorldViewProjection); return Out; } // Pixel shader float4 PixelShader() : COLOR0 { return float4(DiffuseColor, 1.0f); } // Technique technique t0 { pass p0 { VertexShader = compile vs_1_1 VertexShader(); PixelShader = compile ps_2_0 PixelShader(); } }

   

 

 

  23 

5. Verhalten integrieren 
  Blade3D ermöglicht die Implementation von Spiel‐Logik in einer visuellen Art und Weise durch Logik‐ Diagramme oder klassisch durch Skripte und Makros. 

5.1.
 

Logik­Diagramme 

Mit  Logik‐Diagrammen  erstellt  man  intuitiv  Spiel‐Logik  durch  Verknüpfen  von  bestimmten  Eigenschaften  der  Blade3D‐Objekte.  Um  ein  Diagramm  zu  erstellen,  klickt  man  mit  der  rechten  Maustaste  im  Objektbrowser  auf  den  Ordner  Graphs  und  wählt  Create/Logic  Diagramm.  Im  Szeneneditor sieht man das Diagramm‐Fenster halbtransparent vor der eigentlichen Szene. In diesem  Fenster  werden  die  einzelnen  Objekte  angeordnet  und  miteinander  verbunden.  Man  kann  durch  gedrückt halten der linken Maustaste die Ansicht des Diagramms verschieben und mit dem Mausrad  raus‐  und  reinzoomen.  Man  kann  die  Größe  des  Fensters  ändern  indem  man  auf  eine  Ecke  des  weißen  Randes  linksklickt,  die  Maustaste  gedrückt  hält  und  die  Maus  bewegt.  Das  Fenster  ist  nur  sichtbar, wenn das Logik‐Diagramm im Objektbrowser ausgewählt ist. Will  man das Diagramm also  ausblenden, so genügt es ein anderes Objekt auszuwählen.  Um  auf  ein  Objekt  in  einem  Diagramm  zuzugreifen  zieht  man  es  einfach  bei  gedrückter  linker  Maustaste  vom  Objektbrowser  in  das  Diagramm‐Fenster.  Man  sieht  nun  das  Objekt  mit  seinen  Eigenschaften  im  Diagramm.  Jede  Eigenschaft  hat  dabei  einen  Eingang  auf  der  linken  und  einen  Ausgang auf der rechten Seite. Man kann somit jede Eigenschaft eines Objektes durch eine andere  Eigenschaft eines anderen Objektes durch Verknüpfen der Ein‐ und Ausgänge steuern. 

 
Abbildung 17 ‐ Das Standard‐Kamerasteuerungs‐Diagramm 

Will  man  2  Eigenschaften  verknüpfen,  so  zieht  man  mit  gedrückt  gehaltener  linker  Maustaste  vom  Ausgang des einen Objektes zum Eingang des anderen Objektes. Ein Pfeil verbindet nun die beiden   
  24 

Eigenschaften.  Beim  Ziehen  der  Verbindung  blinken  alle  Eingänge  die  denselben  Datentyp  verwenden  grün  und  alle  Eingänge  die  einen  Typ  verwenden  in  den  der  Ausgangstyp  konvertiert  werden kann blinken orange. Man kann also nur Eigenschaften verbinden die denselben oder einen  konvertierbaren Typ enthalten. Eine bereits bestehende Verbindung ist durch einen orangenen Pfeil  gekennzeichnet.  Man  kann  die  Objekte  frei  positionieren,  indem  man  sie  bei  gedrückt  gehaltener  linker  Maustaste  verschiebt. Die Verbindungen bleiben dabei erhalten. Um eine Verbindung zu löschen, klickt man mit  der rechten Maustaste auf sie und wählt Delete Connection.  Logik‐Diagramme sind immer aktiv, d.h. sie werden einmal pro Frame ausgeführt. 

5.2.
 

Skripte 

Skripte werden bei bestimmten Ereignissen, wie z.B. Mausklicks, Tastendrücken oder wenn sich eine  Eigenschaft eines Objektes ändert, ausgeführt. Skripte sind immer an bestimmte Objekte gebunden.  Sie werden in einer C#‐ähnlichen Syntax geschrieben.  Um ein Skript zu erzeugen, klickt man mit der rechten Maustaste auf ein Objekt im Objektbrowser  und wählt Add Script. Danach öffnet sich ein Fenster, indem man auswählt, bei welchem Ereignis das  Skript ausgewählt wird. Unter der Kategorie Events findet man die gängigen Ereignisse wie OnUpdate  und  OnMouseClick  usw.  und  in  den  restlichen  Kategorien  kann  man  eine  Eigenschaft  des  Objektes  auswählen.  Wählt  man  eine  Eigenschaft,  so  wird  das  Skript  immer  ausgeführt,  wenn  sich  diese  Eigenschaft ändert. Nach Klicken auf Ok wird das Skript als ein grüner Kreis im Objektbrowser unter  dem Objekt angezeigt. Klickt man auf das Skript im Objektbrowser, so öffnet sich der Skripteditor und  lädt das Skript. Standardmäßig ist ein erstelltes Skript nicht leer, sondern enthält eine Anweisung, die  beim  Auslösen  des  Skripts  eine  kurze  Textnachricht  in  das  Ausgabefenster  schreibt.  So  kann  man  immer  im  Ausgabefenster  sehen  (das  Ausgabefenster  öffnet  sich,  wenn  man  unterhalb  des  Skripteditors auf Output klickt), wann das Skript ausgeführt wurde.  Im  Skripteditor  kann  man  nun  das  Skript  auf  der  rechten  Seite  eingeben  oder  zu  einem  anderen  Skript  durch  Klicken  auf  den  zugehörigen  Namen  in  der  linken  Liste  wechseln.  Die  Skripte  werden  durch Drücken von F12 oder wenn man den Skript‐Editor schließt, kompiliert. 

5.3.
 

Makros 

Für  kleine  und  häufig  vorkommende  Aufgaben,  wie  Eigenschaften  auf  einen  bestimmten  Wert  zurücksetzen,  Eigenschaften  auf  zufällige  Werte  setzen oder Sounds und Animationen abzuspielen,  bieten sich Makros an.  Um  ein  Makro  zu  erstellen,  klickt  man  mit  der  rechten  Maustaste  auf  den  Ordner  Macros  im  Objektbrowser  und  wählt  Create  und  einen  Makro‐Typ.  Der  Typ  Set  Value  Macro  setzt  eine  Eigenschaft   

  25 

eines  Objektes  auf  einen  bestimmten  Wert.  Man  gibt  im  Objektbrowser  des  Makros  unter  Target  Instance  das  Objekt  und  unter  Target  Property  die  zu  setzende  Eigenschaft  des  Objektes  an.  Unter  Time kann man eine Zeitverzögerung angeben und unter Interpolate kann man die Interpolation hin  zum  Zielwert  aktivieren.  Unter  dieser  Eigenschaft  stellt  man  den  Wert  ein,  auf  den  die  Objekteigenschaft  beim  Aktiviren  des  Makros  gesetzt  oder  interpoliert  werden  soll.  Man  kann  ein  Makro  aktivieren,  indem  man  in  der  Kategorie  Macro  unter  der  Eigenschaft  Active  auf  den  Button  klickt oder indem man diese Eigenschaft in einem Skript auf true setzt. Nach Ausführen des Makros  wird die Active‐Eigenschaft wieder auf false gesetzt.  Die Makro‐Typen Sound und Animation spielen einen Sound oder eine Animation eines Modells ab.  Der  Typ  Compound  Macro  ist  eigentlich  kein  eigenständiges  Makro.  Man  kann  andere  Makros  innerhalb  eines  Compound  Macros  erzeugen  (durch  Rechtsklicken  auf  das  Makro  und  wählen  von  Create  und  dem  Makro‐Typ).  Wird  nun  das  übergeordnete  Compound  Macro  aktiviert,  so  werden  auch alle anderen enthaltenen Makros aktiviert.  Einem  Random  Macro  kann  man  ähnlich  dem  Compound  Macro  Makros  unterordnen.  Beim  Aktivieren des Random Macros wird dann zufällig ein untergeordnetes Makro aktiviert.     

 

 

  26 

6. Soundsystem 
  Blade3D  enthält  ein  einfaches  Soundsystem.  Man  kann  Sounds  der  Szene  hinzufügen,  sie  mit  Effekten versehen und bei bestimmten Ereignissen auslösen. 

6.1.
 

Samples und Sounds erstellen 

Um ein Sample, also eine Sounddatei in dem Format .wav (die Formate .ogg, .mp3, .mod, .it, .s3d und  .xm  sollen  später  noch  unterstützt  werden)  zu  laden,  klicke  mit  der  rechten  Maustaste  im  Objektbrowser  auf  den  Ordner  Audio/Samples,  klicke  dann  auf  Import  Samples  und  wähle  im  darauffolgenden Datei‐Dialog eine Sound‐Datei aus. Die Datei befindet sich nun im Ordner Samples.  Per  Doppelklick  wird  die  Datei  einmal  abgespielt  (jedoch  maximal  20  Sekunden  lang).  Will  man  die  Datei in voller Länge hören, so muss man darauf rechtsklicken und im Menü Preview wählen.  Jetzt kann man einen Sound erstellen, der dieses Sample  nutzt.  Das  Verhältnis  zwischen  Samples  und  Sounds  ist  ähnlich dem zwischen Effekten und Materialien. Mehrere  Sounds können ein Sample nutzen aber mit unterschied‐ lichen  Einstellungen  und  Effekten  abspielen.  Um  den  Sound  zu  erstellen  klickt  man  rechts  auf  den  Ordner  Audio/Sounds  im  Objektbrowser  und  wählt  Create/Sound.  Öffne  nun  den  Eigenschaften‐Inspektor  des  eben  erzeugten  Sounds  mit  Rechtsklick  darauf  und  Abbildung 18 ‐ Soundeigenschaften  Open  Property  Sheet.  Wähle  in  der  Eigenschaft  Sample  das zuvor erstellte Sample aus.  Hinweis:  Alternativ  kann  man  auch  einfach  das  erstellte  Sample  bei  gedrückter  linker  Maustaste  in  den Sounds‐Ordner ziehen.  Ein Sound hat die Eigenschaften Sample, Volume (Lautstärke), Max Duration (maximale Abspiellänge,  standardmäßig auf ‐1 für Abspielen in voller Länge gesetzt) und Loop (ob der Sound in Endlosschleife  gespielt werden soll).  Um dem Sound einen Effekt hinzuzufügen, klicke rechts auf  den  Sound  im  Objektbrowser  und  wähle  Create  und  den  gewünschten Effekt. Es gibt Effekte wie z.B. Echo (ein kurzer  Hall),  Reverb  (Hall),  Compressor  (Dynamik‐Kompressor),  Distortion (Verzerrung) oder Parametric EQ (parametrischer  Equalizer).  Jeder  Effekt  bietet  dabei  weitgehende  Einstell‐ möglichkeiten (siehe die Blade3D‐Wikipedia).  Es  können  einem  Sound  beliebig  viele  Effekte  zugewiesen  werden. 

Samples  und  Sounds  können  in  Containern  verwaltet  werden.  Diese  entsprechen  Unterordnern  im  jeweiligen  Samples‐ oder Sound‐Ordner. Einen Sample‐Container erzeugt man durch einen Rechtsklick auf den   
  27 

Abbildung 19 ‐ Einstellmöglichkeiten des  Echo‐Effekts 

Samples‐Ordner  und  Create/Sample  Container.  Einen  Sound‐Container  erzeugt  man  durch  einen  Rechtsklick auf den Sounds‐Ordner und Create/Sound Container/Sound Container. Als Spezialfall kann  man  hier  alternativ  auch  einen  Random  Sound  Container  über  Create/Sound  Container/Random  Sound Container. Die in diesem Ordner enthaltenen Sounds können zufällig abgespielt werden. 

6.2.
 

Sounds in der Szene verwenden 

Sounds können durch Sound‐Trigger oder durch Skripte abgespielt werden.  6.2.1. Sound­Trigger  Ein  Sound‐Trigger  spielt  einen  Sound  ab,  wenn  die  Kamera  einen  bestimmten  Bereich  betritt  oder  wieder  verlässt.  Um  einen  Sound‐Trigger  zur  Szene  hinzuzufügen  klickt  man  mit  der  rechten  Maustaste  auf  den  Scene‐Ordner  im  Objektbrowser  und  wählt  Create/Trigger  Volume/Sound  Trigger/Sound  Trigger.  Man  sieht  nun  den  Bereich  des  Triggers  im  Szeneneditor  durch  einen  roten  Quader gekennzeichnet. Diesen kann man nun ganz normal positionieren, rotieren und skalieren.  Achtung:  Man  muss  den  Trigger  immer  im  Objektbrowser  auswählen,  da  er  im  Szeneneditor  unsichtbar ist, wenn er nicht selektiert ist. 

 
Abbildung 20 ‐ Sound Trigger‐Hüllquader und Eigenschaften 

Im Eigenschaften‐Inspektor des Triggers stellt man den Sound ein, der beim Betreten (Enter Sound)  und  beim  Verlassen  (Leave  Sound)  abgespielt  werden  soll.  Die  Eigenschaft  Kill  Sound  OnExit  bestimmt,  ob  der  Enter  Sound  gestoppt  werden  soll,  wenn  der  Bereich  verlassen  wird.  Man  kann  statt  eines  bestimmten  Sounds  auch  einen  Random  Sound  Container  angeben.  Dann  wird  immer  zufällig ein Sound aus dem Container ausgewählt.  6.2.2. Sound­Skript  Hier folgt ein kleines Beispiel, wie man einen Sound mithilfe eines Skriptes abspielt.  Füge der Szene ein Objekt, wie z.B. eine Kugel, hinzu. Klicke im Objektbrowser auf die Kugel mit der  rechten Maustaste und wähle Add Script. Wähle im nun folgenden Dialog das Mouse Down‐Ereignis.  Wähle  im  Skripteditor  das  eben  erstellte  OnMouseDown‐Skript  aus.  Füge  dem  Skript  folgende  Anweisungen hinzu: 
IObject sounds = context.Site.GetObject("#Module/Audio/Sounds"); IBlade3DSound sound = (IBlade3DSound) sounds.GetChild(0).Extension; sound.Play();

 

  28 

Drücke F12 zum Kompilieren des Skripts. Beim Klicken auf die Kugel wird nun der Sound abgespielt.  In  der  ersten  Zeile  wird  eine  Referenz  auf  alle  Sound‐Objekte  in  dem  angegebenen  Verzeichnis  erstellt. In der zweiten Zeile wird aus diesen Sound‐Objekten das erste ausgewählt und in der dritten  Zeile abgespielt.   

 

 

  29 

7. Blade3D­Funktionalität erweitern 
  In diesem Abschnitt wird gezeigt, wie man mit Visual C# Express 2005 einen Operator schreibt, der in  die Blade3D‐IDE eingebunden wird und den man in Logikdiagrammen nutzen kann. Der Operator soll  den Absolutwert einer Zahl berechnen.  Man  erstellt  in  C#  Express  ein  neues  Class  Library‐Projekt.  Man  löscht  den  Quellcode  der  bereits  erzeugten  Klasse.  Zuerst  benötigt  man  den  Standardnamensraum  System  sowie  den  Blade3D‐ Namensraum. 
using System; using Blade3D.Runtime.Extensibility;

Dann  kommt  der  Namensraum,  indem  die  nachfolgenden  Klassen  definiert  werden,  z.B.  OperatorTutorial. Außerdem definiert man eine Klasse in der die als statische Funktionen realisierten  Operatoren enthalten sind. 
namespace OperatorTutorial { [OperatorGroup(Description = "Meine neuen Operatoren")] public class MeineOperatoren {

Die  Zeile  in  eckigen  Klammern  über  dem  Klassennamen  ist  ein  Attribut,  das  weitere  Informationen  zur  Klasse  enthält,  die  zur  Laufzeit  abgerufen  werden  können.  In  diesem  Fall  ist  die  Klasse  eine  Gruppe von Operatoren (OperatorGroup) mit einer Beschreibung, die später in Blade3D direkt in der  Umgebung  angezeigt  wird.  Als  nächstes  folgt  eine  statische  Methode  zur  Berechnung  des  Absolutwertes einer Gleitkommazahl. 
[Operator(Description = "Berechnet den Absolutwert eines Floats")] public static void Abs( [OperatorParameter(Description = "Wert.", DefaultValue = "0")] float wert, [OperatorParameter(Description = "Ergebnis.")] out float ergebnis )

Die Funktion heißt Abs und ist durch das Attribut als Operator gekennzeichnet. Die Funktionen hat  einen Ein‐ (wert) und einen Ausgabeparameter (ergebnis). Diese Parameter sind als solche durch das  Attribut OperatorParameter gekennzeichnet.  Der eigentliche Methodenquellcode folgt nun: 
{ ergebnis = Math.Abs(wert); }

Man kann nun in dieser Operatoren‐Gruppe weitere Operatoren definieren wie z.B. die Berechnung  des Absolutwertes einer Ganzzahl: 
[Operator(Description = "Berechnet den Absolutwert eines Ints")] public static void IAbs( [OperatorParameter(Description = "Wert.", DefaultValue = "0")] int wert, [OperatorParameter(Description = "Ergebnis.")]

 

  30 

out int ergebnis ) { ergebnis = Math.Abs(wert); }

Die Klasse und der Namensraum müssen noch geschlossen werden. 
} }

Das  Projekt  kann  nun  kompiliert  werden  und  es  wird im Projektverzeichnis eine .dll‐Datei erzeugt.  Diese muss nun nur noch in das Blade3D‐Installa‐ tionsverzeichnis  kopiert  werden  (standardmäßig  Programme/Digini/Blade3D/).  Blade3D  muss  erst  neu  gestartet  werden  bevor  der  Operator  zur  Abbildung 21 ‐ Die Operatoren im Auswahlmenü Verfügung steht.  Um den Operator einem Logikdiagramm hinzuzufügen, klickt man darin mit der rechten Maustaste  und  wählt  Create.  In  der  aufklappenden  Liste  findet  sich  der  Punkt  Meine  Operatoren,  indem  die  beiden erstellten Operatoren zu finden sind. Man kann den Operator nun in einem Logik‐Diagramm  nutzen. 

 
Abbildung 22 ‐ Der Operator im Logik‐Diagramm 

 

 

 

  31 

8. Online­Hilfe 
  Die Online‐Hilfe ist jederzeit durch Drücken von F1 erreichbar. Je nachdem welcher Bereich gerade  aktiv ist oder welches Objekt gerade ausgewählt ist, wird kontextsensitiv die entsprechende Seite in  der Dokumentation angezeigt.  Ist gerade ein Objekt aktiv, so wird eine kurze Erklärung des Objektes sowiel alle seine Eigenschaften  und von welchen Basis‐Klassen es abgeleitet ist, angezeigt. Viele Objekte enthalten außerdem  eine  kurze Einführung wie man sie erstellt und auch verwendet.  Über den Help Home‐Button in der Hilfe‐Werkzeugleiste kommt man zur Startseite der Online‐Hilfe.  Hier  findet  man  eine  Schnelleinführung  in  die  Bedienung  von  Blade3D  (Quick  Start),  Tutorials,  Beispiele (Samples) und freie Texturen und Modelle.  Die  Samples  lassen  sich  durch  Klicken  auf  das  Sample‐Bildchen  direkt  runterladen  und  installieren.  Das Sample ist nach dem Herunterladen bereits fertig in Blade3D geladen.  Video‐Tutorials können auch direkt im Hilfe‐Fenster angeschaut werden. So kann man gleich selber  die Schritte des Tutorials nachvollziehen. 

 
Abbildung 23 ‐ Die Startseite der Online‐Hilfe in der Blade3D‐Umgebung 

Desweiteren gibt es noch eine sehr schnell wachsende Wiki zu Blade3D. Diese ist unter  http://wiki.blade3d.com zu erreichen.   

 

 

  32 

9. Tutorial: Pong­Spiel 
  Im  diesem  Abschnitt  wird  gezeigt,  wie  man  Blade3D  in  der  Praxis  einsetzt.  Dies  wird  durch  die  Erstellung  eines  einfachen  Pong‐Spiels  gezeigt.  In  dem  Spiel  muss  man  versuchen  eine  Kugel  durch  Steuerung von 2 Schlägern auf dem Spielbrett zu halten.  Zu Beginn erstellt man ein neues Modul über das Dateimenü und Klicken auf New Module. Wichtig:  Speichere das Modul von Zeit zu Zeit ab. 

9.1.
 

Das Spielbrett 

Als  erstes  erzeugt  man  eine  neue  Klasse,  um  das  Spielbrett  zu  repräsentieren.  Rechtsklicke  auf  den  Ordner Types im Objektbrowser und wähle Add Type.  Gib den Namen PongBoard und wähle No Base Type  unter Categories.  Nun  sieht  man  den  Pong  Board‐Typ  unter  Types  im  Objektbrowser. Um der Klasse eine neue Eigenschaft  hinzuzufügen,  in  diesem  Falle  eine  Gleitkommazahl,  klicke  rechts  auf  Pong  Board  und  wähle  Create/Property/Single.  Ändere  den  Namen  der  Eigenschaft  auf  Breite.  Doppelklicke  auf  die  Eigenschaft,  um  den  Eigenschaften‐Inspektor  zu  öffnen.  Ändere  die  Werte  wie  in  Abbildung  25  gezeigt. 
Abbildung 24 ‐ Erstellen einer neuen Klasse 

Um  diese  Eigenschaft  leicht  verändern  zu  könnnen,  ändert man unter der Kategorie Property die Eigenschaft In  Place Editor in slider.  

  Man kann  nun von der Board‐Klasse eine Instanz erzeugen,  indem  man  auf  den  Ordner  Instances  rechtsklickt  und  Create/Pong Board wählt.  Wenn  man  auf  die  Instanz  doppelklickt,  sieht  man  die  Abbildung 25 ‐ Eigenschaft Breite  Breite‐Eigenschaft auf einem Wert von 15.4 und einem Slider für den Bereich 1 bis 100 so wie man es  vorher in der Klasse eingestellt hat.  Wenn  man  die  Klasse  verändert,  so  werden  alle  Änderungen  von  den  Instanzen  der  Klasse  übernommen.  Rechtsklicke  auf  die  Breite‐Eigenschaft  der  Board‐Klasse  und  wähle  Duplicate.  Dies  dupliziert  die  Eigenschaft.  Ändere  den  Namen  auf  Höhe.  Öffne  den  Eigenschaften‐Inspektor  und  ändere Default Value auf 12. Die restlichen Eigenschaften wurden bereits von Breite übernommen.   

  33 

Öffnet man den Eigenschaften‐Inspektor der Instanz des Boards so sieht man die eben  zur Klasse hinzugefügte Eigenschaft Höhe mit dem Wert 12.  Man fügt der Szene nun ein Grid‐Objekt hinzu, um das Board zu repräsentieren. Dazu  klickt man auf das Grid‐Icon in der Scene‐Werkzeugleiste. Jetzt sieht man ein Rechteck  in  der  Mitte  der  Szene  im  Szeneneditor.  Ändere  den  Namen  des  Grids  in  PongBoardGrid.  Öffne  dessen Eigenschaften und setze beiden Subdivision‐Eigenschaften auf 1. Ändere IsSelectable auf false  in der Spatial‐Kategorie.  Nun  verbindet  man  das  Grid  mit  der  Board‐Klasseninstanz,  damit  das  Grid  die  Eigenschaften  der  Instanz  erbt.  Dazu  erzeugt  man  ein  neues  Logik‐Diagramm  durch  Rechtsklicken auf den Ordner Graphs und wählen von Create/Logic  Diagramm.  Ändere  den  Namen  des  Diagramms  in  PongBoardSetup.  Öffne  das  Diagramm  durch  Anwählen  des  erzeugten  Diagramms  im  Objektbroswer.  Ziehe  nun  bei  gedrückt  gehaltener  Maustaste  die  Board‐Instanz  in  das  Diagramm.  Jetzt  sieht  man  die  Board‐Instanz  als  Rechteck  im  Diagramm.  Dabei  sind  die  beiden  Eigenschaften  Breite  und  Höhe  mit  jeweils  einem  Ein‐  und  einem  Ausgang  zu  sehen.  Schiebe  die  Board‐Instanz  auf  die  linke  Seite  des  Diagramms.  Ziehe  nun  das  Game  Board  Grid  in  das  Diagramm  und  platziere  es  auf  der  rechten  Seite.  Ziehe  einen  Pfeil  vom  Ausgang  der  Breite‐Eigenschaft  der  Board‐Instanz  zum  Eingang  der  Length  U‐Eigenschaft  des Game Board Grids. Führe denselben Schritt für  die Höhe durch  und verbinde sie mit Length V.  Das Grid übernimmt nun sofort die Eigenschaften für Höhe und Breite von der Board‐Instanz. 

 
Abbildung 26 ‐ Die Kamera schaut nun auf das Board 

 

  34 

Nun  ändert  man  die  Szeneneigenschaften,  sodass  man  direkt  von  oben  auf  das  Board  schaut.  Doppelklicke  auf  den  Scene‐Ordner  zum  Anzeigen  der  Szeneneigenschaften.  In  der  Kategorie  ViewportBase ändere DrawFloor auf false.   Dies  versteckt  das  standardmäßig  angezeigte  Bodengitter.  Doppelklicke  auf  das  Camera‐Objekt  im  Objektbrowser  unter  Scene.  Setze  die  Local  Position auf  0, 10, 0 und die Local Rotation auf  0, 0, ‐90 wie in Abbildung 26.  Jetzt  erstellt  man  ein  Material  für  das  Board.  Materialien  sind  Instanzen  von  Effekten.  Erzeuge ein neues Material durch Rechtsklicken  auf  den  Materials‐Ordner  und  Wählen  von  Create/Basic/GUI.fx.  Dies  ist  ein  einfacher  Effekt.  Er  benutzt  eine  Textur  und  eine  optionale Angabe zur Durchsichtigkeit (Opacity).  Man  sieht  nun  ein  neues  Material  mit  dem  Namen  GUI.fx.  Ändere  den  Namen  des  Materials  in  GameBoardMaterial.  Öffne  die  Eigenschaften  des  Game  Board  Grids.  Stelle  Material  Info‐Kategorie  unter  Material  das  eben  erzeugte  Material  ein.  Daraufhin  ändern  sich  die  Einstellmöglichkeiten unter dem Materialnamen und man kann eine Textur für das Board auswählen,  z.B. MarbleTile.vtf unter MyModule/Textures/Samples.  Nun  wird  die  Kamerasteuerung  deaktiviert.  Öffne  dazu  die  Kamera‐Eigenschaften.  Klicke  unter  der  Active Rigid Body‐Kategorie bei der Eigenschafte Force Controller auf den kleinen blauen Kreis links,  um die Eigenschaft auf <Unbound> zu setzen. 

9.2.
 

Schläger erstellen 

Nun werden 2 Schläger erstellt. Diese werden wieder als Grid dargestellt. Füge ein weiteres Grid der  Szene hinzu. Ändere den Namen in LinkerSchläger und öffne die Eigenschaften des Grids. Setze beide  Subdivision‐Eigenschaften auf 1. Setze Length U auf  0.5  und  Length  V  auf  2.5.  Setze  die  Local  Position  auf  ‐7,  0.01,  0.  Nun  fügt  man  dem  Schläger  noch  ein  Material  zu.  Dazu  erzeugt  man  ein  neues  Material  durch  Rechtsklicken  auf  den  Materials‐ Ordner  und  Wählen  von  Create/Basic/Text.fx.  Benenne das Material mit SchlägerMaterial. Weise  dem  linken  Schläger  das  Material  zu.  In  der  MaterialInfo‐Kategorie  der  Schläger‐Eigenschaften  mache  folgende  Einstellungen:  setze  UVScale  auf  0.5 und 2.5, ändere Use Vertex Color auf false, um  die  Textur  sichtbar  zu  machen,  wähle  eine  Textur  aus,  z.B.  Stone.vtf  unter  MyModule/Textures/  Samples. 

 

  35 

Erzeuge  von  dem  Schläger  eine  Kopie  durch  Rechtsklicken  auf  den  Schläger  im  Objektbrowser  und  Wählen  von  Duplicate.  Ändere  den  Namen  des  neu  erzeugten  Schlägers  auf  RechterSchläger  und  öffne seinen Eigenschaften‐Inspektor. Setze die Eigenschaften UVScale, Use Vertex Color und Diffuse  Texture  genauso  wie  beim  linken  Schläger.  Setze  die  lokale  Position  auf  7,  0.01,  0.  Damit  wird  der  Schläger an den rechten Rand des Brettes verschoben.  

 
Abbildung 27 ‐ Die PongGame‐Klasse 

Nun erstellt man eine neue Klasse, die die Spiel‐Logik beinhalten soll  und  klickt  dazu  mit  der  rechten  Maustaste  auf  Types  im  Objektbrowser und wählt Add Type. Nenne im erscheinenden Dialog  diese neue Klasse PongGame. Doppelklicke auf die Scenes‐Kategorie  auf  der  linken  Seite  und  wähle  auf  der  rechten  Seite  None  als  base  type und schließe den Dialog mit OK ab. Dieser Basistyp stellt bereits  eine  Update‐Funktion  zur  Verfügung,  in  der  die  eigentliche  Spiel‐ Logik  einmal  pro  Frame  ausgeführt  wird.  Nun  werden  der  neuen  Klasse  einige  Eigenschaften  hinzugefügt  die  zur  Steuerung  der  Schläger benötigt werden.  Füge  der  PongGame‐Klasse  eine  Eigenschaft  durch  Rechtsklicken  darauf  und  wählen  von  Create/Property/Vector3  zu.  Nenne  diese  Eigenschaft  LinkerSchlägerPosition.  Setze  in  der  Eigenschaft  die  Werte wie in Abbildung 28 und setze die Eigenschaft In Place Editor  auf slider.  Erstelle eine  Instanz  der eben erzeugten Klasse durch Rechtsklicken  auf den Scene‐Ordner und wähle Create/Scene Items/Pong Game. In 
Abbildung 28 

 

  36 

den Eigenschaften  der  Klassen‐ Instanz  im  Scene‐ Ordner  sieht  man  die  Werte  der  Schlägerposition.  Diese  kann  man  nun  in  einem  Logik‐Diagramm  mit  der  wirklichen  Abbildung 30 ‐ Diagramm Schläger Position Link Position  des  Schlägers  verbinden.  Dazu  erstellt  man  ein  neues  Logik‐ Diagramm und nennt es SchlägerPositionLink. In das geöffnete Diagramm  zieht  man  die  PongGame‐Instanz  und  posiert  sie  auf  der  linken  Seite.  Danach zieht man den linken Schläger in das Diagramm und platziert ihn  in  der  Mitte.  Verbinde  nun  die  beiden  Positionseigenschaften  wie  in  Abbildung 30. Wenn man nun die Eigenschaft Linker Schläger Position in  der Klasseninstanz ändert, so ändert sich auch die Position des Schlägers  auf dem Spielbrett.  Dupliziere  die  Linker  Schläger  Position‐Eigenschaft  und  nenne  sie  RechterSchlägerPosition.  Gib  die  Werte  wie  in  Abbildung  29  ein.  Ziehe  den  rechten  Schläger  in  das  Logik‐Diagramm  und  platziere  ihn  rechts  neben  dem  linken  Schläger.  Verbinde  die  Rechter  Schläger  Position‐ Eigenschaft mit der Local Position des rechten Schlägers.  Nun werden die Positionen der Schläger  Abbildung 29  durch  die  Klasse  gesteuert.  Die  Schlägergrößen sollen auch von der Klasse gesteuert werden. Dazu  erzeugt  man  in  der  PongGame‐Klasse  im  Ordner  Types  eine  neue  Eigenschaft  Create/Property/Single.  Nenne  diese  Eigenschaft  SchlägerBreite.  Setze  die  Werte  der  Eigenschaft  auf  0.5,  0.3,  1,  0.1  Abbildung 31  und wähle als In Place Editor wieder slider. Dupliziere die Eigenschaft  und nenne die Kopie SchlägerHöhe und setze die Eigenschaften auf  2.5,  0.5,  10,  0.1.  Verbinde  nun  in  dem  Schläger  Position  Link‐Diagramm  die  Eigenschaften  Schläger  Breite  und  Schläger  Höhe  mit  den  Eigenschaften  LengthU  und  LengthV  der  beiden  Schläger  wie  in  Abbildung 32. 

 
Abbildung 32 

 

  37 

Jetzt wird auch die Schlägergröße über die Klasse gesteuert. Dies wird bei der Kollisionserkennung  später noch nützlich sein. 

9.3.
 

Schläger bewegen 

Der Einfachheit wegen werden wir nur eine Ein‐Spieler‐Steuerung einbauen, d.h. wenn ein Schläger  nach oben bewegt, so bewegt sich der andere nach unten.  Erzeuge ein neues Logik‐Diagramm mit dem Namen SchlägerKontrolle. Ziehe die PongGame‐Instanz  in das Diagramm. Klicke in den Hintergrund des Diagramms. Dann klicke mit der rechten Maustaste  und  wähle  Create/Input  Operations/Combined  Control  Adapter.  Dies  ist  der  Eingabe‐Operator,  der  standardmäßig die Kamera steuert, d.h. er nimmt Eingaben der Tastatur, der Maus und des Xbox 360  Controllers  entgegen.  Füge  einen  weiteren  Operator  über  Create/Vector  2  Operators/Vector  2  To  Parts. Dieser Operator extrahiert die Y‐Komponente aus dem Ausgang Linear Thrust des Controllers.  Verbinde den Linear Thrust‐Ausgang mit dem DecomposeVector2‐Operator‐Eingang.  Außerdem werden die Werte der linken Schlägerposition benötigt. Man erzeugt dazu den Operator  Create/Vector3  Operators/Vector3  To  Parts  und  verbindet  diesen  mit  dem  Ausgang  Eigenschaft  Linker  Schläger  Position.  Die  Position  wird  durch  Tastatureingaben  verändert  und  wieder  an  die  Klasseninstanz zurückgegeben.   Erzeuge  den  Operator  Create/Math/Add  Floats  und  platziere  ihn  rechts  vom  DecomposeVector3‐ Operator.  Verbinde  den  Z‐Ausgang  des  DecomposeVector3‐Operators  mit  dem  A‐Eingang  des  Add  Floats‐Operators. Verbinde den Y‐Ausgang des DecomposeVector2‐Operators mit dem B‐Eingang des  Add  Floats‐Operators.  Erzeuge  einen  ComposeVector3‐Operator  (also  einen  Vector3  from  Parts‐ Operator, die beiden Bezeichnungen stehen für denselben Operator). Verbinde den Ausgang des Add 

 Abbildung 33 

  38 

Floats‐Operators mit dem Z‐Eingang des neuen ComposeVector3‐Operators. Verbinde nun die die X‐  und  Y‐Ausgänge  des  DecomposeVector3‐Operators  mit  den  jeweiligen  Eingängen  des  ComposeVector3‐Operators.  Abbildung  33  zeigt  das  Diagramm.  In  dem  Diagramm  nehmen  wir  uns  die Z‐Position (also der Schläger bewegt sich auf  und ab), addieren einen Wert abhängig  von einer  Tastatureingabe  und  bilden  daraus  die  resultierende  Position.  Nun  muss  der  Wert  der  Position  nur  noch  zurückgeschrieben  werden.  Dazu  zieht  man  noch  einmal  die  PongGame‐Instanz  in  das  Diagramm  und  positioniert  sie  auf  der  rechten  Seite.  Man  verbindet  den  Ausgang  des  ComposeVector3‐Operators  mit  dem  Eingang  der  Eigenschaft  Linker  Schläger  Position  der  2.  PongGame‐Instanz im Diagramm.   Nun  muss das selbe Verfahren auf den rechten Schläger angewendet werden. Nur der  Wert der in  Abhängigkeit  der  Tasteneingabe  addiert  wird  muss  negiert  werden,  damit  sich  der  Schläger  in  die  entgegengesetzte  Richtung  bewegt.  Erzeuge  im  selben  Diagramm  den  Operator  Vector2  Operators/Negate  Vector2.  Verbinde  den  Linear  Thrust‐Ausgang  mit  dem  Eingang  des  Negate  Vector2‐Operators  und  platziere  diesen  unterhalb  des  Decompose  Vector2‐Operators.  Füge  einen  weiteren  Decompose  Vector2‐Operator  hinzu  (über  Vector2  Operators/Vector2  To  Parts).  Verbinde  den  Ausgang  des  Negate‐Operators  mit  dem  Eingang  des  neuen  Decompose‐Operators  und  positioniere  ihn  rechts  des  ersten  Decompose  Vector2‐Operators.  Erzeuge  nun  eine  Decompose  Vector3‐Operator  und  platziere  ihn  unterhalb  des  anderen.  Verbinde  den  Ausgang  der  rechten  Schlägerposition mit dem Eingang des zweiten Decompose Vector3‐Operators. Erzeuge einen zweiten  Compose Vector3‐Operator und platziere ihn unterhalb des ersten. Verbinde die X‐ und Y‐Ausgänge  des  zweiten  Decompose  Vector3‐Operators  mit  den  jeweiligen  Eingängen  des  zweiten  Compose  Vector3‐Operators. Erzeuge einen weiteren Add Floats‐Operator und platziere ihn unter dem ersten.  Verbinde den Z‐Ausgang des zweiten Decompose Vector3‐Operators mit dem A‐Eingang des zweiten  Add Floats‐Operators. Verbinde den Y‐Ausgang des zweiten Decompose Vector2‐Operators mit dem 

 

Abbildung 34 

  39 

B‐Eingang  des  zweiten  Add‐Floats‐Operators.  Verbinde  den  Ausgang  des  zweiten  Add  Floats‐ Operators  mit  dem  Z‐Eingang  des  zweiten  Compose  Vector3‐Operators.  Verbinde  zum  Schluss  den  Ausgang  des  zweiten  Compose  Vector3‐Operators  mit  Eingang  der  Eigenschaft  Rechter  Schläger  Position der zweiten PongGame‐Instanz. Das Ergebniss ist in Abbildung 34 zu sehen.   Jetzt werden die Positionen der beiden Schläger  durch  Drücken  der  Tasten  W  und  S  oder  druch  Hoch  und  Runter  auf  dem  Xbox‐Controller  verändert.  Die  Bewegung  der  Schläger  ist  noch  zu  empfindlich  und  deswegen  werden  wir  noch  einen Geschwindigkeits‐Faktor in das Diagramm  einfügen.  Setze  vorher  die  Positionen  der  Schläger  durch  einen  Klick  auf  den  kleinen  Kreis  im  Eigenschaften‐Inspektor  der  PongGame‐Instanz  links neben zurück auf den Standardwert (siehe  Abbildung 35). 

Abbildung 35

Füge  der  PongGame‐Klasse  (im  Ordner  Types)  eine  neue  Eigenschaft  (Gleitkommazahl)  über  Create/Property/Single  hinzu  und  nenne  sie  SchlägerGeschwindigkeit. Setze die Werte der Eigenschaft auf 0.25, 0.01, 10, 0.05 und gib bei In Place  Editor slider ein. Man benutzt nun diese Eigenschaft, um die Tastatureingabe im Schläger Kontrolle‐ Diagramm  zu  skalieren.  Öffne  nun  dieses  Diagramm  und  rechtsklicke  nacheinander  auf  die  beiden  Verbindungen, die von Linear Thrust ausgehen und wähle Delete Connection, um die Verbindungen  zu löschen. Füge einen neuen Operator unter Create/Vector2 Operators/Vector2 Multiply ein, der 2  Vektoren multipliziert. Verbinde Linear Thrust von dem Combined Control Adapter mit dem Eingang  Vector  A  des  eben  erzeugten  Operators.  Verbinde  den  Ausgang  des  Multiply‐Operators  mit  den  Eingängen  der  Decompose  Vector2‐  und  Negate  Vector2‐Operatoren,  die  zuvor  mit  Linear  Thrust  verbunden waren.  Nun benötigt man nur noch einen weiteren Vector2 mit dem der andere Vektor skaliert wird. Dieser  neue  Vektor  wir  mithilfe  der  SchlägerGeschwindigkeit‐Eigenschaft  erzeugt.  Erzeuge  dazu  einen  weiteren  Operator  über  Create/Vector2  Operators/Vector2  From  Parts.  Verbinde  diese  Eigenschaft  von  PongGame  mit  dem  Y‐Eingang  des  neuen  Compose  Vector2‐Operators.  Verbinde  den  Ausgang  dieses Operators mit dem Eingang Vector B des Multiply Vector2‐Operators (siehe Abbildung 36).   Jetzt ist  die  Bewegung der Schläger deutlich langsamer und besser steuerbar als vorher. Man kann  die  Geschwindkeit  über  die  neue  Eigenschaft  Schläger  Geschwindigkeit  nach  belieben  anpassen.  Bisher verlassen die Schläger aber den Bildschirm, wenn man sie zu weit bewegt. Man limitiert nun  den Bewegungsbereich mithilfe des Update‐Skripts, das anfangs des Abschnitts bereits kurz erwähnt  wurde.  Rechtsklicke auf die PongGame‐Klasse und wähle Add Script und dann Update in der erscheinenden  Liste.  Es  erscheint  ein  neuer  Eintrag  unter  der  Klasse  mit  eine  grünen  Kreis  und  dem  Namen  OnUpdate.  Das  ist  das  neu  erzeugte  Skript‐Ereigniss.  Mit  einem  Linksklick  darauf,  wird  es  im  Skripteditor geöffnet. 

 

  40 

 
Abbildung 36 ‐ Das Schläger Kontrolle‐Diagramm 

Die erste Zeile in dem Skript, gibt immer wenn das Skript aktiviert wird die in Klammern angegebene  Zeichenkette  im  Ausgabefenster  aus.  Bisher  passiert  jedoch  noch  nichts,  weil  das  Skript  noch  nicht  aktiviert  wurde.  Um  dies  zu  erreichen,  öffne  die  Eigenschaften  der  PongGame‐Instanz  im  Scene‐ Ordner und gehe in die Kategorie Spatial. Setze die Eigenschaft Fire Update auf true. Jetzt wird die  das  Skript  mit  jedem  Frame  ausgeführt  und  das  Ausgabefenster  füllt  sich  mit  den  Ausgaben  des  Skriptes.  Lösche  die  erste  Zeile  des  Skriptes,  da  diese  für  die  Logik  nicht  notwendig  ist.  Speichere  die  Schlägerpositionen und die Schlägerhöhe in Variablen ab: 
Vector3 linkerSchlaegerPosition = (Vector3)context.Site["LinkerSchlägerPosition"]; Vector3 rechterSchlaegerPosition = (Vector3)context.Site["RechterSchlägerPosition"]; float schlaegerHoehe = (float)context.Site["SchlägerHöhe"];

Folgende Werte soll die Schlägerposition nie überschreiten: 
float maxSchlaegerZ = 7.0f; float minSchlaegerZ = -7.0f;

Überschreitet  die  Schlägerpositionen  die  festgelegten  Werte,  so  wird  die  Position  auf  die  Maximalposition in Abhängigkeit zur Schlägerhöhe gesetzt: 
if ((linkerSchlaegerPosition.Z + schlaegerHoehe) > maxSchlaegerZ) { linkerSchlaegerPosition.Z = maxSchlaegerZ - schlaegerHoehe;

 

  41 

} else if ((linkerSchlaegerPosition.Z - schlaegerHoehe) < minSchlaegerZ) { linkerSchlaegerPosition.Z = minSchlaegerZ + schlaegerHoehe; } if ((rechterSchlaegerPosition.Z + schlaegerHoehe) > maxSchlaegerZ) { rechterSchlaegerPosition.Z = maxSchlaegerZ - schlaegerHoehe; } else if ((rechterSchlaegerPosition.Z - schlaegerHoehe) < minSchlaegerZ) { rechterSchlaegerPosition.Z = minSchlaegerZ + schlaegerHoehe; }

Schließlich werden die Positionen zurückgeschrieben: 
context.Site["LinkerSchlägerPosition"] = linkerSchlaegerPosition; context.Site["RechterSchlägerPosition"] = rechterSchlaegerPosition;

Drücke  F12  zum  Kompilieren  des  Skripts.  Wenn  man  nun  die  Schläger  bewegt  so  stoppen  sie  am  Spielbrettrand. Damit ist das Spielbrett und die Schläger fertig. 

9.4.
 

Ball erstellen 

Der  Ball  wird  ähnlich  den  Schlägern  funktionieren.  Er  hat  eine  Positions‐Eigenschaft  in  der  PongGame‐Klasse,  die  mit  einem  Szenenobjekt  für das Rendering verlinkt ist.  Erzeuge  eine  neue  Eigenschaft  in  der  PongGame‐Klasse  unter  Create/Property/Vector3  und  nenne  diese  BallPosition. Setze die Werte der Eigenschaft auf  {0,  0.01,  0},  {‐8,  0.01,  ‐7},  {8,  0.01,  7},  {0.1,  0.1,  0.1}.  Erzeuge  außerdem  eine  Kugel  durch  Klicken  auf  den  Kugel‐Button  in  der  Scene‐ Werkzeugleiste. Nenne dieses Objekt Ball.  Nun  wird  ein  neues  Material  für  den  Ball  erzeugt.  Rechtsklicke  dazu  auf  den  Materials‐ Ordner  und  wähle  Create/Basic/Text.fx  und  benenne  das  erzeugte  Material  in  BallMaterial.  Öffne  die  Eigenschaften  des  Ball‐Objektes.  Veränder die Local Rotation auf 0, 0, 90 um die  Seitenflächen nach oben zeigen zu lassen. Setze  das eben erzeugte BallMaterial als Material ein.  Setze  Use  Vertex  Colors  auf  false.  Wähle  eine  diffuse  Textur,  z.B.  MarbleTile2.vtf  aus  dem  Samples‐Ordner.  Setze  die  Eigenschaft  UVScale  auf 0.5, 0.5 um die Textur besser zu sehen. 
Abbildung 37 ‐ Das BallLink‐Diagramm 

 

  42 

Jetzt wird die Position des Szenenobjektes mit der eben erzeugten Eigenschaft der PongGame‐Klasse  verlinkt.  Erzeuge  ein  neues  Logik‐Diagramm  und  nenne  es  BallLink.  Öffne  das  Diagramm  und  ziehe  die  PongGame‐Instanz  hinein  und  positioniere  sie  auf  der  linken  Seite.  Ziehe  den  Ball  in  das  Diagramm  und  platziere  ihn  auf  der  rechten  Seite.  Verbinde  die  Eigenschaft  BallPositon  von  PongGame mit der LocalPositon des Balls.  Auch  die  Größe  des  Balls  soll  über  eine  neue  Eigenschaft  der  PongGame‐Klasse  gesteuert  werden.  Erzeuge  in  der  PongGame‐Klasse  diese  Eigenschaft  über  Create/Property/Single  und  nenne  diese  BallGröße.  Setze  die  Werte  der  Eigenschaft  auf  0.25,  0.01,  10,  0.01  und  setze  den  In  Place  Editor  wieder  auf  slider.  Öffne  wieder  das  BallLink‐Diagramm.  Verbinde  den  Ausgang  von  Ball  Größe  der  PongGame‐Klasse  mit  dem  Eingang  der  Radius‐Eigenschaft  des  Balls.  Das  fertige  Diagramm  ist  in  Abbildung 37 zu sehen.  Nun kann man die Größe des Balls leicht über die Eigenschaft in der PongGame‐Instanz anpassen. 

9.5.
 

Ball bewegen 

Der  Ball  wird  nun  in  einen  Körper  mit  physikalischen  Eigenschaften  umgewandelt  und  über  die  Eigenschaft  Velocity (Geschwindigkeit) bewegt. Wähle dazu den Ball im  Scene‐Ordner  aus.  In  der  Physik‐Werkzeugleiste  (Dynamics) klicke auf den Button Make Active Rigid Body.  Wenn  man  nun  die  Eigenschaften  des  Balls  öffnet,  findet   man  eine  neue  Kategorie  mit  dem  Namen  Active  Rigid  Body.  Hier  findet  man  die  physikalischen  Eigenschaften.  Wir  wollen  nicht,  dass  die  Geschwindigkeit  des  Balls  gedämpft  wird  und  setzen  daher  die  Eigenschaften  Damping und Angular Damping auf 0, 0, 0 (siehe Abbildung  38).  Nun  wird  im  OnUpdate‐Skript  auch  die  Position  des  Balls  beschränkt,  sodass  er  das  Spielfeld  nicht  nach  oben  und  unten verlassen kann. Öffne das Skript im Editor und füge  Abbildung 38 ‐ Die physikalischen Eigenschaften folgenden Code hinzu: 
Vector3 ballPosition = (Vector3)context.Site[“BallPosition”]; float ballGroesse = (float)context.Site[“BallGröße”];

Dies  schreibt  die  Ball‐Position  und  die  –Größe  in  die  entsprechenden  Variablen.  Jetzt  wird  die  Position beschränkt ähnlich wie bei den Schlägern: 
float halbeBallGroesse = ballGroesse * 0.5f; float maxBallZ = 5.6f; float minBallZ = -5.6f; if ((ballPosition.Z + halbeBallGroesse) > maxBallZ) { ballPosition.Z = maxBallZ – halbeBallGroesse; } else if ((ballPosition.Z – halbeBallGroesse) < minBallZ)

 

  43 

{ ballPosition.Z = minBallZ + halbeBallGroesse; }

Nun schreibt man die Position nur noch zurück: 
context.Site[“BallPosition”] = ballPosition;

Drücke  F12  zum  Kompilieren  des  Skriptes.  Versuche  nun  die  BallPosition‐Eigenschaft  in  der  PongGame‐Instanz auf 0, 0.01, 10). Jetzt müsste der Ball automatisch wieder an den unteren Rand  des  Spielfeldes  zurückgesetzt  werden.  Setze  die  BallPosition  wieder  auf  den  Standardwert  zurück.  Bevor der Ball bewegt wird, muss erst definiert werden, was geschieht, wenn der Ball das Spielfeld  am  linken  oder  rechten  Rand  verlässt.  Es  soll  eine  Sieg‐Bedingung  gesetzt  werden,  welcher  der  beiden Schläger gewonnen hat. Dazu benötigt man weitere Eigenschaften in der PongGame‐Klasse.  Erzeuge  eine  neue  Eigenschaft  über  Create/Property/Boolean  und  nenne  sie  SiegLinkerSchläger.  Öffne  deren  Eigenschaften  und  setze  Caption False auf Verloren und Caption True auf Gewonnen. Ändere Is  Persistent  auf  False.  Dulpiziere  die  Eigenschaft  SiegLinkerSchläger  und  nenne die neue Eigenschaft SiegRechterSchläger.  Außerdem soll eine Punktzahl gespeichert werden. Erzeuge eine neue  Eigenschaft in der PongGame‐Klasse über Create/Property/UInt32 und  nenne  diese  PunkteLinkerSchläger.  Öffne  deren  Eigenschaften  und  setze  Is  Persistent  auf  false.  Dupliziere  die  Eigenschaft  und  nenne  die  neue Eigenschaft PunkteRechterSchläger.  Lege  eine  neue  Eigenschaft  über  Create/Property/Boolean  in  der  PongGame‐Klasse  mit  dem  Namen  Reset  an.  Ändere  in  der  Eigenschaft  Caption  False  auf  Spielen und Caption True auf Reset. 

Abbildung 39 ‐ Die PongGame‐ Klasse 

Der Ball wird über ein Makro zurückgesetzt. Erzeuge dazu im Ordner Macros ein neues Makro über  Create/Set  Value  Macro  und  nenne  es  ResetBall.  In  den  Eigenschaften  des  Makros  setzt  man  die  Target Instance auf den Ball im Scene‐Ordner und die Target Property auf LocalPosition in der Local  Transform‐Kategorie. In den Eigenschaften des Makros sieht man nun die lokale Position. Setze diese  auf 0, 0.01, 0.  Bisher  wird  der  Ball  an  der  Position  gezeichnet,  die  die  PongGame‐Instanz  vorgibt.  Dies  wird  nun  verändert, sodass die BallPosition der PongGame‐Instanz vom Ball gelesen wird. Öffne das BallLink‐ Diagramm  und  lösche  die  Verbindung  zwischen  der  BallPosition  und  der  LocalPosition.  Ziehe  eine  weitere  Instanz  des  Balles  in  das  Diagramm  und  platziere  sie  links  von  der  PongGame‐Instanz.  Verbinde  den  Ausgang  LocalPosition  des  linken  Balls  mit  dem  Eingang  BallPosition  der  PongGame‐ Instanz.  Teste nun das Makro.  Setze  die  Local‐ Position des Balls auf  einen  bestimmten  Wert,  z.B,  4,  0.01,  4.   
Abbildung 40 ‐ Das veränderte BallLinkd‐Diagramm

  44 

Öffne nun das ResetBall‐Makro und ändere die Eigenschaft Play auf true. Der Ball sollte nun wieder  in die Ausgangslage zurückgekehrt sein.  Erzeuge  ein  neues  Logik‐Diagramm  und  nenne  es  MacroLinks.  Ziehe  das  ResetBall‐Makro  in  das  Diagramm  und  platziere  es  rechts.  Ziehe  die  PongGame‐Instanz  in  das  Diagramm  und  platziere  sie  links. Verbinde den Ausgang Reset der PongGame‐Instanz mit dem Eingang Play des Makros. Wenn  nun die Reset‐Eigenschaft des Spiels auf true gesetzt wird, so wird auch der Ball zurückgesetzt.  Nun werden die Siegbedingungen in das OnUpdate‐Skript implementiert. Öffne dazu das Skript und  füge folgenden Code hinzu: 
bool reset = (bool)context.Site[“Reset”]; if ((ballPosition.X – halbeBallGroesse) < -8.0f) { reset = true; } else if ((ballPosition.X + halbeBallGroesse) > 8.0f) { reset = true; } else if (reset) { reset = false; }

Dies löst ein Reset aus, sobald der Ball den linken oder rechten Spielfeldrand verlässt. Die Eigenschaft  muss jedoch noch zurückgeschrieben werden: 
context.Site[“Reset”] = reset;

Kompiliere  das  Skript  durch  Drücken  von  F12.  Teste  das  Skript,  indem  man  dem  Ball  in  seinen  Eigenschaften  in  der  Active  Rigid  Body‐Kategorie  eine  Geschwindigkeit  zuweist  (Velocity  auf  der  X‐ Achse).  Der  Ball  bewegt  sich  nun  Richtung  Spielfeldrand  und  sobald  er  das  Feld  verlässt,  sollte  er  wieder  in  die  Mitte  des  Feldes  zurückgesetzt  werden.  Setze  die  Geschwindigkeit  und  die  Position  wieder auf die Ursprungswerte.   Der Ball soll am oberen und unteren Spielfeldrand abprallen. Dazu wird wieder das OnUpdate‐Skript  genommen. Finde die Zeile 
float minBallZ = -5.6f;

und füge folgenden Code an: 
IObject ball = context.Site.GetObject(“#Module/Scene/Ball”);

Dies gibt ein Handle auf den Ball im Objektbaum zurück. Man benötigt die Position des Balles: 
Vector3 ballGeschw = (Vector3)ball[“Velocity”];

Jetzt kann man die Geschwindigkeit im Skript verändern. Finde die if‐else if‐Abfrage in der die Ball‐ Position beschränkt wird und ändere sie folgendermaßen: 
if ((ballPosition.Z + halbeBallGroesse) > maxBallZ) { ballPosition.Z = maxBallZ – halbeBallGroesse;

 

  45 

ballGeschw = Vector3.Reflect(ballGeschw, Vector3.Forward); } else if ((ballPosition.Z – halbeBallGroesse) < minBallZ) { ballPosition.Z = minBallZ + halbeBallGroesse; ballGeschw = Vector3.Reflect(ballGeschw, Vector3.Backward); }

Diese  lässt  den  Ball  oben  und  unten  abprallen.  Nun  muss  die  Geschwindigkeit  nur  noch  zurückgeschrieben werden: 
ball[“Velocity”] = ballGeschw;

Drücke F12 zum Kompilieren des Skripts. Überprüfe die Wirkungsweise des Skripts durch Setzen der  Geschwindigkeit.  Der  Ball  sollte  nun  von  den  Rändern  abprallen.  Setze  die  Ball‐Position  und  – Geschwindigkeit wieder zurück.  Ein  Makro  soll  auch  die  Geschwindigkeit  des  Balls  zurücksetzen.  Mehrere  Makros  können  in  einem  Compound‐Makro  vereint  werden.  Dieses  Makro  soll  die  Geschwindigkeit  und  die  Position  zurücksetzen.  Erzeuge  ein  neues  Makro  über  Create/Compound  Macro.  Ziehe  das  ResetBall‐Makro  unter das eben erzeugte Compound‐Makro um es unterzuordnen. Ändere den Namen des ResetBall‐ Makros in ResetBallPosition. Ändere den Namen des Compound‐Makros in ResetBall. Erzeuge unter  dem  Compound‐Makro  ein  neues  Makro  über  Create/Set  Value  Macro  und  nenne  dieses  ResetBallGeschw. Öffne die Eigenschaften des eben erzeugten Makros und setze die Target Instance  auf den Ball und die Target Property auf Velocity in der Active Rigid Body‐Kategorie. Wenn nun das  ResetBall‐Makro  aktiviert  wird,  führt  es  beide  Untermakros  aus.  Das  MacroLinks‐Diagramm  muss  noch verändert werden um das neue Compound‐Makro auszuführen.  Öffne  das  MacroLinks‐Diagramm.  Lösche  ResetBallPosition.  Ziehe  das  neue  ResetBall‐Makro  in  den  Graphen.  Verbinde  den  Reset‐Ausgang  von  der  PongGame‐Instanz  mit  dem  Play‐Eingang  des  ResetBall‐Makros.  Teste nun das Makro. Gib dem Ball eine Geschwindigkeit. Verlässt der Ball das Spielfeld so müsste er  wieder  in  die  Mitte  zurückgesetzt  werden  und  die  Geschwindigkeit  müsste  wieder  auf  0  gesetzt  werden.  Der Ball soll nach dem Reset mit einer zufälligen Geschwindigkeit starten. Finde im OnUpdate‐Skript   folgende Zeile: 
else if (reset) { reset = false; }

Ändere diese Zeile in folgenden Code: 
else if (reset) { ballGeschw.X = Blade3D.Runtime.Operators.MathOperators.GetRandomMinMax(-5, 5); ballGeschw.Z = Blade3D.Runtime.Operators.MathOperators.GetRandomMinMax(-1, 1); if (ballGeschw.X < 0.0f && ballGeschw.X > -2.0f)

 

  46 

{ ballGeschw.X = -2.0f; } else if (ballGeschw.X > 0.0f && ballGeschw.X < 2.0f) { ballGeschw.X = 2.0f; } reset = false; }

Drücke F12 zum Kompilieren. Gib dem Ball eine Geschwindigkeit um das Ganze zu starten. Der Ball  sollte  nun  nach  Verlassen  des  Feldes  zurückgesetzt  werden  und  eine  zufällige  Geschwindigkeit  bekommen. Setze die Ball‐Position und –Geschwindigkeit wieder auf die Ursprungswerte.  Der  Ball  soll  natürlich  auch  an  den  Schlägern  abprallen.  Füge  dazu  im  OnUpdate‐Skript  nach  der  Veränderung der Ball‐Position und –Geschwindigkeit folgenden Code hinzu: 
float schlaegerBreite = (float)context.Site[„SchlägerBreite“]; float halbeSchlaegerBreite = schlaegerBreite * 0.5f; float halbeSchlaegerHoehe = schlaegerHoehe * 0.5f; if ((ballPosition.X - halbeBallGroesse) < (linkerSchlaegerPosition.X + halbeSchlaegerBreite)) { if ((ballPosition.Z + halbeBallGroesse) > (linkerSchlaegerPosition.Z – halbeSchlaegerHoehe)) { if ((ballPosition.Z – halbeBallGroesse) < (linkerSchlaegerPosition.Z + halbeSchlaegerHoehe)) { if ((ballPosition.X + halbeBallGroesse) > (linkerSchlaegerPosition.X – halbeSchlaegerBreite)) { ballGeschw = Vector3.Reflect(ballGeschw, Vector3.Right); } } } } else if ((ballPosition.X + halbeBallGroesse) > (rechterSchlaegerPosition.X - halbeSchlaegerBreite)) { if ((ballPosition.Z + halbeBallGroesse) > (rechterSchlaegerPosition.Z – halbeSchlaegerHoehe)) { if ((ballPosition.Z – halbeBallGroesse) < (rechterSchlaegerPosition.Z + halbeSchlaegerHoehe)) { if ((ballPosition.X + halbeBallGroesse) < (rechterSchlaegerPosition.X + halbeSchlaegerBreite)) { ballGeschw = Vector3.Reflect(ballGeschw, Vector3.Left); } } } }

Drücke  F12  zum  Kompilieren.  In  diesen  verschachtelten  If‐Abfragen  wird  geprüft,  ob  der  Ball  sich  innerhalb  der  Schläger  befindet  und  wenn  ja  wird  er  vom  Schläger  reflektiert.  Das  Spiel  sollte  nun  spielbar sein.   
  47 

9.6.
 

GUI erstellen 

Im  letzten  Abschnitt  haben  wir  der  PongGame‐Klasse  zwei  Eigenschaften  hinzugefügt,  die  die  erzielten  Punkte  speichern.  Diese  Punkte  sollen  nun  in  einer  GUI  auf  dem  Bildschirm  angezeigt  werden. Vorher müssen die Punkte noch in einem Skript inkrementiert werden. Öffne das OnUpdate‐ Skript. Finde den kompletten Code‐Block, der folgenderweise beginnt: 
if ((ballPosition.X – halbeBallGroesse) < -8.0f) { reset = true; } else if …

Und ändere ihn so um: 
bool siegLinkerSchlaeger = (bool)context.Site[“SiegLinkerSchläger“]; bool siegRechterSchlaeger = (bool)context.Site[“SiegRechterSchläger“]; if ((ballPosition.X – halbeBallGroesse) < -8.0f) { reset = true; context.Site[“SiegLinkerSchläger”] = true; } else if ((ballPosition.X + halbeBallGroesse) > 8.0f) { reset = true; context.Site[“SiegRechterSchläger”] = true; } else if (reset == true) { ballGeschw.X = Blade3D.Runtime.Operators.MathOperators.GetRandomMinMax(5, 5); ballGeschw.Z = Blade3D.Runtime.Operators.MathOperators.GetRandomMinMax(-1, 1); if (ballGeschw.X < 0.0f && ballGeschw.X > -2.0f) { ballGeschw.X = -2.0f; } else if (ballGeschw.X > 0.0f && ballGeschw.X < 2.0f) { ballGeschw.X = 2.0f; } if (siegLinkerSchlaeger) { uint punkteLinkerSchlaeger = (uint)context.Site[„PunkteLinkerSchläger“]; punkteLinkerSchlaeger++; context.Site[„PunkteLinkerSchläger“] = punkteLinkerSchlaeger; context.Site[„SiegLinkerSchläger“] = false; } if (siegRechterSchlaeger) {

 

  48 

uint punkteRechterSchlaeger = (uint)context.Site[„PunkteRechterSchläger“]; punkteRechterSchlaeger++; context.Site[„PunkteRechterSchläger“] = punkteRechterSchlaeger; context.Site[„SiegRechterSchläger“] = false; } reset = false; }

Dieser  Codeabschnitt  setzt  die  Sieg‐Eigenschaften  auf  true,  wenn  ein  Schläger  einen  Punkt  macht.  Beim  nächsten  Update  ist  die  Reset‐Eigenschaft  true  und  es  werden  die  Punkte  des  gewinnenden  Schlägers erhöht.  Jetzt  werden  die  Punkte  auf  der  GUI  zur  Anzeige  gebracht.  Rechtsklicke  auf  den  User  Interfaces‐ Ordner im Objektbrowser und wähle Create/User Interface (klicke im auftauchenden Dialog auf Ok)  und nenne die GUI PunkteGUI. Rechtsklicke auf PunkteGUI und wähle Create/Container. Rechtsklicke  auf  den  erzeugten  Container  und  wähle  Create/Label.  Nenne  das  Label  Spieler1Label.  Öffne  die  Label‐Eigenschaften.  Setze  die  Eigenschaft  Text  auf  Spieler  1:.  Setze  die  Position  auf  50,  0  in  der  Control‐Kategorie.  Rechtsklicke  auf  den  Container  und  wähle  Create/Label  und  nenne  es  Spieler1Punkte. Öffne die Eigenschaften des eben erzeugten Labels. Setze die Text‐Eigenschaft auf 0  und die Position auf 180, 0. Dupliziere das Spieler1Label und nenne die Kopie Spieler2Label . Setze die  Text‐Eigenschaft  der  Kopie  auf  Spieler  2:  und  die  Position  auf  800,  0.  Dupliziere  Spieler1Punkte,  nenne  die  Kopie  Spieler2Punkte und setze die Position auf 910, 0.  Abbildung 41 ‐ Die Punkteanzeige Erzeuge  ein  neues  Logik‐Diagramm  und  nenne  es  PunkteGUILink.  Ziehe  die  PongGame‐Instanz,  das  Spieler1Punkte‐  und  das  Spieler2Punkte‐Label  in  das  Diagramm.  Verbinde  die  Ausgänge  der  Eigenschaften  Punkte  Linker  Schläger  und  Punkte  Rechter  Schläger  der  PongGame‐Instanz  mit  den  entsprechenden  Text‐Eingängen  der  Labels  wie  in  Abbildung  42  dargestellt.  Nun  zeigen  die  Labels  den aktuellen Punktestand an.  Der GUI wird nun ein Button hinzugefügt, der  das  ganze  Spiel  zurücksetzt  und  neu  startet.  Rechtsklicke  auf  den  Container  unter  PunkteGUI  und  wähle  Create/Button.  Nenne  den  Button  ResetSpiel.  Setze  die  Text‐ Eigenschaft  des  Buttons  auf  Spiel  Spiel.  Ändere  die  BackColor  auf  Rot,  setze  die  Position  auf  465,  10  und  ändere  die  Größe  (Size) auf 170, 60.  Ein  neues  Compound‐Makro  wird  die  Reset‐ Eigenschaft  der  PongGame‐Instanz  auf  true  Abbildung 42 ‐ Das PunkteGUILink‐Diagramm  und die Punktstände auf 0 setzen. Erzeuge ein  neues  Compound‐Makro  und  nenne  es  ResetSpiel.  Erzeuge  ein  Untermakro  über  Create/Set  Value  Macro und nenne es ResetPongGame. Setze die Target Instance des Untermakros auf die PongGame‐ Instanz  und  die  Target  Property  auf  Reset.  Nun  wird  die  Reset‐Option  angezeigt,  ändere  diese  auf  Reset. Erzeuge im ResetSpiel‐Makro ein neues Untermakro über Create/Set Value Macro und nenne   
  49 

es ResetPunkteSpieler1. Setze die Target Instance auf die PongGame‐Instanz und die Target Property  auf  PunkteLinkerSchläger.  Erzeuge  auf  die  gleiche  Weise  ein  weiteres  Untermakro  für  den  Punktestand des rechten Schlägers.  Dies  sollte  das  Spiel  zurücksetzen.  Man  könnte  weiterhin  noch  2  Untermakros  erzeugen,  die  außerdem  noch  die  Schlägerpositionen  noch  zurücksetzen.  Das  Makro  wird  nun  über  ein  Logik‐ Diagramm mit dem Button verbunden.  Erzeuge  ein  neues  Logik‐Diagramm  und  nenne  es  ResetSpielLinks.  Ziehe  den  ResetSpiel‐Button  und  das  ResetSpiel‐Compound‐Makro  in  das  Diagramm.  Verbinde  den  ClickEvent‐Ausgang  des  Buttons  mit dem Play‐Eingang des Makros.  Nun muss nur noch der Ball zurückgesetzt werden. Dazu gibt es bereits das ResetBall‐Makro. Dieses  muss nur noch als Untermakro in das ResetSpiel‐Makro gezogen werden.  Viel Spaß beim Spielen!   

Quellen: 
  • • Die Blade3D‐Online‐Hilfe    Die Blade3D‐Wiki ( http://wiki.blade3d.com ), aus der auch das Pong‐Tutorial entnommen  wurde    Das Blade3D‐Internetforum  (http://www.xnamagic.com/Community/Forums/tabid/75/Default.aspx ) 

 

  50 

Master your semester with Scribd & The New York Times

Special offer for students: Only $4.99/month.

Master your semester with Scribd & The New York Times

Cancel anytime.