| Start/ | End/ | |||
| True | False | - | Line | Source |
| 1 | /* | |||
| 2 | * [ JIGA ] | |||
| 3 | * | |||
| 4 | * Copyright (c) 2003 Glenn Sanson <glenn.sanson at free.fr> | |||
| 5 | * | |||
| 6 | * This code is distributed under the GNU Library General Public License | |||
| 7 | * | |||
| 8 | * This library is free software; you can redistribute it and/or | |||
| 9 | * modify it under the terms of the GNU Library General Public License | |||
| 10 | * as published by the Free Software Foundation; either version 2 of the | |||
| 11 | * License, or (at your option) any later version. | |||
| 12 | * | |||
| 13 | * This library is distributed in the hope that it will be useful, but | |||
| 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 16 | * Library General Public License for more details. | |||
| 17 | * | |||
| 18 | * You should have received a copy of the GNU Library General Public License | |||
| 19 | * along with this program; if not, write to the Free Software Foundation, Inc., | |||
| 20 | * 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| 21 | * | |||
| 22 | * | |||
| 23 | * [http://glenn.sanson.free.fr/jiga/] | |||
| 24 | */ | |||
| 25 | ||||
| 26 | package net.library.jiga; | |||
| 27 | ||||
| 28 | import java.applet.Applet; | |||
| 29 | import java.awt.Graphics; | |||
| 30 | import java.awt.Image; | |||
| 31 | import java.awt.Point; | |||
| 32 | import java.awt.event.MouseEvent; | |||
| 33 | import java.awt.event.KeyEvent; | |||
| 34 | import java.awt.event.MouseListener; | |||
| 35 | import java.awt.event.MouseMotionListener; | |||
| 36 | import java.awt.event.KeyListener; | |||
| 37 | ||||
| 38 | /** | |||
| 39 | * A time-driven version of the Applet class. | |||
| 40 | * Applet is event-based whereas most games -and lots of non games- require a "time-step" mechanism. | |||
| 41 | * This class should simplify basic devs | |||
| 42 | */ | |||
| 43 | public abstract class GameApplet extends Applet implements Runnable, KeyListener, MouseListener, MouseMotionListener { | |||
| 44 | ||||
| 45 | /** The time-step of the applet. By default, this value is set to 25 ms (= 40 frames per second) */ | |||
| 46 | protected static long REFRESH_RATE_MILLIS = 25; | |||
| 47 | ||||
| 48 | private Graphics gBack; | |||
| 49 | ||||
| 50 | private Image iBack; | |||
| 51 | ||||
| 52 | private GameScreen currentScreen; | |||
| 53 | ||||
| 54 | private GameContext currentContext; | |||
| 55 | ||||
| 56 | private GameMedia currentMedia; | |||
| 57 | ||||
| 58 | private SunAudioManager sunAudio; | |||
| 59 | ||||
| 60 | private int gameWidth, gameHeight; | |||
| 61 | ||||
| 62 | private int bufferWidth, bufferHeight; | |||
| 63 | ||||
| 64 | private boolean gameRunning, threadRunning; | |||
| 65 | ||||
| 66 | private int[] listKeys; | |||
| 67 | ||||
| 68 | private Point mousePosition; | |||
| 69 | ||||
| 70 | private boolean leftMouseButtonState; | |||
| 71 | ||||
| 72 | private boolean rightMouseButtonState; | |||
| 73 | ||||
| 74 | private Point screenPosition; | |||
| 75 | ||||
| 76 | private boolean isApplication = false; | |||
| 77 | ||||
| 78 | /** | |||
| 79 | * Initialise current app(let). | |||
| 80 | * This method is automatically called by the browser at launch time. | |||
| 81 | * When launched as application, initialisation is called by <code>AppletFrame</code> | |||
| 82 | * @AppletFrame | |||
| 83 | */ | |||
| 97 | 0 | 84 | public void init() { | |
| 85 | gameWidth = this.getSize().width; | |||
| 86 | gameHeight = this.getSize().height; | |||
| 87 | ||||
| 88 | bufferWidth = gameWidth; | |||
| 89 | bufferHeight = gameHeight; | |||
| 90 | screenPosition = new Point(0, 0); | |||
| 91 | ||||
| 92 | iBack = this.createImage(gameWidth, gameHeight); | |||
| 93 | gBack = iBack.getGraphics(); | |||
| 94 | ||||
| 95 | currentContext = new GameContext(); | |||
| 96 | currentMedia = new GameMedia(this); | |||
| 97 | ||||
| 95 | 0 | 98 | try { | |
| 99 | sunAudio = new SunAudioManager(this); | |||
| 1 | 100 | } catch (Exception e) { | ||
| 101 | System.err.println("Package sun.audio is not available"); | |||
| 102 | } | |||
| 103 | ||||
| 104 | gameInit(); | |||
| 105 | ||||
| 106 | setCurrentScreen(this.getInitialScreen()); | |||
| 107 | ||||
| 108 | listKeys = new int[0]; | |||
| 109 | mousePosition = new Point(0, 0); | |||
| 110 | ||||
| 95 | 0 | - | 111 | if (needsKeyEvents()) { |
| 112 | addKeyListener(this); | |||
| 113 | } | |||
| 114 | ||||
| 0 | 95 | - | 115 | if (needsMouseEvents()) { |
| 116 | addMouseListener(this); | |||
| 117 | addMouseMotionListener(this); | |||
| 118 | } | |||
| 119 | } | |||
| 120 | ||||
| 121 | /** | |||
| 122 | * Defines the double-buffer size. | |||
| 123 | * Double-buffer needn't have the same size as the screen, | |||
| 124 | * and can be larger (scrolling) | |||
| 125 | * @param newWidth The new double-buffer width | |||
| 126 | * @param newHeight The new double-buffer height | |||
| 127 | */ | |||
| 0 | 0 | - | 128 | public void setFrameBufferSize(int newWidth, int newHeight) { |
| 129 | bufferWidth = newWidth; | |||
| 130 | bufferHeight = newHeight; | |||
| 131 | screenPosition.setLocation(0, 0); | |||
| 132 | ||||
| 133 | iBack = this.createImage(Math.max(gameWidth, newWidth), Math.max(gameHeight, newHeight)); | |||
| 134 | gBack = iBack.getGraphics(); | |||
| 135 | } | |||
| 136 | ||||
| 137 | /** | |||
| 138 | * Defines the position of the screen within the double-buffer space | |||
| 139 | * @param x X-Coordinate of the screen | |||
| 140 | * @param y Y-Coordinate of the screen | |||
| 141 | */ | |||
| 0 | 0 | - | 142 | public void setScreenPosition(int x, int y) { |
| 143 | screenPosition.setLocation(Math.max(0, Math.min(x, bufferWidth - gameWidth)), Math.max(0, Math.min(y, bufferHeight - gameHeight))); | |||
| 144 | } | |||
| 145 | ||||
| 146 | /** | |||
| 147 | * Retrieves the current screen position in the double-buffer space | |||
| 148 | * @return The position of the upper left corner of the screen | |||
| 149 | */ | |||
| 0 | 0 | - | 150 | public Point getScreenPosition() { |
| 0 | - | 151 | return new Point(screenPosition); | |
| 152 | } | |||
| 153 | ||||
| 154 | /** | |||
| 155 | * Defines the current applet as application. | |||
| 156 | * This function should not be called directly | |||
| 157 | */ | |||
| 9 | 0 | 158 | public void setAsApplication() { | |
| 159 | this.isApplication = true; | |||
| 160 | } | |||
| 161 | ||||
| 162 | /** | |||
| 163 | * Checks whether the current applet is an application | |||
| 164 | * @return <code>true</code> only if the game was launched as application | |||
| 165 | */ | |||
| 0 | 0 | - | 166 | public boolean isApplication() { |
| 0 | - | 167 | return this.isApplication; | |
| 168 | } | |||
| 169 | ||||
| 170 | /** | |||
| 171 | * Retrieves the current sound manager object. | |||
| 172 | * @return the audio manager associated with the current processus | |||
| 173 | * @see SunAudioManager | |||
| 174 | */ | |||
| 95 | 0 | 175 | public final SunAudioManager getSunAudioManager() { | |
| 95 | 176 | return sunAudio; | ||
| 177 | } | |||
| 178 | ||||
| 179 | /** | |||
| 180 | * Defines whether this applet needs key data or not | |||
| 181 | * @return <code>true</code> if this feature is required | |||
| 182 | */ | |||
| 95 | 0 | 183 | public boolean needsKeyEvents() { | |
| 95 | 184 | return true; | ||
| 185 | } | |||
| 186 | ||||
| 187 | /** | |||
| 188 | * Defines whether this applet needs key data or not. | |||
| 189 | * N.B. : This consume a lot of CPU | |||
| 190 | * @return <code>true</code> if this feature is required | |||
| 191 | */ | |||
| 0 | 0 | - | 192 | public boolean needsMouseEvents() { |
| 0 | - | 193 | return true; | |
| 194 | } | |||
| 195 | ||||
| 196 | /** | |||
| 197 | * Returns applet width (NOT buffer width) | |||
| 198 | * @return Appl(let) width | |||
| 199 | */ | |||
| 42661 | 0 | 200 | public final int getWidth() { | |
| 42661 | 201 | return gameWidth; | ||
| 202 | } | |||
| 203 | ||||
| 204 | /** | |||
| 205 | * Returns applet height (NOT buffer height) | |||
| 206 | * @return Appl(let) width | |||
| 207 | */ | |||
| 42661 | 0 | 208 | public final int getHeight() { | |
| 42661 | 209 | return gameHeight; | ||
| 210 | } | |||
| 211 | ||||
| 212 | /** | |||
| 213 | * Returns buffer width | |||
| 214 | * @return Current buffer width | |||
| 215 | */ | |||
| 4808E4 | 0 | 216 | public final int getBufferWidth() { | |
| 4808E4 | 217 | return bufferWidth; | ||
| 218 | } | |||
| 219 | ||||
| 220 | /** | |||
| 221 | * Returns buffer height | |||
| 222 | * @return Current buffer height | |||
| 223 | */ | |||
| 4808E4 | 0 | 224 | public final int getBufferHeight() { | |
| 4808E4 | 225 | return bufferHeight; | ||
| 226 | } | |||
| 227 | ||||
| 0 | 0 | - | 228 | public final Image getBackgroundImage() { |
| 0 | - | 229 | return iBack; | |
| 230 | } | |||
| 231 | ||||
| 3790E3 | 0 | 232 | public final Graphics getBackgroundGraphics() { | |
| 3790E3 | 233 | return gBack; | ||
| 234 | } | |||
| 235 | ||||
| 24544 | 0 | 236 | public final GameContext getGameContext() { | |
| 24544 | 237 | return currentContext; | ||
| 238 | } | |||
| 239 | ||||
| 2000 | 0 | 240 | public final GameMedia getGameMedia() { | |
| 2000 | 241 | return currentMedia; | ||
| 242 | } | |||
| 243 | ||||
| 244 | public abstract GameScreen getInitialScreen(); | |||
| 245 | ||||
| 0 | 0 | - | 246 | public void gameInit() { |
| 247 | }; | |||
| 248 | ||||
| 480 | 0 | 249 | public final void setCurrentScreen(GameScreen newCurrentScreen) { | |
| 250 | currentScreen = newCurrentScreen; | |||
| 251 | currentScreen.initBackground(); | |||
| 252 | } | |||
| 253 | ||||
| 95 | 0 | 254 | public final void start() { | |
| 0 | 95 | - | 255 | while (threadRunning) |
| 256 | ; | |||
| 257 | ||||
| 258 | gameRunning = true; | |||
| 259 | ||||
| 260 | new Thread(this).start(); | |||
| 261 | } | |||
| 262 | ||||
| 95 | 0 | 263 | public final void stop() { | |
| 264 | gameRunning = false; | |||
| 265 | } | |||
| 266 | ||||
| 95 | 0 | 267 | public final void run() { | |
| 268 | long time; | |||
| 269 | ||||
| 270 | threadRunning = true; | |||
| 271 | ||||
| 1894E3 | 75 | 272 | while (gameRunning) { | |
| 273 | time = System.currentTimeMillis(); | |||
| 274 | ||||
| 275 | currentScreen.play(listKeys, mousePosition, leftMouseButtonState, rightMouseButtonState); | |||
| 276 | currentScreen.refreshAll(); | |||
| 277 | currentScreen.paintAll(); | |||
| 278 | ||||
| 279 | time = System.currentTimeMillis() - time; | |||
| 280 | ||||
| 1892E3 | 1115 | 281 | if (time < REFRESH_RATE_MILLIS) { | |
| 1892E3 | 0 | 282 | try { | |
| 283 | Thread.sleep(REFRESH_RATE_MILLIS - time); | |||
| 0 | - | 284 | } catch (Exception e) { | |
| 285 | System.err.println("[Thread] - Unable to sleep"); | |||
| 286 | } | |||
| 287 | } | |||
| 288 | ||||
| 1893E3 | 71 | 289 | if (gameRunning) { | |
| 290 | paint(this.getGraphics()); | |||
| 291 | } | |||
| 292 | } | |||
| 293 | ||||
| 294 | threadRunning = false; | |||
| 295 | } | |||
| 296 | ||||
| 1896E3 | 0 | 297 | public final void paint(Graphics g) { | |
| 1896E3 | 0 | - | 298 | if (iBack != null) { |
| 299 | g.drawImage(iBack, -screenPosition.x, -screenPosition.y, this); | |||
| 300 | } | |||
| 301 | } | |||
| 302 | ||||
| 31812 | 0 | 303 | public final void keyPressed(KeyEvent e) { | |
| 304 | int currentKey = e.getKeyCode(); | |||
| 305 | ||||
| 17 | 31795 | 306 | if (currentKey == 18) { | |
| 17 | 307 | return; | ||
| 308 | } | |||
| 309 | ||||
| 9690 | 22105 | 310 | if (listKeys.length != 0) { | |
| 1122 | 8568 | 311 | if (listKeys[0] != currentKey) { | |
| 312 | int[] newListKeys = new int[listKeys.length + 1]; | |||
| 313 | ||||
| 314 | newListKeys[0] = currentKey; | |||
| 1204 | 1122 | 315 | for (int i = 0; i < listKeys.length; i++) { | |
| 316 | newListKeys[i + 1] = listKeys[i]; | |||
| 317 | } | |||
| 318 | ||||
| 319 | listKeys = newListKeys; | |||
| 320 | } | |||
| 321 | } else { | |||
| 322 | listKeys = new int[1]; | |||
| 323 | listKeys[0] = currentKey; | |||
| 324 | } | |||
| 325 | } | |||
| 326 | ||||
| 23239 | 0 | 327 | public final void keyReleased(KeyEvent e) { | |
| 328 | int currentKey = e.getKeyCode(); | |||
| 329 | ||||
| 23230 | 9 | 330 | if (listKeys.length != 0) { | |
| 331 | int[] newListKeys = new int[listKeys.length - 1]; | |||
| 332 | boolean found = false; | |||
| 333 | ||||
| 24434 | 23221 | 334 | for (int i = 0; i < listKeys.length; i++) { | |
| 882 | 23552 | 335 | if (found) { | |
| 336 | newListKeys[i - 1] = listKeys[i]; | |||
| 337 | } else { | |||
| 1200 | 22352 | 338 | if (i != listKeys.length - 1) { | |
| 339 | newListKeys[i] = listKeys[i]; | |||
| 340 | } | |||
| 341 | } | |||
| 342 | ||||
| 23221 | 1213 | 343 | if (listKeys[i] == currentKey) { | |
| 344 | found = true; | |||
| 345 | } | |||
| 346 | ||||
| 9 | 24425 | 347 | if (i == listKeys.length - 1 && !found) { | |
| 9 | 347 | T && T | ||
| 23221 | 347 | T && F | ||
| 1204 | 347 | F && _ | ||
| 9 | 348 | return; | ||
| 349 | } | |||
| 350 | } | |||
| 351 | ||||
| 352 | listKeys = newListKeys; | |||
| 353 | } | |||
| 354 | } | |||
| 355 | ||||
| 313 | 0 | 356 | public final void keyTyped(KeyEvent e) { | |
| 357 | } | |||
| 358 | ||||
| 0 | 0 | - | 359 | public final void mouseClicked(MouseEvent e) { |
| 360 | } | |||
| 361 | ||||
| 0 | 0 | - | 362 | public final void mouseEntered(MouseEvent e) { |
| 363 | mousePosition = e.getPoint(); | |||
| 364 | ||||
| 365 | paint(this.getGraphics()); | |||
| 366 | } | |||
| 367 | ||||
| 0 | 0 | - | 368 | public final void mouseExited(MouseEvent e) { |
| 369 | mousePosition = e.getPoint(); | |||
| 370 | ||||
| 371 | paint(this.getGraphics()); | |||
| 372 | } | |||
| 373 | ||||
| 0 | 0 | - | 374 | public final void mousePressed(MouseEvent e) { |
| 375 | mousePosition = e.getPoint(); | |||
| 376 | ||||
| 377 | int buttons = e.getModifiers(); | |||
| 378 | ||||
| 0 | 0 | - | 379 | if ((buttons & MouseEvent.BUTTON1_MASK) == MouseEvent.BUTTON1_MASK) { |
| 380 | leftMouseButtonState = !leftMouseButtonState; | |||
| 381 | } | |||
| 382 | ||||
| 0 | 0 | - | 383 | if ((buttons & MouseEvent.BUTTON3_MASK) == MouseEvent.BUTTON3_MASK) { |
| 384 | rightMouseButtonState = !rightMouseButtonState; | |||
| 385 | } | |||
| 386 | ||||
| 387 | paint(this.getGraphics()); | |||
| 388 | } | |||
| 389 | ||||
| 0 | 0 | - | 390 | public final void mouseReleased(MouseEvent e) { |
| 391 | mousePosition = e.getPoint(); | |||
| 392 | ||||
| 393 | int buttons = e.getModifiers(); | |||
| 394 | ||||
| 0 | 0 | - | 395 | if ((buttons & MouseEvent.BUTTON1_MASK) == MouseEvent.BUTTON1_MASK) { |
| 396 | leftMouseButtonState = !leftMouseButtonState; | |||
| 397 | } | |||
| 398 | ||||
| 0 | 0 | - | 399 | if ((buttons & MouseEvent.BUTTON3_MASK) == MouseEvent.BUTTON3_MASK) { |
| 400 | rightMouseButtonState = !rightMouseButtonState; | |||
| 401 | } | |||
| 402 | ||||
| 403 | paint(this.getGraphics()); | |||
| 404 | } | |||
| 405 | ||||
| 0 | 0 | - | 406 | public final void mouseDragged(MouseEvent e) { |
| 407 | mousePosition = e.getPoint(); | |||
| 408 | ||||
| 409 | paint(this.getGraphics()); | |||
| 410 | } | |||
| 411 | ||||
| 0 | 0 | - | 412 | public final void mouseMoved(MouseEvent e) { |
| 413 | mousePosition = e.getPoint(); | |||
| 414 | ||||
| 415 | paint(this.getGraphics()); | |||
| 416 | } | |||
| 417 | } | |||
| ***TER 68% (66/97) of SOURCE FILE GameApplet.java | ||||