📄 daserstespieldeu.html
字号:
<html><!-- InstanceBegin template="/Templates/template.dwt" codeOutsideHTMLIsLocked="false" -->
<head>
<!-- InstanceBeginEditable name="doctitle" -->
<title>Java Cooperation: our first game</title>
<!-- InstanceEndEditable --><meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<link href="jc_style.css" rel="stylesheet" type="text/css">
<script src="klayers.js"></script>
<script>
function cancelCloseMenu(){
if(self.tm) clearTimeout(tm) // cancel delayed closing
}
function showMenu(){
if(!self.menu || !self.submenu){
menu=layer("menulayer")
submenu=layer("submenulayer")
}
cancelCloseMenu()
submenu.moveTo(menu.getAbsoluteLeft(), menu.getAbsoluteTop() + menu.getHeight()) // move second menu relatively
submenu.show()
}
function initiateHideMenu(){
tm=setTimeout("hideMenu()",400) // 1 second delay to close a submenu
}
function hideMenu(){
submenu.hide()
}
</script>
<!-- InstanceBeginEditable name="head" --><!-- InstanceEndEditable -->
</head>
<body bgcolor="#ffffff" leftmargin="0" topmargin="0" rightmargin="0" bottommargin="0">
<div align="center">
<a name="top"></a>
<table bgcolor="#737373" border="0" cellpadding="0" cellspacing="0" width="618">
<tr>
<td rowspan="8" bgcolor="#000000"><img src="Pics/spacer.gif" width="1" height="1" border="0" alt=""></td>
<td bgcolor="#000000"><img src="Pics/spacer.gif" width="131" height="1" border="0" alt=""></td>
<td bgcolor="#000000"><img src="Pics/spacer.gif" width="13" height="1" border="0" alt=""></td>
<td bgcolor="#000000"><img src="Pics/spacer.gif" width="58" height="1" border="0" alt=""></td>
<td bgcolor="#000000"><img src="Pics/spacer.gif" width="94" height="1" border="0" alt=""></td>
<td bgcolor="#000000"><img src="Pics/spacer.gif" width="81" height="1" border="0" alt=""></td>
<td bgcolor="#000000"><img src="Pics/spacer.gif" width="48" height="1" border="0" alt=""></td>
<td bgcolor="#000000"><img src="Pics/spacer.gif" width="23" height="1" border="0" alt=""></td>
<td bgcolor="#000000"><img src="Pics/spacer.gif" width="38" height="1" border="0" alt=""></td>
<td bgcolor="#000000"><img src="Pics/spacer.gif" width="19" height="1" border="0" alt=""></td>
<td bgcolor="#000000"><img src="Pics/spacer.gif" width="108" height="1" border="0" alt=""></td>
<td bgcolor="#000000"><img src="Pics/spacer.gif" width="5" height="1" border="0" alt=""></td>
</tr>
<tr>
<td rowspan="5"><a href="index.html"><img name="fab_r1_c1" src="Pics/fab_r1_c1.gif" width="131" height="71" border="0" alt="Java cooperation home"></a></td>
<td rowspan="6" bgcolor="#737373"></td>
<td colspan="9" height="15" bgcolor="#737373"></td>
<td rowspan="8" bgcolor="#000000"><img src="Pics/spacer.gif" width="1" height="1" border="0" alt=""></td>
</tr>
<tr>
<td colspan="5"><div class="colontitul"><!-- InstanceBeginEditable name="Colontitul" -->Tutorial<!-- InstanceEndEditable --></div></td>
<td colspan="2" bgcolor="#737373"><img name="fab_r2_c8" src="Pics/fab_r2_c8.gif" width="57" height="19" border="0" alt="type and press Enter"></td>
<td colspan="2">
<FORM method=GET action="http://www.google.com/search">
<TABLE bgcolor="#FFFFFF" cellpadding="0" cellspacing="0" height="10px"><tr>
<td height="10" valign="middle">
<INPUT TYPE=text name=q size=18 maxlength=60 value="" style="font-size:12px; color:#000000; border-width: 0px;">
<input type=hidden name=domains value="http://javacooperation.gmxhome.de/">
<input type=hidden name=sitesearch value="http://javacooperation.gmxhome.de/" checked>
</td></tr></TABLE>
</td>
</form>
<td><img src="Pics/spacer.gif" width="1" height="19" border="0" alt=""></td>
</tr>
<tr>
<td colspan="9" bgcolor="#666666"><img name="fab_r3_c3" src="Pics/fab_r3_c3.gif" width="474" height="8" border="0" alt=""></td>
<td><img src="Pics/spacer.gif" width="1" height="8" border="0" alt=""></td>
</tr>
<tr>
<td colspan="6"><a href="TutorialStartDeu.html"><img src="Pics/deupanel_01.gif" width="56" height="22" border="0"></a><a href="OnlineSpieleStartDeu.html"><img src="Pics/deupanel_02.gif" width="94" height="22" border="0"></a><a href="DownloadsDeu.html"><img src="Pics/deupanel_03.gif" width="76" height="22" border="0"></a><a href="LinksDeu.html"><img src="Pics/deupanel_04.gif" width="52" height="22" border="0"></a><a href="KontaktDeu.html"><img src="Pics/deupanel_05.gif" width="64" height="22" border="0"></a></td>
<td><img name="fab_r4_c9" src="Pics/fab_r4_c9.gif" width="19" height="22" border="0" alt=""></td>
<td width="108" height="22" bgcolor="#666666"><div align="center"><span id="menulayer" style="position: relative; background-color:#666666; width:108; height:20; vertical-align:baseline; border:1px solid #FFFFFF"><a href="#" class="text" onmouseover="showMenu(); return true" onmouseout="initiateHideMenu(); return true">Select language</a></span>
</div>
<div id="submenulayer" style="position: absolute; visibility: hidden; background-color: #666666; width:108px;">
<div class="text" style="border:1px solid #FFFFFF; border-top-width:0; padding:5px">
<a href="#" onmouseover="cancelCloseMenu(); return true" onmouseout="initiateHideMenu(); return true">German</a><br>
<a href="indexEng.html" onmouseover="cancelCloseMenu(); return true" onmouseout="initiateHideMenu(); return true">English</a><br>
<a href="http://javacooperation.dev.juga.ru/index.html" onmouseover="cancelCloseMenu(); return true" onmouseout="initiateHideMenu(); return true">Russian</a>
</div>
</div>
</td>
<td><img name="fab_r4_c11" src="Pics/fab_r4_c11.gif" width="5" height="22" border="0" alt=""></td>
</tr>
<tr>
<td colspan="9"><img name="fab_r5_c3" src="Pics/fab_r5_c3.gif" width="474" height="7" border="0" alt=""></td>
</tr>
<tr>
<td colspan="11" style="padding:18; background-color:#333333; vertical-align:top;">
<div class="text">
<!-- InstanceBeginEditable name="EditRegion" -->
<h2>Die Entwicklung unseres ersten Spiels</h2>
<h3>Die Spielidee</h3>
<p align="justify">In unserem Spiel soll der Spieler zwei Bälle (einen roten und einen blauen), die sich, per Zufallsgenerator bestimmt, in verschiedene Richtungen bewegen, durch einen Mausklick auf den Ball abschießen. Läßt der Spieler einen Ball aus dem Spielfeld fliegen, ohne ihn getroffen zu haben, so verliert er eines von anfangs 10 Leben. Trifft er den Ball, so erhält er eine gewisse Zahl von Punkten (abhängig von der Geschwindigkeit des Balles) und ein neuer Ball erscheint auf dem Spielfeld. Das Spiel soll außerdem Sounddateien bei einem Schuss, bei einem Treffer und wenn ein Ball das Spielfeld verlassen hat abspielen.</p>
<h3>Die verwendeten Klassen und ihre Methoden</h3>
<h5>Die Klasse Main</h5>
<p align="justify">In dieser Klasse sollen alle Methoden, die das Applet und die Animation direkt betreffen, implementiert werden. Dazu gehören die Methoden init(), start(), stop(), paint(), update(), run() und die mouseDown() - Methode zum Auffangen von Benutzerereignissen. Die Klasse verwaltet zudem alle für das Spiel nötigen Objekte (zwei Ball Objekte und ein Spieler Objekt) sowie den Thread.</p>
<ol start="1" type="1">
<li>init(): In ihr werden alle Objekte initialisiert, die Audiodateinen geladen, der Mauscursor bestimmt und zudem wird die Geschwindigkeit des Spiels mit Hilfe eines Parameters von der HTML - Seite an das Applet übergeben</li>
<li>start(): Startet den Thread</li>
<li>stop(): Stopt den Thread</li>
<li>run(): Bewegt die beiden Bälle</li>
<li>paint(...): Zeichnet die beiden Bälle sowie Punkte und Leben des Spielers. Ist das Spiel beendet, so wertet sie das Ergebniss und zeichnet die Bewertung auf den Bildschirm</li>
<li>update(...): Realisiert die Doppelpufferung</li>
<li>mouseDown (...): Hört auf die Mausklicks des Benutzers. Läuft das Spiel, so testet sie nach einem Mausclick, ob einer der beiden Bälle getroffen wurde oder nicht. Ist das Spiel beendet oder wurde die Seite gerade neu geladen, so kann fängt sie einen Doppelclick des Benutzers auf und startet somit das Spiel.</li>
</ol>
<h5>Die Klasse Player</h5>
<p align="justify">Diese Klasse verwaltet Punktestand und Leben des Spielers. Dazu verfügt sie über die Methoden getScore() und getLives(), die die aktuellen Werte an die Main - Klasse übergeben, ebenso wie die addScore(int plus) und looseLife() - Methoden, mit denen man Leben abziehen und Punkte hinzufügen kann.</p>
<h5>Die Klasse Ball</h5>
<p align="justify">Diese Klass enthält die kompliziertesten Methoden des Spiels. Sie definiert alle wichtigen Funktionen eines Ball Objektes. Diese sind:</p>
<ol start="1" type="1">
<li>Ball(...): In der Konstruktormethode werden alle relevanten Daten (Farbe des Balles, Bewegungsrichtung ...) an das Ball Objekt übergeben</li>
<li>move(): Diese Methode bewegt den Ball und testet durch den Aufruf von isOut() ob sich der Ball im Aus befindet</li>
<li>ballWasHit(): Diese Methode wird aufgerufen, wenn der Ball getroffen worden ist. Der Ball wird daraufhin auf seinen Startpunkt zurückgesetzt, die Richtung der Flugbahn neu bestimmt</li>
<li>userHit (int x, int y): Diese Methode testet mit Hilfe des Skalarproduktes (Details folgen später) ob der Ball bei einem Klick des Spielers getroffen wurde oder nicht</li>
<li>isOut(): Diese Methode testet, ob der Ball nach einer Bewegung im Aus ist oder nicht. Ist dies der Fall, so verliert der Spieler ein Leben.</li>
<li>DrawBall(Graphics g): Diese Methode zeichnet den Ball und wird in jedem Threaddurchlauf von der paint() - Methode der Main - Klasse aufgerufen</li>
</ol>
<h5>Zusammenspiel der einzelnen Methoden:</h5>
<p align="justify">Bei jedem Threaddurchlauf in der Main - Methode wird die move - Methode jedes Balles aufgerufen. Diese legt die neuen Koordinaten des Balles fest und testet zudem selbstständig, durch den Aufruf der Methode isOut(), ob der Ball im Aus oder noch im Spielfeld ist. Ist der Ball im Aus, so ruft isOut() die looseLife() - Methode des Player - Objektes auf und der Spieler verliert ein Leben. <br>
Immer wenn der Spieler in das Applet klickt, wird dieses Ereigniss von mouseDown in der Klasse Main aufgefangen und die Methode userHit () für beide Bälle aufgerufen. Diese testet, ob der Ball getroffen wurde und liefert je nach dem true oder false zurück. Ist der Rückgabewert true, so wird von der Main - Methode aus ballWasHit () aufgerufen, die alle weiteren nötigen Schritte (Ball zurücksetzen, Punkte des Spielers erhöhen...) ausführt.</p>
<h5>Bevor wir richtig starten noch ein Hinweis</h5>
<p align="justify">Zu allererst ist es wichtig, dass ihr euch den gesammten SourceCode des Spiels (am Ende der Seite) als *.zip - Archiv runterladet und immer im Auge habt, während ich den Code erkläre. Dabei werde ich nur auf bestimmte Teile des Programmes eingehen und ihr solltet in der Lage sein bzw. es bald lernen, den restlichen Sourcecode (mit Hilfe der andernen Kapitel) zu lesen und zu verstehen um euch auf diese Art und Weise weiteres Wissen anzueignen. <br>
Am allerwichtigsten aber ist es, dass ihr euch möglichst bald an ganz einfache, eigene Aufgaben wagt und euch überlegt wie ihr bestimmte Probleme in diesem Spiel gelöst hättet. Denn jedes Spiel erfordert ab einem gewissen Punkt ganz individuelle Lösungen, die ihr nirgendwo finden werdet und bei denen euch oft auch niemand helfen kann. Benutzt also dieses erste Spiel und die anderen Applets / Sourcecodes auf diesen bzw. anderen Seiten (siehe auch Links) als Ideeengeber und "Nachschlagewerke", mit deren Hilfe ihr eure eigenen Spiel entwickelt. Denn nur Übung macht den Meister!</p>
<h3>Flugrichtung des Balles zufällig gestallten</h3>
<p align="justify">Wie ich schon mal im ersten Kapitel angedeutet habe, wollen wir die beiden Bälle nun nicht mehr nur horrizontal über das Applet bewegen, sondern wir wollen beide Dimensionen (x und y - Koordinate) des Applets ausnutzen. Dazu müssen wir zu dem uns schon bekannten Richtungsvektor in x - Richtung (x_speed) noch einen weiteren in y - Richtung (y_speed) hinzufügen. Unser Ball hat also nun eine Geschwindigkeit in x - Richtung, die bei jedem Aufruf der Methode move() zur aktuellen x - Koordinate hinzugezählt wird und ebenso eine y - Geschwindigkeit, die jeweils zur y - Koordinate hinzuaddiert wird. Der y_speed soll bei beiden Bällen immer konstant bleiben. Dabei soll der eine Ball nach oben (y_speed = -1) und der andere Ball nach unten (y_speed = 1) fliegen. Man beachte, dass das Koordinatensystem von Java sozusagen auf dem Kopf steht (y - Werte werden von oben nach unten immer größer!). Des weiteren soll diese Geschwindigkeit in x - Richtung nach jedem Abschuss / Aus des Balles neu, per Zufall bestimmt werden.</p>
<h5>Ein Zufallsgenerator</h5>
<p align="justify">Zunächst müssen wir uns also einen Zufallsgenerator in Java beschaffen. Wir importieren hierfür die Klasse <i>java.util.*;</i> in unsere Ballklasse und deklarieren anschließend folgendes Objekt als Instanzvariable der Klasse Ball:<br></p>
<ul><i>Random rnd = new Random ();</i></ul>
<p align="justify">Nun können wir mit dem Befehl <i>rnd.nextInt()</i> eine zufällige Integerzahl erzeugen. Da wir eine Zahl zwischen -3 und +3 erzeugen wollen, müssen wir diese Zahl anschließend noch modulo 4 rechnen um nur Zahlen in diesem Zahlenraum zu erhalten. <br>
Nun können wir immer wenn ballWasHit() aufgerufen wird oder wenn isOut() den Wert true zurückliefert die neue Flugrichtung des Balles zufällig bestimmen, indem wir x_speed den zufallsgenerierten Wert zuweisen.</p>
<h5>Die move - Methode des Balles</h5>
<p align="justify">Nachdem wir die Instanzvariablen x_speed und y_speed deklariert und im Konstruktor initialisiert haben, können wir sie in jedem Aufruf von move() zu den aktuellen Koordinaten hinzuzählen. x_speed wird dabei immer wieder neu bestimmt (siehe oben), y_speed bleibt konstant. Die move() - Methode sieht also folgendermaßen aus:</p>
<ul><i>
public void move()<br>
{
<ul>
// Hinzuzählen der Speed - Variablen zu den aktuellen Koordinaten<br>
pos_x += x_speed;<br>
pos_y += y_speed;<br><br>
/* Aufrufen der Methode isOut() um zu testen, ob sich der Ball noch im Spielfeld befindet */<br>
isOut();<br>
</ul>
}<br>
</i></ul>
<h5>Die Methode isOut()</h5>
<p align="justify">Die Methode isOut() prüft, ob ein Ball eine der Grenzen des Spielfeldes überschritten hat. Trifft eine der vier Abfragen zu, so wird der Ball auf seine Startposition zurückgesetzt, eine Audiodatei abgespielt, die Flugrichtung neu bestimmt und der Spieler verliert ein Leben (wie genau, das folgt später noch). Das Prinzip ist das gleiche wie schon in unserem dritten Applet (BallReverse) besprochen, mit dem einzigen Unterschied, dass wir hier vier Grenzen haben, die wir nach möglichen Überschreitungen abfragen müssen und nicht nur zwei wie in unserem Beispiel aus Kapitel 1 c. Daher möchte ich nicht näher auf die programmiertechnische Seite dieser Methode eingehen, versucht stattdessen die einzelen Schritte (im Grunde ist es nur einer, der sich viermal wiederholt) alleine nachzuvollziehen (mit den gegebenen Kommentaren und dem Kapitel 1c sollte das kein Problem sein).</p>
<h3>Den Ball abschießen</h3>
<p align="justify">Dieses Problem ist wohl das Schwierigste in diesem Spiel. Der Ball hat ja eine x und eine y - Koordinate. Klickt der Spieler auf das Applet, so werden die x und die y - Koordinate mit an die aufgerufenen Methode userHit (int x, int y) übergeben. Nun muss die Methode entscheiden, ob der Schuss den Ball getroffen hat, oder nicht. Wie soll man das bewerkstelligen. <br> <br>
Es genügt nicht nur x und y - Koordinate des Balles mit denen des Schusses zu vergleichen (bei Gleichheit gilt der Ball dann als getroffen), denn dann müsste der Spieler immer genau die Mitte des noch dazu bewegten Balles treffen. Eine fast unlösbare Aufgabe! <br> <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -