001 package com.croftsoft.apps.ajgp.basics; 002 003 import java.applet.Applet; 004 import java.applet.AudioClip; 005 import java.awt.Color; 006 import java.awt.Cursor; 007 import java.awt.Dimension; 008 import java.awt.Font; 009 import java.awt.Graphics2D; 010 import java.awt.Point; 011 import java.awt.Rectangle; 012 import java.awt.event.ComponentAdapter; 013 import java.awt.event.ComponentEvent; 014 import java.awt.event.KeyAdapter; 015 import java.awt.event.KeyEvent; 016 import java.awt.event.MouseAdapter; 017 import java.awt.event.MouseEvent; 018 import java.awt.event.MouseMotionAdapter; 019 import java.util.Random; 020 import javax.swing.Icon; 021 import javax.swing.ImageIcon; 022 import javax.swing.JComponent; 023 024 import com.croftsoft.core.CroftSoftConstants; 025 import com.croftsoft.core.animation.AnimatedApplet; 026 import com.croftsoft.core.animation.AnimationInit; 027 028 /********************************************************************* 029 * Game programming basics example. 030 * 031 * @version 032 * 2003-11-06 033 * @since 034 * 2003-10-05 035 * @author 036 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 037 *********************************************************************/ 038 039 public final class BasicsExample 040 extends AnimatedApplet 041 ////////////////////////////////////////////////////////////////////// 042 ////////////////////////////////////////////////////////////////////// 043 { 044 045 private static final String VERSION 046 = "2003-11-06"; 047 048 private static final String TITLE 049 = "CroftSoft Basics"; 050 051 private static final String APPLET_INFO 052 = "\n" + TITLE + "\n" 053 + "Version " + VERSION + "\n" 054 + CroftSoftConstants.COPYRIGHT + "\n" 055 + CroftSoftConstants.DEFAULT_LICENSE + "\n" 056 + CroftSoftConstants.HOME_PAGE + "\n"; 057 058 // 059 060 private static final Color BACKGROUND_COLOR 061 = Color.BLACK; 062 063 private static final Cursor CURSOR 064 = new Cursor ( Cursor.CROSSHAIR_CURSOR ); 065 066 private static final Font FONT 067 = new Font ( "Arioso", Font.BOLD, 20 ); 068 069 private static final Double FRAME_RATE 070 = new Double ( 30.0 ); 071 072 private static final Dimension FRAME_SIZE 073 = new Dimension ( 600, 400 ); 074 075 private static final String SHUTDOWN_CONFIRMATION_PROMPT 076 = "Close " + TITLE + "?"; 077 078 // 079 080 private static final String MEDIA_DIR = "media/basics/"; 081 082 private static final String AUDIO_FILENAME 083 = MEDIA_DIR + "drip.wav"; 084 085 private static final String IMAGE_FILENAME 086 = MEDIA_DIR + "croftsoft.png"; 087 088 // 089 090 private static final long RANDOM_SEED = 0L; 091 092 private static final Color BALL_COLOR = Color.RED; 093 094 private static final Color SCORE_COLOR = Color.GREEN; 095 096 private static final int VELOCITY = 3; 097 098 ////////////////////////////////////////////////////////////////////// 099 // final instance variables 100 ////////////////////////////////////////////////////////////////////// 101 102 private final Rectangle componentBounds; 103 104 private final Random random; 105 106 // 107 108 private final Rectangle ballRectangle; 109 110 private final Rectangle targetRectangle; 111 112 ////////////////////////////////////////////////////////////////////// 113 // non-final instance variables 114 ////////////////////////////////////////////////////////////////////// 115 116 private boolean componentResized; 117 118 private KeyEvent keyEvent; 119 120 private Point mousePoint; 121 122 private boolean mousePressed; 123 124 // 125 126 private AudioClip audioClip; 127 128 private Icon icon; 129 130 // 131 132 private boolean rolling; 133 134 private int score; 135 136 ////////////////////////////////////////////////////////////////////// 137 ////////////////////////////////////////////////////////////////////// 138 139 public static void main ( String [ ] args ) 140 ////////////////////////////////////////////////////////////////////// 141 { 142 launch ( new BasicsExample ( ) ); 143 } 144 145 private static AnimationInit createAnimationInit ( ) 146 ////////////////////////////////////////////////////////////////////// 147 { 148 AnimationInit animationInit = new AnimationInit ( ); 149 150 animationInit.setAppletInfo ( APPLET_INFO ); 151 152 animationInit.setCursor ( CURSOR ); 153 154 animationInit.setFont ( FONT ); 155 156 animationInit.setFrameIconFilename ( IMAGE_FILENAME ); 157 158 animationInit.setFrameRate ( FRAME_RATE ); 159 160 animationInit.setFrameSize ( FRAME_SIZE ); 161 162 animationInit.setFrameTitle ( TITLE ); 163 164 animationInit.setShutdownConfirmationPrompt ( 165 SHUTDOWN_CONFIRMATION_PROMPT ); 166 167 return animationInit; 168 } 169 170 ////////////////////////////////////////////////////////////////////// 171 ////////////////////////////////////////////////////////////////////// 172 173 public BasicsExample ( ) 174 ////////////////////////////////////////////////////////////////////// 175 { 176 super ( createAnimationInit ( ) ); 177 178 componentBounds = new Rectangle ( ); 179 180 random = new Random ( RANDOM_SEED ); 181 182 animatedComponent.addComponentListener ( 183 new ComponentAdapter ( ) 184 { 185 public void componentResized ( 186 ComponentEvent componentEvent ) 187 { 188 componentResized = true; 189 } 190 } ); 191 192 animatedComponent.addKeyListener ( 193 new KeyAdapter ( ) 194 { 195 public void keyPressed ( KeyEvent ke ) 196 { 197 keyEvent = ke; 198 } 199 } ); 200 201 animatedComponent.addMouseListener ( 202 new MouseAdapter ( ) 203 { 204 public void mousePressed ( MouseEvent mouseEvent ) 205 { 206 mousePressed = true; 207 } 208 } ); 209 210 animatedComponent.addMouseMotionListener ( 211 new MouseMotionAdapter ( ) 212 { 213 public void mouseMoved ( MouseEvent mouseEvent ) 214 { 215 mousePoint = mouseEvent.getPoint ( ); 216 } 217 } ); 218 219 ballRectangle = new Rectangle ( ); 220 221 targetRectangle = new Rectangle ( ); 222 } 223 224 ////////////////////////////////////////////////////////////////////// 225 // interface Lifecycle methods 226 ////////////////////////////////////////////////////////////////////// 227 228 public void init ( ) 229 ////////////////////////////////////////////////////////////////////// 230 { 231 super.init ( ); 232 233 animatedComponent.requestFocus ( ); 234 235 componentResized = true; 236 237 ClassLoader classLoader = getClass ( ).getClassLoader ( ); 238 239 audioClip = Applet.newAudioClip ( 240 classLoader.getResource ( AUDIO_FILENAME ) ); 241 242 icon = new ImageIcon ( 243 classLoader.getResource ( IMAGE_FILENAME ) ); 244 245 ballRectangle.width = icon.getIconWidth ( ); 246 247 ballRectangle.height = icon.getIconHeight ( ); 248 249 targetRectangle.width = icon.getIconWidth ( ); 250 251 targetRectangle.height = icon.getIconHeight ( ); 252 } 253 254 ////////////////////////////////////////////////////////////////////// 255 // interface ComponentAnimator methods 256 ////////////////////////////////////////////////////////////////////// 257 258 public void update ( JComponent component ) 259 ////////////////////////////////////////////////////////////////////// 260 { 261 if ( componentResized ) 262 { 263 componentResized = false; 264 265 component.repaint ( ); 266 267 component.getBounds ( componentBounds ); 268 269 if ( !rolling ) 270 { 271 ballRectangle.y = componentBounds.height - ballRectangle.height; 272 } 273 } 274 275 boolean rollRequested = false; 276 277 if ( mousePressed ) 278 { 279 mousePressed = false; 280 281 rollRequested = true; 282 } 283 284 int ballMove = 0; 285 286 if ( keyEvent != null ) 287 { 288 int keyCode = keyEvent.getKeyCode ( ); 289 290 switch ( keyCode ) 291 { 292 case KeyEvent.VK_SPACE: 293 294 rollRequested = true; 295 296 break; 297 298 case KeyEvent.VK_LEFT: 299 case KeyEvent.VK_KP_LEFT: 300 301 ballMove = -1; 302 303 break; 304 305 case KeyEvent.VK_RIGHT: 306 case KeyEvent.VK_KP_RIGHT: 307 308 ballMove = 1; 309 310 break; 311 } 312 313 keyEvent = null; 314 315 mousePoint = null; 316 } 317 318 if ( mousePoint != null ) 319 { 320 if ( mousePoint.x 321 < ballRectangle.x + ballRectangle.width / 2 - VELOCITY) 322 { 323 ballMove = -1; 324 } 325 else if ( mousePoint.x 326 > ballRectangle.x + ballRectangle.width / 2 + VELOCITY ) 327 { 328 ballMove = 1; 329 } 330 else 331 { 332 mousePoint = null; 333 } 334 } 335 336 if ( rollRequested ) 337 { 338 if ( !rolling ) 339 { 340 audioClip.play ( ); 341 342 rolling = true; 343 } 344 } 345 346 component.repaint ( targetRectangle ); 347 348 if ( rolling ) 349 { 350 component.repaint ( ballRectangle ); 351 352 ballRectangle.y -= VELOCITY; 353 354 boolean reset = false; 355 356 if ( targetRectangle.intersects ( ballRectangle ) ) 357 { 358 reset = true; 359 360 targetRectangle.x = -targetRectangle.width; 361 362 audioClip.play ( ); 363 364 score++; 365 366 component.repaint ( ); 367 } 368 else if ( ballRectangle.y + ballRectangle.height < 0 ) 369 { 370 reset = true; 371 372 if ( score > 0 ) 373 { 374 score--; 375 } 376 377 component.repaint ( ); 378 } 379 380 if ( reset ) 381 { 382 ballRectangle.y = componentBounds.height - ballRectangle.height; 383 384 rolling = false; 385 } 386 387 component.repaint ( ballRectangle ); 388 } 389 else if ( ballMove != 0 ) 390 { 391 component.repaint ( ballRectangle ); 392 393 ballRectangle.x += ballMove * VELOCITY; 394 395 if ( ballRectangle.x < 0 ) 396 { 397 ballRectangle.x = 0; 398 } 399 400 if ( ballRectangle.x 401 > componentBounds.width - ballRectangle.width ) 402 { 403 ballRectangle.x 404 = componentBounds.width - ballRectangle.width; 405 } 406 407 component.repaint ( ballRectangle ); 408 } 409 410 if ( score > 1 ) 411 { 412 targetRectangle.x += random.nextInt ( score ) * VELOCITY; 413 } 414 else 415 { 416 targetRectangle.x += VELOCITY; 417 } 418 419 if ( targetRectangle.x >= componentBounds.width ) 420 { 421 targetRectangle.x = -targetRectangle.width; 422 } 423 424 component.repaint ( targetRectangle ); 425 } 426 427 public void paint ( 428 JComponent component, 429 Graphics2D graphics ) 430 ////////////////////////////////////////////////////////////////////// 431 { 432 graphics.setColor ( BACKGROUND_COLOR ); 433 434 graphics.fill ( componentBounds ); 435 436 icon.paintIcon ( component, graphics, targetRectangle.x, 0 ); 437 438 graphics.setColor ( BALL_COLOR ); 439 440 graphics.fillOval ( 441 ballRectangle.x, 442 ballRectangle.y, 443 ballRectangle.width, 444 ballRectangle.height ); 445 446 graphics.setColor ( SCORE_COLOR ); 447 448 graphics.drawString ( 449 "Score: " + Integer.toString ( score ), 450 0, componentBounds.height ); 451 } 452 453 ////////////////////////////////////////////////////////////////////// 454 ////////////////////////////////////////////////////////////////////// 455 }