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

📄 platformgamebasicseng.html

📁 java tutorial all about java game design
💻 HTML
📖 第 1 页 / 共 3 页
字号:
<html><!-- InstanceBegin template="/Templates/template.dwt" codeOutsideHTMLIsLocked="false" -->
<head>
<!-- InstanceBeginEditable name="doctitle" -->
<title>Java Cooperation: platform game basics </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="TutorialStartEng.html"><img src="Pics/engpanel_01.gif" width="56" height="22" border="0"></a><a href="OnlineSpieleStartEng.html"><img src="Pics/engpanel_02.gif" width="94" height="22" border="0"></a><a href="DownloadsEng.html"><img src="Pics/engpanel_03.gif" width="76" height="22" border="0"></a><a href="LinksEng.html"><img src="Pics/engpanel_04.gif" width="52" height="22" border="0"></a><a href="KontaktEng.html"><img src="Pics/engpanel_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="indexDeu.html" onmouseover="cancelCloseMenu(); return true" onmouseout="initiateHideMenu(); return true">German</a><br>
<a href="#" 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>Platform game basics </h2>
  <p align="justify">Since I started to implement <a href="Applets/Games/JrioGame/JrioEng.html">J-Rio </a> one year ago, I thought about writing a tutorial chapter about the basics of platform games, but until today I never had the time to do it. But as many mails I got in the last year included questions about techniques of J-rio and platform games in general, I think that such a chapter could be very usefull to some of you. Also as I won't give the sourcecode of J-rio away, people that asked me for the sourcecode have with this chapter the chance to take a look behind the scenes of my J-rio implementation because the example applet we will implement in this chapter is some kind of a lite version of J-rio. Well, ok, I hope that I can help you a little bit with this chapter and before we start you should take one more look at the chapters about the <a href="LeveleditorEng.html">level editor </a> and about <a href="ScrollingEng.html">scrolling </a> because I'll use the techniques I introduced in those chapters in our platform game but I won't talk about them in detail anymore. You should also <a href="SourceCodes/PlatformGameBasics/PlatformGameBasics.zip">download the sourcecode </a> of the example applet now and work the code through while you read this tutorial. This chapter won't give you the details to every line of code but I'll focus on three major problems. First, we'll take a closer look at the <a href="#PlatformGameKlassendesign">class design </a> I have chosen to implement the game, second, we'll talk about the methods and attributes of the <a href="#PlatformGamePlayerObjekt">player class </a> where I'll focus on things that are related to the movement of the player and last but not least we'll talk about <a href="#PlatformGameLevelObjekt">the structure and function of the class level </a>. </p>
  <h3><a name="PlatformGameKlassendesign">The class design of our platform game </a></h3>
  <p align="justify">The more complex a game (or any other program) gets, the more important becomes a good class design to allow the programmer to add new functions to the game easily. In our case (or in my case when I implemented J-rio) we want to have the possiblity to add new enemies and level elements to our already released game without any major changes of the code and it should also be easy to write new levels for the game. I think that I managed those problems pretty well with the J-rio class design and that's why I'll use it in our case too, even though there might be simpler but maybe not so powerful solutions (this does not mean that I found the only correct solution and there might not be better ones than mine!). For example it is really easy to add new levels to J-rio, just take a look at the <a href="../../../Downloads/J-RioLevelEditor.zip">J-rio level editor </a>. <br>
  If you downloaded the sourcecode of this chapter and extracted the *.zip - file you'll find the following classes (Note: what follows now is just an overview, many details will follow later): </p>
  <h4>The class <em>Main </em></h4>
  <p align="justify">First of all the Main class implements the applet itself, which means the <strong>init() </strong>, <strong>start() </strong>, <strong>stop() </strong>, <strong>destroy() </strong> and <strong>paint(Graphics g) </strong> - methods and includes the main game thread within the method run() of the interface <strong>Runnable </strong>. It also holds methods to handle player events (keyDown...) and two attributes: an instance of the class player and one instance of a child class of the class level (in our case only the class LevelOne). In our <strong>run() </strong> - loop we manage the complete game which means to call methods to draw player and level, to scroll the level and the player if necessary, to test for collisions between player and level elements and so on. Please note that the class main does not implement one of those methods on its own but calls methods in the classes Player and Level. </p>
  <h4>The class <em>Player </em></h4>
  <p align="justify">This class implements behaviour and attributes of the player object. This means it holds information about the position of the player in the game, stores the player images used to animate the player and is also responsible to control the movement of the player (which is explained in detail later). </p>
  <h4>The class <em>LevelElement </em></h4>
  <p align="justify">A game like <strong>J-rio </strong> consists of many different kinds of level elements that have different attributes, behaviour and cause different interactions with the player. There are for example those "questionmark stones" that have at least two different states, which are "hit" and "not yet hit", moving platforms and the most simple level element, the ground element, that has no special behaviour at all. And for this chapter we will concentrate on this very simple element implemented in the class <strong>Ground </strong>. But despite those differences between the different kinds of level elements they have quite a bit of common behaviour, which is implemented in the class <strong>LevelElement </strong>, which is the basic class for every level element in our Platform game. This basic bahaviour contains the position of the level element, a unique integer identifier, a boolean variable "inSight" that is used for scrolling and painting the level element (see chapter about scrolling for details), as well as an Image - object to store the level element GIF. Every level element in J-rio extends the class LevelElement and the internal data structure of the class <strong>Level </strong> contains only instances of the child classes of the class <strong>LevelElement </strong> that are identified by their unique integer id. </p>
  <h4>The class <em>Ground </em></h4>
  <p align="justify">This class represents exactly such a child class of the class LevelElement. But this kind of LevelElement has no special behaviour so that it only calls the super constructor in its own constructor. </p>
  <h4>The class <em>Level </em></h4>
  <p align="justify">The abstract class <strong>Level </strong> is maybe the most important and complex class of the game. The class holds a method to translate the string representation of the level (given in the class LevelOne) to the internal data representation of the level which is a two dimensional array of LevelElement - instances. It also holds methods used for collision control between player and level elements. What the internal representation looks like, how it is created and how the collision control works will be explained later in this chapter. </p>
  <h4>The class <em>LevelOne </em></h4>
  <p align="justify">This class contains level specific definitions especially the definition of the level itself consisting of 25 strings representing 25 rows of the level. The color of the background can also be manipulated using the initializeColorArray() method of the class LevelOne. </p>
  <h4>Die Klasse <em>C_Jump </em></h4>
  <p align="justify">To make changes of the game size, levelelement size... easier all constants used in the game are written down in a special class, in our case in the class C_jump. </p>
  <h4>How the classes work together </h4>
  <p align="justify">As I already said the class <strong>Main </strong> holds an instance of the <strong>Player </strong> - object, as well as an instance of a child class of the class <strong>Level </strong>. <strong>Main </strong> is also responsible for managing the complete game. The class <strong>Player </strong> is used to store player specific attributes and to move, draw, animate and scroll the player correctly, whereas the class <strong>Level </strong> is used to hold the internal representation of the level, to draw and to scroll the level as well as to test for collisions between the player and level elements. A level is implemented by a child class of the class <strong>Level </strong>, in our case by the class <strong>LevelOne </strong>. When we construct a instance of the class LevelOne, the string representation of the level is translated to the two dimensional array of <strong>LevelElement </strong> - objects, stored in the parent class of LevelOne <strong>Level </strong>. Every level element is a child class of <strong>LevelElement </strong>, in our platform game there is only the class <strong>Ground </strong>. <br>
  I hope that I could make clear now, why I designed the classes like I did, if there are any problems left you maybe should take a look at the <a href="LeveleditorEng.html">level editor chapter </a>, where I used quite the same design but maybe a little bit simpler. Now, we'll take a closer look at the classes <strong>Player </strong> and <strong>Level </strong>. </p>
  <h3><a name="PlatformGamePlayerObjekt">Details of the class <em>Player </em></a></h3>
  <p align="justify">The animation and movement control of the player is very important for our game. But to control the movement of the player in a platform game is not that simple as it might seem, because we have to take care that our player has to stop walking or jumping if he hits a wall, he has to fall down of any platform if the end is reached, has to stop falling if he lands on a platform and so on. That's why I'm going to explain my solotion to those problems within the next part of this chapter. <br>
  First of all you have to recognize that in this platform game the movement of the player is controlled in a indirect way using boolean flags. In our player class / object the keyboard input of the human player and results of the collisions control in the class Level only set boolean values of four movement flags and do not cause any movement of the player on their own (which means they don't change the x of y positions). The run() - method of the class Main calls a method named playerMove() of our Player class which now moves the player according to the values of the movement flags. Let's take a closer look on those flags: </p>
  <h4>The four movement flags and their control </h4>
  <p align="justify">Our player object as four, partly independent movement flags: </p>
  <ul>
    <li>
      <p align="justify"><strong>walking_left </strong>: shows if the player should move to the left and is mainly controlled by the keyboard input of the human player, so its value is set to true if the left arrow key is pressed and is set to false if the key is released. But the flag is also influenced by the collision control of the level, becaues our player has to stop movement if it hits a wall on its left side. </p>
    <li>
      <p align="justify"><strong>walking_right </strong>: same as the walking_left flag, only in the other direction (no surprise I think ;-) </p>
    <li>
      <p align="justify"><strong>jumping </strong>: this flag indicates that our player has to jump. But things are a little bit more complicated here because on the one hand, this movement is controlled by two controllers: the human player pressing or releasing the 'a' - key and the collision control of the level class (for example if the player bangs his head against a wall). On the other hand the player may not be able to jump one more time if he's already jumping or he may not jump if he's falling and so on, details on those problems and their solution follow later. </p>
    <li>
      <p align="justify"><strong>falling </strong>: This flag is only controlled by the collision control of the level class (set to true if the player leaves a platform...). Here we need some tricks too to stop the player right on the surface of a new platform (or at least to correct mistakes made here) and so on, details again later. </p>
    </li>
  </ul>
  <p align="justify">The <strong>walking_left </strong> and <strong>walking_right </strong> as well as the <strong>falling </strong> and <strong>jumping </strong> flags may not be true at the same time. But falling / jumping and walking_left / walking_right are completely independent from each other so they can be true together because our player must have the chance to jump to the left or to fall to the right side. The movement flags are controlled from two different sides: the keyboard input of the human player and the collision control of the level class, we'll discuss later this chapter. But now we'll take a look at the set - methods for our boolean flags and the playerMove() - method that does the movement work for us. </p>
  <p align="justify">The set - methods for the walking_left and walking_right values are really simple, here is the code. </p>
  <ul>
    <em> // Method sets the value of the walking_left flag <br>
  public void playerWalkLeft(boolean value) <br>
  { <br>
    </em>
    <ul>
      <em> walking_left = value; </em>
    </ul>
    <em>} <br>
    <br>
  // Method sets the value of the walking_right flag <br>
  public void playerWalkRight(boolean value) <br>
  { <br>
    </em>
    <ul>
      <em> walking_right = value; </em>
    </ul>
    <em>} <br>
    </em>
  </ul>
  <p align="justify">In case of the flag <strong>jumping </strong> it's getting a little bit more complicated because we have to take care of some more things, when we set the value. First of all the player can only jump, if he's not already falling which means that the value of <strong>falling </strong> is false and if the player is not already jumping so the value of another flag <strong>jump_lock </strong> has to be false too. One more thing is, that we will use a counter <strong>jump_counter </strong> to contoll the length of the jump. This counter must be reset to 0 when the player starts a new jump which means that the values of the flags are: <strong>jumping </strong> = false, <strong>jump_lock </strong> = false and value is true. You'll find some details on the jump_counter later this chapter. Here comes the code: </p>
  <ul>
    <em> // Method to set the value of the jumping flag <br>
  public void playerJump(boolean value) <br>
  { <br>
    </em>
    <ul>
      <em> // reset jump_counter if player starts a new jump <br>
    if(!jumping &amp;&amp; !jump_lock &amp;&amp; value) <br>
    { <br>
      </em>
      <ul>
        <em> jump_counter = 0; </em>
      </ul>
      <em>} <br>
      <br>
    // the player can only jump, if he's not already falling <br>
    if(falling) <br>
    { <br>
      </em>
      <ul>
        <em> jumping = false; </em>
      </ul>
      <em>} <br>
    else <br>
    { <br>
      </em>
      <ul>
        <em> jumping = value; </em>
      </ul>
      <em>} <br>
      </em>
    </ul>
    <em>} <br>
    </em>
  </ul>
  <p align="justify">The last one of the four flags is the <strong>falling </strong> flag. With this flag, it is important that if falling is set to false which means the player lands on a platform, we have to end a jump (jump_lock and jumping must be set to false). One more thing is, that in some cases the player does not stop moving right on the surface of the platform but a little bit more down so that it seem the player would be standing right in the platform. So we have to correct errors that happen here. We also have to take care that the player can't jump and fall at the same time but this is guarantied somewhere else (in the method playerMove()). </p>

⌨️ 快捷键说明

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