📄 leveleditordeu.html
字号:
<html><!-- InstanceBegin template="/Templates/template.dwt" codeOutsideHTMLIsLocked="false" -->
<head>
<!-- InstanceBeginEditable name="doctitle" -->
<title>Java Cooperation: leveleditor</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>Leveleditor</h2>
<p align="justify">In diesem Kapitel wollen wir euch eine Möglichkeit vorstellen einen Leveleditor zu programmieren, den man in jedem beliebigen, arraybasierten Javaspiel verwenden kann. Vorstellbare Anwendungsmöglichkeiten dieses Leveleditors wären z. B. ein Breakoutklon, Boulderdash, PacMan, ein "Jump and Run" Spiel oder auch ein Nibbles - Klon wie unser Spiel <a href="Applets/Games/Snakin/Snakin.html">Snakin</a>. Bevor ihr weiterlest solltet ihr euch mit der Verwendung von Arrays sowie Applet Parametern vertraut machen, falls ihr es noch nicht seid.</p>
<h3>Wozu braucht man einen Leveleditor?</h3>
<p align="justify">Obwohl die Antwort auf diese Frage eigentlich selbsterklärend ist möchte ich kurz darauf eingehen. Einen Leveleditor zu programmieren und das Spiel danach so auszurichten, dass es mit jedem beliebigen erstellten Level funktioniert, ist wesentlich schwieriger, als ein Spiel zu programmieren, das nur in einer statischen Levelumgebung läuft. Dennoch lohnt sich dieser anfängliche Mehraufwand immer dann, wenn man sein Spiel mit vielen verschiedenen Leveln ausstatten will. Hat man sein Spiel von Anfang an auf einen Leveleditor und damit erstellte Level eingerichtet, so ist das Hinzufügen weiterer Level eine Sache von wenigen Minuten. Hat man das Spieldesign dagegen nur auf statische Level ausgerichtet, so ist es sehr schwer, vielleicht sogar unmöglich, neue Level hinzuzufügen. Diese Überlegung ist im Grunde für jede Software von Bedeutung. Oft ist ein anfänglicher Mehraufwand an Designüberlegungen am Ende "Gold wert" und erspart dem Programmierer (also euch) eine Menge Ärger wenn die Software erweitert werden soll, als eine schnelle "zusammengahackte" Lösung. So, nach dieser "Moralpredigt" wollen wir uns nun dem eigentlichen Problem widmen.</p>
<h3>Die Grundidee</h3>
<p align="justify">Unabhängig davon, wo und wie genau wir die Level unseres Spieles definieren, was im nächsten Abschnitt erklärt wird, müssen wir uns darüber Gedanken machen, wie das Level intern im Spiel dargestellt werden soll. <br>
Wir werden über unser Spielfeld ein rechteckiges Raster legen und in dieses Raster unsere Spielsteine bzw. Levelelemente platzieren. Somit ist die Position jedes Elementes auf dem Spielfeld eindeutig durch das Rasterquadrat, in dem es sich befindet, bestimmt. Intern werden wir hierzu eine zweidimensionale Matrix erzeugen, deren Reihen und Spalten unser gerastertes Spielfeld representieren. Wir werden nun je nach Aussehen des Levels, das wir geschrieben haben, diese Matrix mit verschiedenen Levelelementen füllen. Immer wenn wir das Level zeichnen werden wir die gesammte Levelmatrix durchlaufen und jedes Objekt in der Matrix an jener Position im Spielfeld zeichnen, an der das Object in der Matrix auftaucht. Aufbauend auf dieser ziemlich einfachen Idee wenden wir uns nun der Fragestellung zu, wo und wie wir das Level definieren wollen, mit dem wir später unsere Matrix füllen wollen.</p>
<h3>Wo und wie definieren wir die Level?</h3>
<p align="justify">Da wir ja Applets programmieren haben wir grundsätzlich drei Möglichkeiten wo wir die Level unseres Spiels definieren:</p>
<ol start="1" type="1">
<li>In einer externen Datei</li>
<li>Im Sourcecode des Spiels</li>
<li>In der HTML Seite, in der das Applet laufen soll mit Hilfe von Appletparametern</li>
</ol>
<p align="justify">Die Möglichkeiten 1 und 2 sind aus verschiedenen Gründen für Applets nicht so gut geeignet wie die dritte Alternative. Das Einlesen von externen Dateien in das Applet ist nicht ganz einfach und fällt daher weg. Die Level im Sourcecode des Spiels zu definieren ist dann in Ordnung, wenn man nicht will, dass der Spieler die Level einsehen kann (z. B. wenn man jedes Level mit einem Passwort versieht oder das Ziel des Spiels darin besteht ein Level zu erkunden), ist jedoch ungeeignet um dem Spieler die Definition eigener Level zu ermöglichen. Die Grundidee des dritten Ansatzes, den wir im Folgenden verwenden werden, kann jedoch bei Bedarf ohne Probleme auf die beiden anderen Ansätze übertragen werden. </p>
<p align="justify">Wir werden unsere Level also mit Hilfe von Appletparametern definieren. Diese können innerhalb des Applet - Tags in einer HTML - Seite definiert werden und können vom Applet mit Hilfe der getParameter (Parametername) - Methode eingelesen werden. Appletparamter haben immer die Gestallt: <br> <br>
<ul><param name= "Name des Parameters" value="Wert des Paramters"><br><br></ul>
<p align="justify">Unsere Level werden nun immer aus 3 Informationsparametern und 8 Levelzeilen bestehen. dabei werden die Namen der Parameter immer folgenden Aufbau haben: "Level" + "Levelnummer" + "_" + "Identifikator". Der Identifikator kann dabei die Werte "Author", "Name", "Comment" oder "Line" + "Zeilennummer" annehmen. Die value - Strings können im Falle der Informationsparameter beliebige Strings sein, die Levelzeilen hingegen werden immer aus 10 Buchstaben bestehen die die einzelnen Steine des Levels in verschiedenen Farben bestimmen. Diese Farben sind r = rot, g = grün, b = blau und y = gelb sowie ein Platzhalter ":" der Stellen definiert, an denen kein Stein plaziert werden soll. Die einzige Stelle an der sich die die Namen der Levelparameter verschiedener Level unterscheiden ist also die Levelnummer. Daher können wir leicht in einer while oder for - Schleife alle Level von 1 bis zu der in "Levels_in_total" definierten Zahl nacheinander einlesen (siehe readLevel - Methode unten).
Im Folgenden seht ihr die Struktur eines Levels, das unser Leveleditor einlesen kann.</p>
<code>
<ul>// Beginn des Applettags, mit normalen Applet Informationen<br>
<applet code = Main width=300 height=400><br><br>
// Diese Zeile gibt an, wieviele Level insgesammt definiert sind<br>
<param name="Levels_in_total" value="1"><br><br>
// Diese Zeilen speichern allgemeine Informationen über unser Level<br>
<param name="Level1_Author" value="FBI"><br>
<param name="Level1_Name" value="Test Level 1"><br>
<param name="Level1_Comment" value="My first try"><br><br>
// Das eigentliche Level<br>
<param name="Level1_Line0" value="rrrrrrrrrr"><br>
<param name="Level1_Line1" value="bbbbbggggg"><br>
<param name="Level1_Line2" value="r::rrrr::r"><br>
<param name="Level1_Line3" value="yyyyybbbbb"><br>
<param name="Level1_Line4" value="rrr::::rrr"><br>
<param name="Level1_Line5" value="gggggyyyyy"><br>
<param name="Level1_Line6" value="r::rrrr::r"><br>
<param name="Level1_Line7" value="bgybgrybgy"><br><br>
// Ende des Applet Tags<br>
</applet>
</ul>
</code>
<h3>Das Klassendesign des Leveleditors</h3>
<p align="justify">Um nun ein, auf die oben dargestellte Weise definiertes, Level in unser Spiel einzulesen und dort verwenden zu können werden wir für unseren Leveleditor nun folgende Klassen benötigen:</p>
<ol start="1" type="1">
<li><u>LevelReader</u>: <p align="justify">Diese Klasse wird die in dem Parameter "Levels_in_total" angegebene Zahl von Leveln mit Hilfe der getParameter(Parametername) - Methode einlesen und für jedes gelesene Level eine Instanz der Klasse Level (siehe unten) erzeugen sowie alle erzeugten Level in einem Levelarray speichern. Anschließend gibt die Methode readLevels(), die das Einlesen bewerkstelligt, das erzeugte Levelarray an die aufrufende Klasse zurück.</p></li>
<li><u>Level</u>: <p align="justify">Diese Klasse speichert zum Einen alle Informationen über ein Level, also Name des Authors, Name des Levels und die Beschreibung. Zum Anderen verfügt jedes Level über ein zweidimensionales Array (stone map), das die Positionen der Steine in einem Level speichert bzw. Objekte der Klasse Stone (siehe unten), die ihre jeweilige Position und Farbe "kennen". Außerdem hat jedes Level noch eine eigene paint - Methode, die das Level zeichnet.</p></li>
<li><u>Stone</u>: <p align="justify">Diese Klasse speichert Farbe und Position eines Steines in einer Stonemap. Die Position des Steines wird im Konstruktor aufgrund der Position des Steines in der Stonemap des Levels berechnet. Ein Stein verfügt zudem über eine eigene paint(Graphics g) - Methode, die den Stein an der richtigen Position im Level und in der richtigen Farbe zeichnet.</p></li>
<li><u>Main</u>: <p align="justify">Diese Klasse speichert das Levelarray und zeichnet das Level, das im Moment aus dem Levelarray ausgewählt ist. Außerdem behandelt sie die Benutzereingaben.</p></li>
<li><u>C_LevelEditor</u>: <p align="justify">Diese Klasse beinnhaltet alle im Leveleditor vorkommenden Konstanten, wie z. B. die Anzahl der Zeilen aus der ein Level besteht, den Abstand der Steine zueinander sowie ihre Größe, die Namen der Identifikatoren... . So lässt sich der Leveleditor leicht auf mehrere Levelzeilen, veränderte Größe der Rasterquadrate, andere Identifikatornamen... erweitern.</p></li>
</ol>
<h3>Der Sourcecode der wichtigsten Methoden</h3>
<p align="justify">Wie immer werde ich nicht auf jede einzelne Methode des Leveleditors eingehen. Ich werde im Folgenden nur die wichtigsten Methoden und Klassen besprechen. Dazu gehören LevelReader und seine Methode readLevels(), sowie die Klasse Level. Auf die Klassen Main, Stone und C_LevelEditor werde ich nicht näher eingehen, was heißt, dass ihr euch wie immer den Sourcecode runterladen und euch die anderen Methoden und Klassen selbst ansehen solltet.</p>
<h4>LevelReader</h4>
<p align="justify">Zunächst einmal müssen wir alle in der HTML - Seite definierten Level in unser Spiel einlesen und als Levelobjekte in einem Array aus Levelelementen speichern. Dies geschieht in der Klasse LevelReader mit Hilfe der Methode readLevel(). Die Methode an sich ist relativ selbsterklärend, einzige Besonderheit ist, dass wir dem Levelreader eine Refferenz auf die Elternklasse des Applets (Parent) übergeben müssen, damit er mit der getParameter - Methode auf die Appletparameter in der HTML - Seite zugreifen kann. So, hier kommt die Klasse LevelReader:</p>
<ul>
<br>
import java.util.*;<br>
import java.applet.*;<br>
import java.awt.*;<br>
<br><br>
public class LevelReader<br>
{<br>
<ul>
// Variablen<br>
private int levels_in_total;<br><br>
// Array, speichert alle erzeugten Level<br>
private Level [] level_array;<br><br>
// Appletrefferenz<br>
private Component parent;<br><br>
public LevelReader (Component parent)<br>
{<br>
<ul>
// Initialisierung der Appletrefferenz<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -