import java.awt.Graphics; import java.awt.Image; import java.awt.Dimension; import java.awt.image.MemoryImageSource; import java.awt.event.MouseEvent; import java.awt.event.KeyEvent; import java.awt.AWTEvent; import java.applet.Applet; public class Shooter extends Applet implements Runnable { private Image image = null; private MemoryImageSource source = null; private volatile Thread thread = null; private volatile int state = 0; private boolean up, down, left, right, fire; private int score = 0; private static int[][] ship = { { 0x00000000, 0x00000000, 0xFF666666, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0xFF999999, 0x00000000, 0x00000000 }, { 0x00000000, 0xFF666666, 0xFFCCCCCC, 0xFF666666, 0x00000000 }, { 0x00000000, 0xFF999999, 0xFF6666FF, 0xFF999999, 0x00000000 }, { 0x00000000, 0xFFCCCCCC, 0xFF9999FF, 0xFFCCCCCC, 0x00000000 }, { 0xFFCCCCCC, 0xFFCCCCCC, 0xFFFFFFFF, 0xFFCCCCCC, 0xFFCCCCCC }, { 0xFFCCCCCC, 0xFFCCCCCC, 0xFFCCCCCC, 0xFFCCCCCC, 0xFFCCCCCC } }; private static int[][] bullet = { { 0xFFFFFF33 }, { 0xFFFFFF00 }, { 0xFFCCCC00 } }; private static int[][] alien = { { 0x00000000, 0xFF009900, 0xFF33FF33, 0xFF009900, 0x00000000 }, { 0xFF009900, 0xFF33FF33, 0xFF33FF33, 0xFF33FF33, 0xFF009900 }, { 0xFF33FF33, 0x00000000, 0xFFFF3333, 0x00000000, 0xFF33FF33 }, { 0xFF33FF33, 0x00000000, 0xFF33FF33, 0x00000000, 0xFF33FF33 }, { 0xFF33FF33, 0xFF009900, 0x00000000, 0xFF009900, 0xFF33FF33 }, { 0x00000000, 0xFF33FF33, 0x00000000, 0xFF33FF33, 0x00000000 } }; private static int[][] explosion = { { 0x00000000, 0xFFFF3333, 0xFFFF3333, 0xFFFF3333, 0x00000000 }, { 0xFFFF3333, 0xFFFF3333, 0xFFFF3333, 0xFFFF3333, 0xFFFF3333 }, { 0xFFFF3333, 0x00000000, 0xFFFF3333, 0x00000000, 0xFFFF3333 }, { 0xFFFF3333, 0x00000000, 0xFFFF3333, 0x00000000, 0xFFFF3333 }, { 0xFFFF3333, 0xFFFF3333, 0x00000000, 0xFFFF3333, 0xFFFF3333 }, { 0x00000000, 0xFFFF3333, 0x00000000, 0xFFFF3333, 0x00000000 } }; public void start() { (thread = new Thread( this )).start(); } protected void processMouseEvent( MouseEvent me ) { if ( me.getID() == MouseEvent.MOUSE_RELEASED ) { synchronized( this ) { requestFocus(); } } } protected synchronized void processKeyEvent( KeyEvent ke ) { int code = ke.getKeyCode(); boolean pressed = (ke.getID() == KeyEvent.KEY_PRESSED); if ( ke.getID() == KeyEvent.KEY_PRESSED || ke.getID() == KeyEvent.KEY_RELEASED ) { switch( code ) { case KeyEvent.VK_UP: up = pressed; break; case KeyEvent.VK_DOWN: down = pressed; break; case KeyEvent.VK_LEFT: left = pressed; break; case KeyEvent.VK_RIGHT: right = pressed; break; case KeyEvent.VK_SPACE: fire = pressed; break; case KeyEvent.VK_ESCAPE: state = (!pressed)? 0 : state; break; } } } public void run() { enableEvents( AWTEvent.MOUSE_EVENT_MASK ); enableEvents( AWTEvent.KEY_EVENT_MASK ); Dimension size = getSize(); int width = size.width; int height = size.height; int[] pixels = new int[ width*height ]; int x = 0, y = 0; // ship position int[][] aliens = new int[ 20 ][ 3 ]; int[][] bullets = new int[ 8 ][ 3 ]; synchronized( this ) { source = new MemoryImageSource( width, height, pixels, 0, width ); source.setFullBufferUpdates( true ); source.setAnimated( true ); image = createImage( source ); } //Thread.currentThread().setPriority( Thread.MIN_PRIORITY ); while( thread == Thread.currentThread() ) { if ( state == 0 ) { state = 1; x = width/2; y = height - (ship.length+2); for ( int i = 0; i < aliens.length; i++ ) { int[] a = aliens[ i ]; a[ 0 ] = (int)(width*Math.random()); a[ 1 ] = (int)((height-100)*Math.random()); a[ 2 ] = 1; // alive } for ( int i = 0; i < bullets.length; i++ ) { int[] b = bullets[ i ]; b[ 2 ] = 0; // inactive } score = 0; up = down = left = right = fire = false; } else if ( state == 1 ) { if ( up ) y-=2; if ( down ) y+=2; if ( left ) x-=2; if ( right ) x+=2; x = x < 0? 0 : (x >width? width: x); y = y < 0? 0 : (y >height? height: y); if ( fire ) { fire = false; for ( int i = 0; i < bullets.length; i++ ) { int[] b = bullets[ i ]; if ( b[ 2 ] == 0 ) { b[ 2 ] = 1; b[ 0 ] = x+ship[ 0 ].length/2; b[ 1 ] = y; break; } } } } for ( int i = 0; i < pixels.length; i++ ) { pixels[ i ] = 0xFF000000; } for ( int i = 0; i < aliens.length; i++ ) { int[] a = aliens[ i ]; if ( a[ 2 ] == 1 ) { put( width, height, pixels, alien, a[ 0 ], a[ 1 ] ); if ( state == 1 ) { if ( colliding( x, y, ship, a[ 0 ], a[ 1 ], alien ) ) { state = 2; // print score } else { for ( int j = 0; j < bullets.length; j++ ) { int[] b = bullets[ j ]; if ( b[ 2 ] > 0 ) { if ( colliding( b[ 0 ], b[ 1 ], bullet, a[ 0 ], a[ 1 ], alien ) ) { a[ 2 ] = 2; // killed it b[ 2 ] = 0; score++; } } } a[ 1 ] += 4; if ( Math.abs( a[ 1 ] - y ) > 30 ) a[ 0 ] += (int)(5*(0.5-Math.random())); else { if ( a[ 0 ] < x ) a[ 0 ]+=2; if ( a[ 0 ] > x ) a[ 0 ]-=2; } if ( a[ 1 ] > height ) { a[ 2 ] = 0; } } } } else if ( a[ 2 ] == 2 ) { put( width, height, pixels, explosion, a[ 0 ], a[ 1 ] ); a[ 2 ] = 0; } else if ( state == 1 ) { a[ 1 ] = -alien.length; // just above screen a[ 0 ] = (int)(width*Math.random()); a[ 2 ] = 1; } } for ( int i = 0; i < bullets.length; i++ ) { int[] b = bullets[ i ]; if ( b[ 2 ] > 0 ) { put( width, height, pixels, bullet, b[ 0 ], b[ 1 ] ); if ( state == 1 ) { b[ 1 ] -= 4; if ( b[ 1 ] < 0 ) b[ 2 ] = 0; } } } put( width, height, pixels, ship, x, y ); synchronized( this ) { source.newPixels(); repaint(); } try { Thread.sleep( 40 ); } catch( Exception e ) { } } } private void put( int width, int height, int[] pixels, int[][] sprite, int x, int y ) { for ( int j = 0; j < sprite.length; j++ ) { int[] r = sprite[ j ]; for ( int i = 0; i < r.length; i++ ) { int pixel = r[ i ]; if ( pixel != 0 ) { int px = x+i, py = y+j; if ( px >= 0 && px < width && py >= 0 && py < height ) { pixels[ py*width + px ] = pixel; } } } } } private boolean colliding( int x1, int y1, int[][] sprite1, int x2, int y2, int[][] sprite2 ) { int width1 = sprite1[ 0 ].length, height1 = sprite1.length; int width2 = sprite2[ 0 ].length, height2 = sprite2.length; if ( (x1 <= (x2+width2) && x2 <= x1) || (x2 <= (x1+width1) && x1 <= x2) ) { if ( (y1 <= (y2+height2) && y2 <= y1) || (y2 <= (y1+height1) && y1 <= y2) ) { // TODO pixel perfect collisions return true; } } return false; } public void stop() { thread = null; } public void update( Graphics g ) { paint( g ); } public synchronized void paint( Graphics g ) { if ( image != null ) { Dimension size = getSize(); //g.drawImage( image, 0, 0, size.width, size.height, this ); g.drawImage( image, 0, 0, this ); if ( state == 2 ) { g.setColor( java.awt.Color.white ); g.drawString( "Press Escape", 10, 20 ); g.drawString( "You Scored: " + score, 10, size.height/2 ); } } } }