import java.awt.AWTEvent; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Polygon; import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.util.Random; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.SourceDataLine; import javax.swing.JApplet; public class BlackSh4rK extends JApplet implements Runnable { private static final float G = 2000.0f; private static final float D = 5.0f; private static final Polygon HULL = new Polygon( new int[]{-1,16,21,22,22,15,12,4,3,-2,-24,-28,-30,-32,-33,-28,-31},new int[]{-9,-9,-8,-6,-5,-3,0,1,2,2,-1,2,11,11,-2,-2,-3,},17); private int[] keys = new int[4]; private int mouseX,mouseY; private boolean shift; private boolean firingCannon; private boolean firingRocket; public BlackSh4rK() { BufferedImage cursor = new BufferedImage(32,32,BufferedImage.TYPE_INT_ARGB); Graphics g2d = cursor.getGraphics(); g2d.setColor(Color.BLACK); g2d.drawLine(16+2,16+2,16+8,16+8); g2d.drawLine(16+2,16-2,16+8,16-8); g2d.drawLine(16-2,16-2,16-8,16-8); g2d.drawLine(16-2,16+2,16-8,16+8); setCursor(Toolkit.getDefaultToolkit().createCustomCursor(cursor,new Point(16,16),null)); } public void start(){ Thread t = new Thread(this); t.start(); } public void processEvent(AWTEvent e) { switch(e.getID()){ case KeyEvent.KEY_PRESSED: case KeyEvent.KEY_RELEASED: KeyEvent ke = (KeyEvent)e; if (ke.getKeyCode() >= 37 && ke.getKeyCode() <= 40){ int down = (ke.getID() == KeyEvent.KEY_PRESSED)?1:0; keys[ke.getKeyCode() - 37] = down; shift = (ke.getModifiersEx() & KeyEvent.SHIFT_DOWN_MASK) != 0; } break; case MouseEvent.MOUSE_MOVED: case MouseEvent.MOUSE_DRAGGED: mouseX = ((MouseEvent) e).getX(); mouseY = ((MouseEvent) e).getY(); break; case MouseEvent.MOUSE_PRESSED: if (((MouseEvent)e).getButton() == MouseEvent.BUTTON1){ firingCannon = true; } else { firingRocket = true; } break; case MouseEvent.MOUSE_RELEASED: if (((MouseEvent)e).getButton() == MouseEvent.BUTTON1){ firingCannon = false; } else { firingRocket = false; } break; } } public void run() { int mx = 0; int my = 0; float x = 64; float y = 64; float angle = 0; float gunAngle = 0; int i,j; int step = 0; BufferedImage backBuffer = new BufferedImage(640,480, 2); // lifeTime,x,y,vx,vy float bullets[][] = new float[128][5]; int bulletHead = 0; // lifeTime,x,y,angle,tx,ty float rockets[][] = new float[64][7]; int rocketHead = 0; // lifeTime,x,y,vx,vy,r,g,b,size float particles[][] = new float[512][9]; int particleHead = 0; float fx = 0,fy = 0; float vx = 0,vy = 0; float dt = 0; long lastTime = System.nanoTime(); Random rand = new Random(); Polygon[] ground = new Polygon[2]; for(j = 0; j < ground.length; j++){ ground[j] = new Polygon(); ground[j].addPoint(0,50); } j = 0; for(i = 0; i < 100; i++){ ground[0].addPoint(i*100 +rand.nextInt(50),32 + rand.nextInt(16)); j += rand.nextInt(8) - (i>50?5:3); ground[1].addPoint(i*20 +rand.nextInt(10),96 + j*4); } ground[0].addPoint(10000,50); ground[0].addPoint(10000,0); ground[0].addPoint(0,0); ground[1].addPoint(1800,50); ground[1].addPoint(1800,0); ground[1].addPoint(0,0); enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK); while(true){ int xoff = (int)(x > 120 ?-x-200:-320); int yoff = (int)(y > 240 ?-y:-240); if (xoff < -10000+320) xoff = -10000+320; if (yoff < -360) yoff = -360; mx = mouseX - xoff - 320; my = 240 - mouseY - yoff; if(!this.hasFocus()){ requestFocus(); } Graphics2D g2d = (Graphics2D)backBuffer.getGraphics(); //g2d.setPaint(PAINT); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); dt = (System.nanoTime() - lastTime)/1e9f; angle += (((keys[2]-keys[0])*(shift?0.5f:0.2f) - angle))*5*dt; float thrust = G*(1 + (keys[1]*(shift?2.0f:1.0f) - keys[3]*(shift?2.0f:1.0f))); fx = thrust*(float)Math.sin(angle) - vx*D*0.2f; fy = -G + thrust*(float)Math.cos(angle) - vy*D; vx += fx*dt; vy += fy*dt; x += vx*dt; y += vy*dt; if (y > 600) y = 600; if (y < 32) y = 32; lastTime = System.nanoTime(); AffineTransform tx = g2d.getTransform(); g2d.translate(320, 240); g2d.scale(1, -1); AffineTransform bt = new AffineTransform(); if (firingCannon && step%5 == 0){ bt.rotate(-angle,x,y); bt.translate(20,-8); float[] b = bullets[bulletHead]; b[0] = 1.0f; b[1] = x; b[2] = y; bt.transform(b, 1, b, 1, 1); b[3] = (float)Math.cos(gunAngle-angle + rand.nextFloat()*0.1f - 0.05f)*1000; b[4] = (float)Math.sin(gunAngle-angle + rand.nextFloat()*0.1f - 0.05f)*1000; bulletHead = (bulletHead+1)%bullets.length; } if (firingRocket && step%20 == 0){ bt.setToIdentity(); bt.rotate(-angle,x,y); bt.translate(0,-8); float[] r = rockets[rocketHead]; r[0] = 5.0f; r[1] = x; r[2] = y; bt.transform(r, 1, r, 1, 1); r[3] = -angle; r[4] = mx; r[5] = my; rocketHead = (rocketHead+1)%rockets.length; } g2d.setColor(new Color(220,170,135)); g2d.translate(-320,-240); g2d.fillRect(0,0,640,480); g2d.setColor(new Color(108,93,83)); g2d.translate(xoff/10,yoff/10); g2d.fillPolygon(ground[1]); g2d.translate(-xoff/10,-yoff/10); g2d.translate(320,240); g2d.translate(xoff,yoff); g2d.setColor(new Color(36,31,28)); g2d.fillPolygon(ground[0]); int dx = mouseX-xoff-320; int dy = 240 - mouseY - yoff; dx -= x; dy -= y; gunAngle = (float)Math.atan2(dy,dx) + angle; if (gunAngle < -0.5f) gunAngle = -0.5f; if (gunAngle > 0.2f) gunAngle = 0.2f; for(i = 0; i < rockets.length; i++){ float[] r = rockets[i]; if (r[0] > 0.0f){ g2d.setColor(Color.GRAY); g2d.setStroke(new BasicStroke(2,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER)); dx = (int)(Math.cos(r[3])*8); dy = (int)(Math.sin(r[3])*8); g2d.drawLine((int)r[1],(int)r[2],(int)(r[1]-dx),(int)(r[2]-dy)); r[0] -= dt; r[1] += dt*dx*100; r[2] += dt*dy*100; dx = (int)(r[4] - r[1]); dy = (int)(r[5] - r[2]); if ((dx*dx + dy*dy) < 2048){ r[4] = r[1] + (int)(Math.cos(r[3])*10000); r[5] = r[2] + (int)(Math.sin(r[3])*10000); } r[3] += (Math.atan2(r[5] - r[2], r[4] - r[1]) - r[3])*dt*10.0f; // Explode! if (r[2] < 32){ r[0] = 0.0f; for(j = 0; j < 100; j++){ float[] p = particles[particleHead]; p[0] = 1.0f; p[1] = r[1]; p[2] = r[2]; p[3] = rand.nextInt(100) - 50; p[4] = 200 + rand.nextInt(200); p[5] = 0.28f; p[6] = 0.24f; p[7] = 0.22f; p[8] = 2 + rand.nextInt(4); particleHead = (particleHead + 1)%particles.length; } float[] p = particles[particleHead]; p[0] = 0.5f; p[1] = r[1]; p[2] = r[2]; p[3] = 0; p[4] = 0; p[5] = 1.0f; p[6] = 1.0f; p[7] = 1.0f; p[8] = 64; particleHead = (particleHead + 1)%particles.length; } } } Color c1 = new Color(255,255,255,64); Color c2 = new Color(255,255,255,255); g2d.setStroke(new BasicStroke(1)); for(i = 0; i < bullets.length; i++){ float[] b = bullets[i]; if (b[0] > 0.0f){ g2d.setColor(c1); g2d.drawLine((int)b[1],(int)b[2],(int)(b[1]- b[3]*dt*0.3),(int)(b[2]-b[4]*dt*0.3)); g2d.setColor(c2); g2d.fillOval((int)b[1]-1,(int)b[2]-1,2,2); b[0] -= dt; b[1] += dt*b[3]; b[2] += dt*b[4]; if (b[2] < 32){ b[0] = 0.0f; for(j = 0; j < 10; j++){ float[] p = particles[particleHead]; p[0] = 1.0f; p[1] = b[1]; p[2] = b[2]; p[3] = rand.nextInt(50) - 25; p[4] = 200 + rand.nextInt(100); p[5] = 0.28f; p[6] = 0.24f; p[7] = 0.22f; p[8] = 1 + rand.nextInt(2); particleHead = (particleHead + 1)%particles.length; } } } } g2d.setClip(-xoff-320,32,640,480); for(i = 0; i < particles.length; i++){ float[] p = particles[i]; if (p[0] > 0.0f){ g2d.setColor(new Color(p[5],p[6],p[7],p[0])); g2d.fillOval((int)(p[1]-p[8]/2),(int)(p[2]-p[8]/2),(int)p[8],(int)p[8]); p[0] -= dt; p[1] += dt*p[3]; p[2] += dt*p[4]; p[4] -= G*dt*0.5f; if (p[2] < 32){ p[2] = 32; } } } g2d.translate(x,y); g2d.rotate(-angle); g2d.setColor(Color.DARK_GRAY.darker().darker()); g2d.fillPolygon(HULL); g2d.drawLine(0,2,0,12); dx = (int)(8*Math.cos(gunAngle)); dy = (int)(8*Math.sin(gunAngle)); g2d.drawLine(18,-8,18+dx,-8+dy); c1 = new Color(64,64,64,128); c2 = new Color(128,128,128,128); if (step%2 == 0){ g2d.setColor(c1); g2d.fillOval(-24,4,48,3); g2d.setColor(c2); g2d.fillOval(-24,12,48,3); } else { g2d.setColor(c2); g2d.fillOval(-24,4,48,3); g2d.setColor(c1); g2d.fillOval(-24,12,48,3); } g2d.setTransform(tx); getGraphics().drawImage(backBuffer,0,0,null); try { Thread.sleep(10); } catch (InterruptedException e) {} step++; } } }