package com; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; /** * @author 玄雨 * @qq 821580467 * @date 2013-8-10 */ public class TestDraw { public static void main(String[] args) { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); MyPanel p = new MyPanel(); p.addMouseMotionListener(p); f.add(p); f.pack(); f.setVisible(true); } } class Utils { public static final boolean isArcArcCollides(float x1, float y1, float r1, float x2, float y2, float r2) { return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) <= (r1 + r2); } } class MyBoom { public final float x, y; public final float degree; public int life = 20; private Image data; public final int width = 20, height = 20; private float scale; public MyBoom(float x, float y, float degree) { this.x = x; this.y = y; this.degree = degree; scale = 0.2f; try { data = ImageIO.read(new File("boom.png")); } catch (IOException e) { e.printStackTrace(); } } public void drawSelf(Graphics2D g2d) { g2d.rotate(degree + Math.PI, x, y); int tempWidth = (int) (width * scale); int tempHeight = (int) (height * scale); g2d.drawImage(data, (int) x - tempWidth / 2, (int) y - tempHeight / 2, tempWidth, tempHeight, null); life--; scale = scale + 0.1f; g2d.rotate(-degree - Math.PI, x, y); } } class MyBullet { public float x, y; public final float speed; public final float speedX, speedY; public final float degree; public int life = 100; private Image data; public final int width = 15, height = 20; public MyBullet(float x, float y, float speedX, float speedY, float degree) { speed = 8; this.x = x; this.y = y; this.speedX = speedX; this.speedY = speedY; this.degree = degree; try { data = ImageIO.read(new File("bullet.png")); } catch (IOException e) { e.printStackTrace(); } } public void drawSelf(Graphics2D g2d) { g2d.rotate(degree + Math.PI, x, y); g2d.drawImage(data, (int) x - width / 2, (int) y - height / 2, width, height, null); g2d.rotate(-degree - Math.PI, x, y); } public void moveSelf() { this.x += speedX * speed; this.y += speedY * speed; life--; } } class MyEnemy { public float x, y; public float speedX, speedY; public float speed; public float degree; private Image data; public final int width = 40, height = 40; public MyEnemy(float x, float y) { this.x = x; this.y = y; speed = 1; try { data = ImageIO.read(new File("rubbish.png")); } catch (IOException e) { e.printStackTrace(); } } private void adjustDegree() { if (speedX == 0 && speedY >= 0) { degree = 0; } else if (speedX == 0 && speedY < 0) { degree = (float) Math.PI; } else if (speedY == 0 && speedX < 0) { degree = (float) Math.PI * 3 / 2; } else if (speedY == 0 && speedX > 0) { degree = (float) Math.PI / 2; } else if (speedX < 0 && speedY > 0) { degree = (float) (-Math.asin(speedX)); } else if (speedX > 0 && speedY > 0) { degree = (float) (Math.asin(-speedX)); } else if (speedX > 0 && speedY < 0) { degree = (float) (Math.PI - Math.asin(-speedX)); } else if (speedX < 0 && speedY < 0) { degree = (float) (Math.PI - Math.asin(-speedX)); } } public void setTowards(float x, float y) { float tempX = x - this.x; float tempY = y - this.y; float distance = (float) Math.sqrt(tempX * tempX + tempY * tempY); speedX = tempX / distance; speedY = tempY / distance; adjustDegree(); } public void drawSelf(Graphics2D g2d) { g2d.rotate(degree + Math.PI, x, y); g2d.drawImage(data, (int) x - width / 2, (int) y - height / 2, width, height, null); g2d.rotate(-degree - Math.PI, x, y); } public boolean ofOfBound() { return x < 0 || y < 0 || x > MyPanel.width || y > MyPanel.height; } public void moveSelf() { this.x += speedX * speed; this.y += speedY * speed; } } class MyCharactor { public float x, y; public float speedX, speedY; public float speed; public float degree; private Image data; public final int width = 40, height = 40; public MyCharactor(float x, float y) { this.x = x; this.y = y; speed = 2; try { data = ImageIO.read(new File("player.png")); } catch (IOException e) { e.printStackTrace(); } } private void adjustDegree() { if (speedX == 0 && speedY >= 0) { degree = 0; } else if (speedX == 0 && speedY < 0) { degree = (float) Math.PI; } else if (speedY == 0 && speedX < 0) { degree = (float) Math.PI * 3 / 2; } else if (speedY == 0 && speedX > 0) { degree = (float) Math.PI / 2; } else if (speedX < 0 && speedY > 0) { degree = (float) (-Math.asin(speedX)); } else if (speedX > 0 && speedY > 0) { degree = (float) (Math.asin(-speedX)); } else if (speedX > 0 && speedY < 0) { degree = (float) (Math.PI - Math.asin(-speedX)); } else if (speedX < 0 && speedY < 0) { degree = (float) (Math.PI - Math.asin(-speedX)); } } public void setTowards(float x, float y) { float tempX = x - this.x; float tempY = y - this.y; float distance = (float) Math.sqrt(tempX * tempX + tempY * tempY); speedX = tempX / distance; speedY = tempY / distance; adjustDegree(); } public void drawSelf(Graphics2D g2d) { g2d.rotate(degree + Math.PI, x, y); g2d.drawImage(data, (int) x - width / 2, (int) y - height / 2, width, height, null); g2d.rotate(-degree - Math.PI, x, y); } public void moveSelf() { this.x += speedX * speed; this.y += speedY * speed; } public MyBullet autoShot() { return new MyBullet(x, y, speedX, speedY, degree); } } class MyPanel extends JPanel implements MouseMotionListener { private static final long serialVersionUID = 1L; public static final int width = 800, height = 480; private MyCharactor c; private List<MyBullet> bullets; private List<MyEnemy> enemies; private List<MyBoom> booms; private int step; private int fps = 1000 / 60; private int de_time; private int de_sleep; private boolean flag = true; private Image back; public MyPanel() { super(); this.setPreferredSize(new Dimension(width, height)); c = new MyCharactor(width / 2, height / 2); bullets = new ArrayList<MyBullet>(); enemies = new ArrayList<MyEnemy>(); booms = new ArrayList<MyBoom>(); try { back = ImageIO.read(new File("background.jpg")); } catch (IOException e1) { e1.printStackTrace(); } new Thread(new Runnable() { @Override public void run() { while (flag) { long start = System.currentTimeMillis(); repaint(); long end = System.currentTimeMillis(); if (end - start < fps) { try { Thread.sleep(fps - (end - start)); de_time = (int) (end - start); de_sleep = (int) (fps - (end - start)); } catch (InterruptedException e) { } } } } }).start(); } public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D) g; g2d.setColor(Color.BLACK); if (back == null) { g2d.fillRect(0, 0, width, height); } else { g2d.drawImage(back, 0, 0, width, height, null); } for (int i = 0; i < bullets.size(); ++i) { MyBullet b = bullets.get(i); b.drawSelf(g2d); b.moveSelf(); if (b.life < 0) { bullets.remove(b); } for (int j = 0; j < enemies.size(); ++j) { MyEnemy e = enemies.get(j); if (Utils.isArcArcCollides(b.x, b.y, (b.width + b.height) / 4, e.x, e.y, (e.width + e.height) / 4)) { booms.add(new MyBoom(e.x, e.y, e.degree)); enemies.remove(e); bullets.remove(b); continue; } } } for (int i = 0; i < enemies.size(); ++i) { MyEnemy e = enemies.get(i); e.drawSelf(g2d); e.moveSelf(); if (e.ofOfBound()) { // e.setTowards(c.x, c.y); enemies.remove(e); } } if (c != null) { c.drawSelf(g2d); c.moveSelf(); for (int i = 0; i < enemies.size(); ++i) { MyEnemy e = enemies.get(i); if (Utils.isArcArcCollides(c.x, c.y, (c.width + c.height) / 4, e.x, e.y, (e.width + e.height) / 4)) { System.out.println("碰上啦...."); flag = false; return; } } step++; if (step == 15) { step = 0; bullets.add(c.autoShot()); int key = (int) (Math.random() * 4); MyEnemy e; switch (key) { case 0: e = new MyEnemy(0, (float) (Math.random() * height)); e.setTowards(c.x, c.y); enemies.add(e); break; case 1: e = new MyEnemy(width, (float) (Math.random() * height)); e.setTowards(c.x, c.y); enemies.add(e); break; case 2: e = new MyEnemy((float) (Math.random() * width), 0); e.setTowards(c.x, c.y); enemies.add(e); break; case 3: e = new MyEnemy((float) (Math.random() * width), height); e.setTowards(c.x, c.y); enemies.add(e); break; } } } for (int i = 0; i < booms.size(); ++i) { MyBoom b = booms.get(i); b.drawSelf(g2d); if (b.life == 0) { booms.remove(b); } } g2d.setColor(Color.GRAY); g2d.drawString("渲染逻辑耗时:" + de_time + "ms", 10, 20); g2d.drawString("帧暂停的时间:" + de_sleep + "ms", 10, 40); } @Override public void mouseDragged(MouseEvent e) { int x = e.getX(); int y = e.getY(); c.setTowards(x, y); } @Override public void mouseMoved(MouseEvent e) { int x = e.getX(); int y = e.getY(); c.setTowards(x, y); } }