1 //实现MyFrame--实现绘制窗口,和实现重写 重画窗口线程类 2 3 package cn.xiaocangtian.Test; 4 5 import java.awt.Frame; 6 import java.awt.event.WindowAdapter; 7 import java.awt.event.WindowEvent; 8 9 10 public class MyFrame extends Frame { 11 12 //加载窗口 13 public void launchFrame() { 14 setSize(Constant.GAME_WIDTH, Constant.GAME_HEIGHT); //设置窗口大小 15 setLocation(100, 100); //设置左上角坐标,开始位置, 也就是窗口开始位置 16 setVisible(true); //设置为可见(默认为不可见) 17 18 //启动重画线程 19 new PaintThread().start(); 20 21 //匿名内部类---用来关闭窗口 22 addWindowListener(new WindowAdapter() { 23 @Override 24 public void windowClosing(WindowEvent e) { 25 System.exit(0); 26 } 27 }); 28 29 } 30 31 /** 32 * 定义一个重画窗口的线程类 33 * 是一个内部类(方便访问外部类属性) 34 */ 35 class PaintThread extends Thread { 36 public void run() { 37 while (true) { 38 repaint(); //重画 39 try { 40 Thread.sleep(40); //1s = 1000ms 41 } catch (InterruptedException e) { 42 e.printStackTrace(); 43 } 44 } 45 } 46 } 47 48 }
1 package cn.xiaocangtian.Util; 2 3 import java.awt.Image; 4 import java.awt.Toolkit; 5 import java.awt.image.BufferedImage; 6 import java.io.IOException; 7 import java.net.URL; 8 9 import javax.imageio.ImageIO; 10 import javax.swing.ImageIcon; 11 12 /** 13 * 游戏开发中常用的工具类(比如:加载图片等方法) 14 * @author admin 15 * 16 */ 17 public class GameUtil { 18 19 private GameUtil () {} //工具类通常将构造方法私有 20 21 public static Image getImage(String path) { 22 // URL u = GameUtil.class.getClassLoader().getResource(path); 23 // BufferedImage img = null; 24 // try { 25 // img = ImageIO.read(u); 26 // } catch (IOException e) { 27 // e.printStackTrace(); 28 // } 29 // 30 // return img; //BufferedImage是Image子类,也算正确返回 31 return Toolkit.getDefaultToolkit().getImage(GameUtil.class.getClassLoader().getResource(path)); 32 } 33 }
1 package cn.xiaocangtian.Solar; 2 3 import java.awt.Graphics; 4 import java.awt.Image; 5 6 import cn.xiaocangtian.Util.GameUtil; 7 8 //封装成类 9 //导入图片 10 public class Star { 11 Image img; //用于导入图片 12 double x, y; //图片位置 13 int width, height; //图片长宽 14 15 public void draw(Graphics g) { 16 g.drawImage(img, (int)x, (int)y, null); 17 } 18 19 public Star() { //子类要调用父类的默认造函数 20 21 } 22 23 public Star(Image img) { 24 this.img = img; 25 this.width = img.getWidth(null); 26 this.height = img.getHeight(null); 27 28 } 29 30 public Star(Image img, double x, double y) { 31 this(img); 32 this.x = x; 33 this.y = y; 34 35 } 36 37 //导入 38 public Star(String imgpath, double x, double y) { 39 this(GameUtil.getImage(imgpath), x, y); 40 } 41 }
1 package cn.xiaocangtian.Util; 2 3 /** 4 * 游戏项目中用到的常量 5 * 单独负责常量 6 * @author admin 7 */ 8 public class Constant { 9 10 public static final int GAME_WIDTH = 750; 11 public static final int GAME_HEIGHT = 600; 12 13 }
1 package cn.xiaocangtian.Solar; 2 3 import java.awt.Color; 4 import java.awt.Graphics; 5 import java.awt.Image; 6 7 import cn.xiaocangtian.Util.GameUtil; 8 9 public class Planet extends Star { 10 11 //除了图片,坐标,行星沿着某个椭圆运行:长轴,短轴,速度, 角度,绕着某个Star飞 12 double longAxis; //椭圆的长轴 13 double shortAxis; //椭圆的短轴 14 double speed; //飞行的速度 15 double degree; //角度 16 Star center; //中心 17 boolean satillite; //标志是否是卫星 18 19 public void draw(Graphics g) { 20 super.draw(g); 21 move(); 22 if (!satillite) { //不是卫星再画出轨迹 23 drawTrace(g); 24 } 25 } 26 27 public void move() { 28 //沿着椭圆飞 29 x = (center.x + center.width/2) + longAxis * Math.cos(degree); 30 y = (center.y + center.height/2) + shortAxis * Math.sin(degree); 31 //速度不一样,所以增量也不同 32 degree += speed; 33 } 34 35 //画出行星的轨迹 36 public void drawTrace(Graphics g) { 37 double ovalX, ovalY, ovalWidth, ovalHeight; 38 ovalHeight = longAxis * 2; //长度即为长轴*2 39 ovalWidth = shortAxis * 2; 40 ovalX = (center.x + center.width/2) - longAxis; //左上顶点为(中心.x + x.width/2) - 长轴 41 ovalY = (center.y + center.height/2) - shortAxis; 42 43 Color oldColor = g.getColor(); 44 g.setColor(Color.blue); //设置轨迹颜色 45 g.drawOval((int)ovalX, (int)ovalY, (int)ovalHeight, (int)ovalWidth); 46 g.setColor(oldColor); 47 } 48 49 50 //需要调用父类的空构造器 51 public Planet(Star center, String imgpath, double longAxis, 52 double shortAxis, double speed) { 53 super(GameUtil.getImage(imgpath)); 54 55 this.center = center; 56 this.x = center.x + longAxis; //行星的位置 57 this.y = center.y; 58 59 this.longAxis = longAxis; //当前行星的长轴 60 this.shortAxis = shortAxis; 61 this.speed = speed; 62 63 this.width = img.getWidth(null); 64 this.height = img.getHeight(null); 65 } 66 67 public Planet(Star center, String imgpath, double longAxis, 68 double shortAxis, double speed, boolean satellite) { 69 this(center, imgpath, longAxis, shortAxis, speed); 70 this.satillite = satellite; 71 } 72 73 public Planet(Image img, double x, double y) { 74 super(img, x, y); 75 } 76 77 public Planet(String imgpath, double x, double y) { 78 super(imgpath, x, y); 79 } 80 81 }
1 package cn.xiaocangtian.Solar; 2 3 import java.awt.Graphics; 4 import java.awt.Image; 5 6 import cn.xiaocangtian.Util.Constant; 7 import cn.xiaocangtian.Util.GameUtil; 8 import cn.xiaocangtian.Util.MyFrame; 9 10 /** 11 * 太阳系主窗口 12 * @author admin 13 * 14 */ 15 public class SolarFrame extends MyFrame { 16 //导入背景 17 Image bg = GameUtil.getImage("images/yuzhou.png"); 18 //这里是利用封装的类,导入图片 19 Star sun = new Star("images/sun.png", Constant.GAME_WIDTH / 2, Constant.GAME_HEIGHT / 2); 20 Planet earth = new Planet(sun, "images/polar.png", 150, 100, 0.1); 21 Planet moon = new Planet(earth, "images/moon.png", 30, 20, 0.3, true); 22 Planet Mars = new Planet(sun, "images/Mars.png", 200, 130, 0.2); 23 24 /** 25 * 可以继续添加 其他 行星,只需一行代码(已经封装好) 26 * ...... 27 * ...... 28 * ...... 29 */ 30 31 /** 32 * 重写重绘函数,此为回调函数,只需要实现,然后由系统自动调用 33 */ 34 public void paint(Graphics g) { 35 g.drawImage(bg, 0, 0, null); 36 sun.draw(g); //这里使用的是封装的方法 37 earth.draw(g); 38 moon.draw(g); 39 Mars.draw(g); 40 41 /*** 42 * 还可以继续添加其他行星并绘制 43 * .......... 44 * .......... 45 * .......... 46 */ 47 } 48 49 public static void main(String[] args) { 50 new SolarFrame().launchFrame(); 51 } 52 }
//本程序只添加了太阳,地球,月球,火星,其余可以自行添加,使用封装好的方法,只用十分简洁的代码即可