java太阳系模型


我们知道太阳系有八大行星,围绕太阳,按照不同的速度转动;月亮围绕地球转动。星球都有各自的轨道。

我们可以先看实现效果:(真实场景是动态图)


可以先照着敲,本项目参考了北京尚学堂高琪老师的教学视频(感谢尚学堂高琪老师),并加入了一些自己的想法。

   注意:  在Java编写具有连贯变化的窗口程序时,通常的办法是在子类中覆盖父类的paint(Graphics)方法,在方法中使用实现窗口重绘的过程。连贯变换的窗口会不断地调用update(Graphics)函数,该函数自动的调用paint(Graphics)函数。这样就会出现闪烁的情况。
为了解决这一问题,可以应用双缓冲技术。可以通过截取上述过程,覆盖update(Graphics)函数,在内存中创建一个与窗口大小相同的图形,并获得该图形的图形上下文(Graphics),再将图片的图形上下文作为参数调用paint(Graphics)函数(paint(Graphics)中的GUI函数会在图片上画图),再在update(Graphics)函数调用drawImage函数将创建的图形直接画在窗口上。

源码如下(代码中有大量注释):

星球类:

package com.uwo9.solar;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;

import com.uwo9.util.GameUtil;

public class Star {

	Image img; //星球图片
	double x, y;//x轴坐标、y轴坐标
	String name;//星球名称
	int width,height;//图片宽度高度

	public void draw(Graphics g) {
		g.drawImage(img, (int) x, (int) y, null);
		if(this.name!=null){//画星球名称
			Color c = g.getColor();
			g.setColor(Color.white);
			g.drawString(this.name, (int) x, (int) y);
			g.setColor(c);
		}
	}

	public Star() {
	}

	/**
	 * 
	 * @param img 星球图片
	 */
	public Star(Image img) {
		this.img = img;
		this.width=img.getWidth(null);
		this.height=img.getHeight(null);
		System.out.println(this.width);
	}
	
	/**
	 * 
	 * @param img 星球图片
	 * @param x x轴坐标
	 * @param y y轴坐标
	 */
	public Star(Image img, double x, double y) {
		this(img);
		this.x = x;
		this.y = y;
	}
	
	/**
	 * 
	 * @param imgpath 星球图片地址
	 * @param x x轴坐标
	 * @param y y轴坐标
	 */
	public Star(String imgpath, double x, double y) {
		this(GameUtil.getImage(imgpath), x, y);
	}
	
	/**
	 * 
	 * @param imgpath 星球图片地址
	 * @param x x轴坐标
	 * @param y y轴坐标
	 * @param name 星球名称
	 */
	public Star(String imgpath, double x, double y,String name) {
		this(GameUtil.getImage(imgpath), x, y);
		this.name=name;
	}
}
行星类:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;

import com.uwo9.util.GameUtil;

public class Planet extends Star {

	double longAxis;// 椭圆长轴
	double shortAxis;// 椭圆短轴
	double speed;// 飞行的速度
	double degree;// 角度
	Star center;// 中心
	boolean satellite;// 是否卫星

	/**
	 * 
	 * @param center
	 *            中心
	 * @param imgpath
	 *            星球图片地址
	 * @param longAxis
	 *            轨道长轴
	 * @param shortAxis
	 *            轨道短轴
	 * @param speed
	 *            飞行速度
	 */
	public Planet(Star center, String imgpath, double longAxis, double shortAxis, double speed) {
		super(GameUtil.getImage(imgpath));
		this.center = center;
		this.x = center.x + longAxis;
		this.y = center.y;
		this.longAxis = longAxis;
		this.shortAxis = shortAxis;
		this.speed = speed;
	}

	/**
	 * 
	 * @param center
	 *            中心
	 * @param imgpath
	 *            星球图片地址
	 * @param longAxis
	 *            轨道长轴
	 * @param shortAxis
	 *            轨道短轴
	 * @param speed
	 *            飞行速度
	 * @param name
	 *            星球名称
	 */
	public Planet(Star center, String imgpath, double longAxis, double shortAxis, double speed, String name) {
		this(center, imgpath, longAxis, shortAxis, speed);
		this.name = name;
	}

	/**
	 * 
	 * @param center
	 *            中心
	 * @param imgpath
	 *            星球图片地址
	 * @param longAxis
	 *            轨道长轴
	 * @param shortAxis
	 *            轨道短轴
	 * @param speed
	 *            飞行速度
	 * @param satellite
	 *            是否卫星
	 */
	public Planet(Star center, String imgpath, double longAxis, double shortAxis, double speed, boolean satellite) {
		this(center, imgpath, longAxis, shortAxis, speed);
		this.satellite = satellite;
	}

	/**
	 * 
	 * @param center
	 *            中心
	 * @param imgpath
	 *            星球图片地址
	 * @param longAxis
	 *            轨道长轴
	 * @param shortAxis
	 *            轨道短轴
	 * @param speed
	 *            飞行速度
	 * @param name
	 *            星球名称
	 * @param satellite
	 *            是否卫星
	 */
	public Planet(Star center, String imgpath, double longAxis, double shortAxis, double speed, String name,
			boolean satellite) {
		this(center, imgpath, longAxis, shortAxis, speed, name);
		this.satellite = satellite;
	}

	/**
	 * 
	 * @param img
	 *            星球图片
	 * @param x
	 *            x轴坐标
	 * @param y
	 *            y轴坐标
	 */
	public Planet(Image img, double x, double y) {
		super(img, x, y);
	}

	/**
	 * 
	 * @param imgpath
	 *            星球图片地址
	 * @param x
	 *            x轴坐标
	 * @param y
	 *            y轴坐标
	 * @param name
	 *            星球名称
	 */
	public Planet(String imgpath, double x, double y, String name) {
		super(imgpath, x, y, name);
	}

	@Override
	public void draw(Graphics g) {
		super.draw(g);
		if (!satellite) {
			drawTrace(g);
		}
		move();
	}

	/**
	 * 画轨迹
	 * 
	 * @param g
	 */
	public void drawTrace(Graphics g) {
		double ovalx, ovaly, ovalWidth, ovalHeight;
		ovalWidth = longAxis * 2;
		ovalHeight = shortAxis * 2;
		ovalx = (center.x + center.width / 2) - longAxis;
		ovaly = (center.y + center.height / 2) - shortAxis;

		Color c = g.getColor();
		g.setColor(Color.blue);
		g.drawOval((int) ovalx, (int) ovaly, (int) ovalWidth, (int) ovalHeight);
		g.setColor(c);
	}

	/**
	 * 沿着椭圆轨迹飞行
	 * 
	 */
	public void move() {
		x = (center.x + center.width / 2) + longAxis * Math.cos(degree) - this.width / 2;
		y = (center.y + center.height / 2) + shortAxis * Math.sin(degree) - this.height / 2;
		degree += speed;
	}

}
常量类:

/**
 * 游戏项目中的常量
 *
 */
public class Constant {
	/**
	 * 窗体宽度
	 */
	public static final int GAME_WIDTH=800;
	/**
	 * 窗体高度
	 */
	public static final int GAME_HEIGHT=600;
}
工具类:

package com.uwo9.util;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;

/**
 * 游戏开发中常用的工具类(比如:加载图片等方法)
 * 
 */
public class GameUtil {
	private GameUtil() {// 工具类通常会将构造方法私有
	}

	/**
	 * 
	 * @param path
	 *            图片地址
	 * @return
	 */
	public static Image getImage(String path) {
		
		BufferedImage image = null;
		try {
			URL u = GameUtil.class.getClassLoader().getResource(path);
			image = ImageIO.read(u);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return image;
	}
}

窗体

package com.uwo9.util;

import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class MyFrame extends Frame {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 4419278382442876209L;

	protected MyFrame(){}
	protected MyFrame(String s){
		super(s);
	}
	
	/**
	 * 加载窗口
	 */
	public void launchFrame() {
		setSize(Constant.GAME_WIDTH, Constant.GAME_HEIGHT);
		setLocation(100, 100);
		setVisible(true);

		new PaintThread().start();// 启动重画线程

		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
	}

	private Image offScreenImage = null;

	/**
	 * 利用双缓冲技术处理闪烁
	 */
	@Override
	public void update(Graphics g) {
		if (offScreenImage == null) {
			offScreenImage = this.createImage(this.getSize().width, this.getSize().height);
		}
		Graphics gOff = offScreenImage.getGraphics();
		print(gOff);
		g.drawImage(offScreenImage, 0, 0, null);
	}

	/**
	 * 定义一个重画窗口的线程类
	 *
	 */
	class PaintThread extends Thread {
		@Override
		public void run() {
			while (true) {
				repaint();
				try {
					Thread.sleep(40);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

}


主窗体

package com.uwo9.solar;

import java.awt.Graphics;
import java.awt.Image;

import com.uwo9.util.Constant;
import com.uwo9.util.GameUtil;
import com.uwo9.util.MyFrame;

/**
 * 太阳系的主窗口
 * 容器左上角为坐标点
 *
 */
public class SolarFrame extends MyFrame {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1219934545878639839L;

	protected SolarFrame(String s){
		super(s);
	}
	
	Image bg = GameUtil.getImage("images/bg.jpg");//背景
	//太阳
	Star sun = new Star("images/sun.jpg", Constant.GAME_WIDTH / 2, Constant.GAME_HEIGHT / 2,"太阳");
	//1.水星 
	Planet mercury = new Planet(sun, "images/Mercury.jpg", 50, 36, 0.4446,"水星");
	//2.金星 
	Planet venus = new Planet(sun, "images/Venus.jpg", 88, 67, 0.0176,"金星");
	//3.地球 
	Planet earth = new Planet(sun, "images/earth.jpg", 150, 93, 0.0108,"地球");
	//月球 
	Planet moom = new Planet(earth, "images/moon.jpg", 15, 10, 0.1332,"月球", true);
	//4.火星 
	Planet mars = new Planet(sun, "images/Mars.jpg", 210, 120, 0.0056,"火星");
	//5.木星 
	Planet jupiter = new Planet(sun, "images/jupiter.jpg", 240, 150, 0.0008,"木星");
	//6.土星 
	Planet saturn = new Planet(sun, "images/Saturn.jpg", 270, 180, 0.0004,"土星");
	//7.天王星 
	Planet uranus = new Planet(sun, "images/Uranus.jpg", 300, 210, 0.00008,"天王星");
	//8.海王星 
	Planet neptune = new Planet(sun, "images/Neptune.jpg", 350, 250, 0.00001,"海王星");

	@Override
	public void paint(Graphics g) {
		g.drawImage(bg, 0, 0, null);
		sun.draw(g);
		mercury.draw(g);
		venus.draw(g);
		earth.draw(g);
		moom.draw(g);
		mars.draw(g);
		jupiter.draw(g);
		saturn.draw(g);
		uranus.draw(g);
		neptune.draw(g);
	}

	public static void main(String[] args) {
		new SolarFrame("太阳系模型").launchFrame();
	}
}



  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值