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

📄 bildschirmflackerndeu.html

📁 java tutorial all about java game design
💻 HTML
字号:
<html><!-- InstanceBegin template="/Templates/template.dwt" codeOutsideHTMLIsLocked="false" -->
<head>
<!-- InstanceBeginEditable name="doctitle" -->
<title>Java Cooperation: bounce a ball</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>Reduzierung des Bildschirmflackerns</h2>
  <p align="justify">Wie ihr in dem vorigen Beispiel sicherlich bemerkt habt, flackert der Ball sehr stark, was sich bei wirklich aufwendigen Graphiken noch verst&auml;rken w&uuml;rde. Der Grund daf&uuml;r ist recht einfach. Vor jedem Aufruf der Methode paint() durch repaint() in unserem Thread wird das Bild vollst&auml;ndig gel&ouml;scht um dann erneut gezeichnet zu werden. Dadurch erscheint f&uuml;r den Bruchteil einer Sekunde ein vollkommen leerer Bildschirm, was wir als Flackern wahrnehmen. Um dieses Flackern des Bildes zu verhindern, gibt es zun&auml;chst drei verschiedene M&ouml;glichkeiten. </p>
  <ol start="1" type="1">
  <li>Bildschirm nicht l&ouml;schen</li>
  <li>Bildschirm nur dort l&ouml;schen, wo es n&ouml;tig ist</li>
  <li>Die Doppelpufferung</li>
  </ol><br>
  <h4>Bildschirm nicht l&ouml;schen</h4>
  <p align="justify">Dieser Ansatz erscheint auf den ersten Blick als die L&ouml;sung aller Probleme. In unserem Fall w&uuml;rde es aber bedeuten, dass der Ball eine dicke, rote Linie hinterlassen w&uuml;rde. Wir wollen den Ball aber als bewegten Ball wahrnehmen und nicht als Objekt, dass eine rote Linie hinter sich herzieht. Das L&ouml;schen des Bildschirmes zu unterdr&uuml;cken ist also nur f&uuml;r nicht bewegte Animationen sinnvoll. <br>
  Auch f&uuml;r den sp&auml;teren Verlauf dieser Lektion ist es wichtig zu verstehen, dass jedesmal wenn repaint() aufgerufen wird, nicht gleich auch die Methode paint() aufgerufen wird. Stattdessen ist eine Methode namens update() dazwischengeschaltet. Wird diese nicht &uuml;berschrieben, so ist diese Methode daf&uuml;r verantwortlich, dass der Bildschirm mit einem leeren Bild &uuml;berlagert und anschlie&szlig;end durch den Aufruf von paint() von der Methode update() aus, neu gezeichnt wird. Um also das L&ouml;schen des Bildschirms zu unterdr&uuml;cken, muss man update() so &uuml;berschreiben, dass sie nur noch paint() aufruft. Dies ist in drei Zeilen zu bewerkstelligen.</p>

  public void update(Graphics g)<br>
  {
  <ul>paint(g);</ul>
  }

  <p align="justify">Wie gesagt ist diese M&ouml;glichkeit nur bei statischen Animationen wirklich praktikabel und wird somit nur selten verwendet. </p>
  <h4>Bildschirm nur dort l&ouml;schen, wo es n&ouml;tig ist</h4>
  <p align="justify">Die Idee dieses Ansatzes besteht darin, den Bildschirm nur dort zu l&ouml;schen, wo sich im letzten Schritt ein Graphikelement befunden hat, sich nun aber keines mehr befindet. Dieser Ansatz l&auml;sst sich z. B. bei dem sehr bekannten Spiel Snakin' ganz gut umsetzen, indem man als letztes Glied der Schlange ein Element in der Farbe des Hintergrundes, und somit unsichtbares Element, anh&auml;ngt. Dadurch wird immer beim n&auml;chsten Schritt das vorher letzte Element &uuml;berlagert. Da sich diese Methode nur in bestimmten F&auml;llen anwenden l&auml;&szlig;t und dann immer nach einer, auf das spezifische Problem abgestimmten, Vorgehensweise verlangt, m&ouml;chte ich nicht n&auml;her auf diese Methode eingehen. Wenden wir uns stattdessen der sogenannten Doppelpufferung zu, die man als Standardmethode ohne Abwandlung in jedes Applet mit Animationen &uuml;bernehmen und somit das Flakern des Bildes effektiv unterdr&uuml;cken kann.
  </p>
  <h4>Die Doppelpufferung</h4>
  <p align="justify">Die Doppelpufferung kann in jedes Applet, ohne gro&szlig;en, programiertechnischen Aufwand eingebaut werden. Beim Doppelpuffern wird bei jedem Animationsschritt zun&auml;chst die gesamte Bildschirmausgabe in ein Offscreen-Image geschrieben. Erst wenn alle Ausgabeoperationen abgeschlossen sind, wird dieses Offscreen-Image auf die Fensteroberfl&auml;che kopiert. Im Detail sind dazu folgende Schritte erforderlich:</p>
  <ol start="1" type="1">
  <li>Das Fensterobjekt beschaft sich durch Aufruf von createImage ein Offscreen-Image und speichert es in einer Instanzvariablen ( = Erzeugen eines leeren Bildes)</li>
  <li>Durch Aufruf von getGraphics wird ein Grafikkontext zu diesem Image beschafft</li>
  <li>Alle Bildschirmausgaben (inklusive L&ouml;schen des Bildschirms) gehen zun&auml;chst auf den Offscreen-Grafikkontext ( = Zeichnen des Bildes im Hintergrund)</li>
  <li>Wenn alle Ausgabeoperationen abgeschlossen sind, wird das Offscreen-Image mit drawImage in das Ausgabefenster kopiert. ( = Zeichnen des Bildes im Vordergrund)</li>
  </ol>
  <p align="justify">
  Durch diese Vorgehensweise wird erreicht, da&szlig; das Bild komplett aufgebaut ist, bevor es angezeigt wird. Da beim anschlie&szlig;enden Kopieren die neuen Pixel direkt &uuml;ber die alten kopiert werden, erscheinen dem Betrachter nur die Teile des Bildes ver&auml;ndert, die auch tats&auml;chlich ge&auml;ndert wurden. Ein Flackern, das entsteht, weil Fl&auml;chen f&uuml;r einen kurzen Zeitraum gel&ouml;scht und dann wieder gef&uuml;llt werden, kann nicht mehr auftreten.</p>
  <p align="justify">Einziger, gravierender Nachteil der Doppelpufferung ist jedoch, dass die Konstruktion des OffscreenImages ziemlich speicheraufwendig ist, und au&szlig;erdem die Bilddaten zweimal geschrieben werden. In den meisten F&auml;llen und auf schnellen Rechnern ist es jedoch weitaus vorteilhafter, in sehr kurzer Zeit die Doppelpufferung zu realisieren, als sich lange mit der Suche nach alternativen M&ouml;glichkeiten aufzuhalten.</p>
  <p align="justify">So, aber nach der ganzen Theorie nun zur Implementierung der Doppelpufferung in unserem Ball - Applet aus dem letzten Kapitel!</p>
  <h5>Der Programcode zur Umsetzung der Doppelpufferung</h5>
  // Definition zweier Instanzvariablen f&uuml;r die Doppelpufferung im Kopf des Programmes<br>
  private Image dbImage;<br>
  private Graphics dbg;<br>
  <br>
  ... anderer Programcode ...<br>
  <br>
  /** Update - Methode, Realisierung der Doppelpufferung zur Reduzierung des Bildschirmflackerns */<br>
  public void update (Graphics g)<br>
  {<ul>
          // Initialisierung des DoubleBuffers<br>
          if (dbImage == null)<br>
          {<ul>
                  dbImage = createImage (this.getSize().width, this.getSize().height);<br>
                  dbg = dbImage.getGraphics ();<br>
          </ul>}<br>
  <br>
          // Bildschirm im Hintergrund l&ouml;schen<br>
          dbg.setColor (getBackground ());<br>
          dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);<br>
  <br>
          // Auf gel&ouml;schten Hintergrund Vordergrund zeichnen<br>
          dbg.setColor (getForeground());<br>
          paint (dbg);<br>
  <br>
          // Nun fertig gezeichnetes Bild Offscreen auf dem richtigen Bildschirm anzeigen<br>
          g.drawImage (dbImage, 0, 0, this);<br>
  </ul>}<br>

  <p align="justify">Wie schon erw&auml;hnt l&auml;&szlig;t sich der obige Programmcode in jedes Applet &uuml;bernehmen, so auch in unser Ball - Beispiel von vorher.</p>
  <p><a href="SourceCodes/Doppelpufferung/BallbewegungDoppel.java">SourceCode Applet download</a><br>
  <a href="SourceCodes/Doppelpufferung/Doppelpufferung.java">SourceCode Doppelpufferung download</a><br>
  <a href="Applets/Doppelpufferung/BallBewegung2Applet.html">Applet ansehen</a>
  <h4>N&auml;chstes Kapitel</h4>
<a href="BallStopDeu.html">Verhindern, dass der Ball sich aus dem Spielfeld bewegt</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 + -