⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 daserstespieldeu.html

📁 java tutorial all about java game design
💻 HTML
📖 第 1 页 / 共 2 页
字号:
  Also, zweite Idee: Man akzeptiert alle Koordinaten als Treffer, die um einen gewissen Betrag kleiner bzw. gr&ouml;&szlig;er sind als die Koordinaten des Balles. Dies muss nat&uuml;rlich f&uuml;r die x und die y - Koordinate gleicherma&szlig;en zutreffen (&& - Abfrage). Auf diese Weise testet man, ob der Klick des Spielers in einem Quadrat um den Ball (bei Radius 10 z. B. mit Kantenl&auml;nge 20) erfolgt ist. Diese Idee hatte ich bei meinem ersten Versuch dieses Spiel umzusetzen implementiert, mit leider nur m&auml;&szlig;igem Erfolg. Das Ganze hat mal funktioniert, mal wieder nicht, obwohl der Ball richtig getroffen wurde. Der Grund daf&uuml;r ist mir immernoch schleierhaft. <br>  <br>
  Nun denn, die dritte Idee: Aus der Schule d&uuml;rfte den meisten noch der Begriff eines Vektors gel&auml;ufig sein. Wir haben es hier nun zwei Vektoren zu tun, die bei einem Schuss entstehen: Einem Schussvektor (x_maus, y_maus) des Mausklicks und einem Positionsvektor des Balles (x_ball, y_ball). Wenn wir nun die L&auml;nge des Verbindungsvektors dieser beiden Vektoren bestimmen und dieser kleiner als der Radius des Balles ist, so haben wir den Ball getroffen. <br>
  Zun&auml;chst berechnen wir also den Verbindungsvektor indem wir die Koordinaten des einen Vektors von denen des Anderen abziehen:</p>
  <ul><i>
  // Bestimmen des Verbindungsvektors<br>
  double x = maus_x - pos_x;<br>
  double y = maus_y - pos_y;<br>
  </i></ul>
  <p align="justify">Nun k&ouml;nnen wir mit Hilfe des Skalarproduktes bzw. Pythagoras (c = Wurzel aus a&sup2; + b&sup2;) die L&auml;nge dieses Verbindungsvektors bestimmen:</p>
  <ul><i>
  // Berechnen der Distanz<br>
  double distance = Math.sqrt ((x*x) + (y*y));<br>
  </i></ul>
  <p align="justify">Als letzten Schritt testen wir, ob die L&auml;nge dieses Vektors kleiner ist als ein gewisser Betrag, bis zu dem wir den Ball noch als getroffen ansehen. Ich habe f&uuml;r diese Zahl 15 gew&auml;hlt obwohl der Ball nur einen Radius von 10 hat. Aber nachdem ich einige Werte getestet habe, erschien mir dieser Wert als der am besten taugliche.</p>
  <ul><i>
  // Wenn Distanz kleiner als 15 gilt Ball als getroffen<br>
  if (distance &lt; 15)<br>
  {<ul>
     player.addScore (20);<br>
     return true;<br>
  </ul>
  }<br>
  else return false;<br>
  </i></ul>
  <p align="justify">Damit k&ouml;nnen wir den Ball abschie&szlig;en, wenn wir auf bzw. kurz daneben schie&szlig;en. Die R&uuml;ckgabewerte ergeben sich aus der oben beschriebenen Struktur und Zusammenarbeit der Methoden.</p>
  <h3>Das Spielerobjekt: Punkte z&auml;hlen und Leben verlieren</h3>
  <p align="justify">Um dies zu verwirklichen haben wir die Player - Klasse mit den Methoden looseLife() und addScore (int plus) ausgestattet. Immer wenn ein Ball das Spielfeld verl&auml;sst, ruft er player.looseLife() in der Methode isOut() auf. Dadurch verliert der Spieler ein Leben. Trifft der Spieler den Ball (ober beschrieben), so ruft die Methode userHit() player.addScore (10* Math.abs(x_speed) + 10) auf und z&auml;hlt somit je nach Geschwindikeit des Balles Punkte zu denen des Spielers hinzu. Umso schneller ein Ball fliegt, umso mehr Punkte kann man durch einen Abschuss somit erreichen. Die Methoden addScore und looseLife sind dabei wirklich denkbar einfach. <br>
  Einziger Knackpunkt: Man muss sehen, dass das Player - Objekt in der Klasse Main geschaffen wird. Die Refferenz auf das Spieler - Objekt muss also im Konstruktor oder in der Methode (userHit() bzw. isOut()) die Methoden des Objektes verwendet, an die Klasse Ball &uuml;bergeben worden sein! <br>
  Dies ist eine wichtige Technik, denn es kommt h&auml;ufig vor, dass mehrere Klassen Zugriff auf ein und das selbe Objekt ben&ouml;tigen. Man initialisiert das Objekt dann einfach z. B. in der Klasse Main (die ich gerne verwende um alle Objekte des Spiels zu verwalten) und &uuml;bergibt die Refferenz von dort aus an alle anderen Objekte, die die Refferenz ben&ouml;tigen.</p>
  <h3>Mauszeiger ver&auml;ndern: Das Fadenkreuz</h3>
  <p align="justify">Nat&uuml;rlich passt zu unserem Spiel ein Fadenkreuz als Mauszeiger viel besser, als ein normaler Zeiger. Um uns einen Fadenkreuzmauszeiger zu beschaffen, m&uuml;ssen wir unserer Main - Klasse lediglich drei Codezeilen hinzuf&uuml;gen: Zun&auml;chst eine Instanzvariable der Klasse Cursor:</p>
  <ul><i>
  // Fadenkreuzmauszeiger<br>
  Cursor c;   // Variable f&uuml;r Cursor<br>
  </i></ul>
  <p align="justify">In die Init - Methode f&uuml;gen wir dann folgende Zeilen ein:</p>
  <ul><i>
  // Mauszeiger wird zu Fadenkreuz<br>
  c = new Cursor (Cursor.CROSSHAIR_CURSOR);<br>
  this.setCursor (c);<br>
  </i></ul>
  <p align="justify">Weitere Klassenvariablen der Klasse Cursor und somit weitere Mauscursor, k&ouml;nnen in der API nachgelesen werden.</p>
  <h3>Spielzust&auml;nde: Das Spiel erst nach einem Doppelklick starten und beenden, wenn der Spieler seine Leben verbraucht hat</h3>
  <p align="justify">Bis auf eine kleine Kleinigkeit ist unser Spiel nun fertig: Es ist f&uuml;r den Spieler sehr unangenehm, wenn das Spiel schon losgeht, bevor er sich &uuml;berhaupt die Anleitung durchgelesen hat. Wir wollen das Spiel daher erst dann starten, wenn er einen Doppelklick in das Appletfenster ausgef&uuml;hrt hat. Das hat nicht nur den Vorteil, dass der Spieler den Startpunkt des Spieles selbst bestimmen kann, sondern wenn man in seinem Spiel Tastaturereignisse verwendet, dann kann man den Tastaturfocus f&uuml;r das Applet (wird durch Klick auf das Applet erreicht) auf diese Weise sicherstellen. Des weiteren soll das Spiel nat&uuml;rlich dann beendet sein, wenn der Spieler alle seine Leben verspielt hat.</p>
  <p align="justify">Zun&auml;chst f&uuml;gen wir also in die Klasse Main eine boolsche Instanzvariable mit Namen isStoped ein. Ist sie true, so ist das Spiel gestoppt, ist sie false, so l&auml;uft das Spiel.
  Nun f&uuml;gen wir in unseren Thread (run - Methode) eine Abfrage ein, die die Methoden zur Bewegung des Balles nur dann aufruft, wenn der Spieler mehr als 0 Leben hat und gleichzeitig isStoped false ist. repaint() wird weiterhin immer nach dem Starten des Threads aufgerufen. </p>
  <i><ul>
  // Endlosschleife der run - Methode<br>
  while (true)<br>
  {<ul>
       if (player.getLives() >= 0 && !isStoped)<br>
       {<ul>
            redball.move();<br>
            blueball.move();<br>
       </ul>
       }<br><br>

       ...<br>
  </ul>}
  </ul></i>
  <p align="justify">Im n&auml;chsten Schritt wollen wir in der paint() - Methode eine weitere Abfrage einf&uuml;gen. Sie soll, solange der Spieler noch Leben hat, die B&auml;lle sowie die Angabe &uuml;ber Leben und Punkte zeichen. Ist das Spiel gestoppt, so zeichnet sie zudem die Information, dass das Spiel mit einem Doppelklick gestartet werden kann, auf den Bildschirm. Hat der Spieler keine Leben mehr, so wertet die paint() - Methode seine Punktezahl aus, schreibt eine Bewertung der Ergebnisse auf den Bildschirm, sowie weitere Informationen auf den Bildschirm und gew&auml;hrleistet, dass das Spiel nach
  einem weiteren Doppelklick des Spielers wieder gestartet wird. Die paint() - Methode gestalltet sich also folgenderma&szlig;en: </p>
  <ul><i>
  // paint() - Methode<br>
  public void paint (Graphics g)<br>
  {<ul>
       // Spieler hat noch Leben<br>
       if (player.getLives() >= 0)<br>
       {<ul>
          // Alle n&ouml;tigen Anweisungen zum Zeichnen von Ball, Punktestand...<br><br>
          ...<br><br>
          // Wenn das Spiel zus&auml;tzlich noch gestoppt ist<br>
          if (isStoped)<br>
          {<ul>
               // Information: "Spiel startet auf Doppelklick" zeichen<br>
          </ul>}

       </ul>}<br>
       // Spieler hat keine Leben mehr<br>
       else if (player.getLiver() &lt; 0)<br>
       {<ul>
            // Bewertung der Punkte, Game over zeichnen, isStoped true setzen<br>
            // Details bitte im SourceCode nachlesen
       </ul>}
  </ul>}
  </i></ul>
  <p align="justify">Nun ist es fast geschafft! Im Moment haben wir aber noch keine Kontrolle dar&uuml;ber, wann wir das Spiel starten, da wir in die MouseDown - Methode noch keine Befehle eingef&uuml;gt haben, die das Umschalten von dem gestoppten Spielzustand in das laufende Spiel erlauben. Um dies zu erreichen m&uuml;ssen wir die mouseDown() - Methode folgenderma&szlig;en ver&auml;ndern:</p>
  <ul><i>
  // Auffangen der Mausereignisse<br>
  public void mouseDown (Event e, int x, int y)<br>
  {<ul>
       // Behandlung von Mausereignissen, w&auml;hrend das Spiel l&auml;uft<br>
       if (!isStoped)<br>
       {<ul>
            // Test ob roter Ball getroffen wurde<br>
            if (redball.userHit (x, y))<br>
            {<ul>
               // Abspielen der Audiodatei<br>
               hitnoise.play();<br><br>

               // Ball zu Startwert zur&uuml;cksetzten<br>
               redball.ballWasHit ();<br>
           </ul>}<br>
            // Test ob blauer Ball getroffen wurde<br>
            if (blueball.userHit (x, y))<br>
            {<ul>
               // Abspielen der Audiodatei<br>
               hitnoise.play();<br><br>

               // Ball zu Startwert zur&uuml;cksetzten<br>
               blueball.ballWasHit ();<br>
            </ul>}<br>
            else<br>
            {<ul>
                // Abspielen des normalen Schussger&auml;usches<br>
                shotnoise.play();<br>
            </ul>}
       </ul>}<br>
       // Gestopptes Spiel bei Doppelklick starten<br>
       else if (isStoped && e.clickCount == 2)<br>
       {<ul>
            // Alle wichtigen Werte zur&uuml;cksetzen<br>
            isStoped = false;<br>
            init ();<br>
       </ul>}<br><br>

       return true;<br>
  </ul>}
  </i></ul>
  <h3>Geschafft!!</h3>
  <p align="justify">So, nun habt ihr es hinter euch und wenn ihr auch die Teile, die ich nicht so ausf&uuml;hrlich besprochen habe, verstanden habt, dann steht eurem ersten Spiel ja nichts mehr im Wege.
  Die n&auml;chsten Kapitel werden sich noch mit einigen weiterf&uuml;hrenden Problemen und L&ouml;sungen befassen, die ich in meinen bisher programmierten Spielen verwendet bzw. irgendwo mal gesehen habe. <br> Ansonsten entlasse ich euch hiermit "in die Freiheit", in der Dank der M&auml;chtigkeit und Flexibilit&auml;t von Java beinahe alles m&ouml;glich ist, w&uuml;nsche euch viel Spa&szlig; und Erfolg bei der Entwicklung eurer eigenen Spiele, hoffe, dass ich euch in diesem Tutorial ein wenig weiterhelfen konnte und wenn ihr eure ersten Spiele geschrieben, W&uuml;nsche, Anregungen, Beschwerden, eigene Tutorials zu bestimmten Themen... oder ein Problem habt, dann schreibt bzw. schickt mir doch einfach eine Mail bzw. euer Spiel...! <br>
  Zuguterletzt k&ouml;nnt ihr euch, wie immer den SourceCode runterladen und das Spiel ausprobieren.</p>
  <p><a href="SourceCodes/ErstesSpiel/DasersteSpiel.zip">SourceCode download (*.zip -  Datei)</a><br>
  <a href="Applets/ErstesSpiel/ErstesSpiel.html">Applet ansehen</a>
  <h4>N&auml;chstes Kapitel</h4>
<a href="PongKIDeu.html">K&uuml;nstliche Intelligenz f&uuml;r einen Pong Klon</a>
  <!-- InstanceEndEditable -->
</div>
</td>
</tr>

<tr>
<td colspan="11" style="background-color:#990000" align="center">
<table width="100%" style="padding:0"><tr>
  <td width="88" bgcolor="#993300"><div align="center" style="font-size:10px; color: #FFFFFF;">  <a href="#top"> to top </a></div></td>
  <td><div align="center" style="font-size:10px; color: #FFFFFF;">
<a href="mailto:javacooperation@gmx.de">Fabian Birzele</a>, 2001-2004.<br>
web-design: <a href="http://www.freehand.str.ru/">Vadim Murzagalin</a>, 2004.
</div></td>
<td width="88">
</td>
</tr>
</table>

</td>

</tr>

</table>
</div>

</body>
<!-- InstanceEnd --></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -