用Java模拟一个太阳系的轨迹运转
程序员文章站
2022-07-13 11:06:25
...
模拟一个太阳系的轨迹运转
分类封装各种工具类
应用一些必要的条件,比如加载窗口,图片的加载,动画的实现
窗口加载类:
package duxuan.zqx.Util;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class MyFrame extends Frame {
/**
* 定义一个窗口的加载界面
*/
public void LoadWindow() {
setLocation(200,200); //定义窗口左上角的位置在(200,200)
setSize(Constant.MAX_WIDTH,Constant.MAX_HEIGHT); //定义窗口的宽度和高度
setVisible(true); //窗口可视化
new PaintThread().start(); //调用内部类的PaintThread 重画窗口
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
/**
* 定义一个重画窗口的线程类,是一个内部类
* @param args
*/
class PaintThread extends Thread{
public void run() {
while(true) {
repaint(); //重画窗口界面,一直重复调用加载窗口
try {
Thread.sleep(80); //1s = 1000ms,计算机休眠80ms
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
项目常量类:
package duxuan.zqx.Util;
public class Constant {
public static final int MAX_WIDTH = 900; //窗口的最大宽度
public static final int MAX_HEIGHT =800; //窗口的最大高度
}
图片加载类:
package duxuan.zqx.Util; //包名
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
public class GameUtil {
private GameUtil(){} //工具类最好将构造器私有了。
public static Image getImage(String path){
URL u = GameUtil.class.getClassLoader().getResource(path);
BufferedImage bi=null;
try {
bi = javax.imageio.ImageIO.read(u);
} catch (IOException e) {
e.printStackTrace();
}
return bi;
}
}
行星类(Star.java):
这个主要是用于定义中心位置太阳,一切星球都围着太阳转
package duxuan.zqx.Util;
import java.awt.Graphics;
import java.awt.Image;
public class Star {
Image img; //行星的图片
double x,y; //行星的坐标
double width,heigth; //行星图片的高度和宽度
public Star(String path,double x,double y) { //重载构造方法
this.img =GameUtil.getImage(path); //获取图片的路径
this.x = x; //获取行星的x坐标
this.y = y; //获取行星的y坐标
this.width = img.getWidth(null); //获取行星图片的宽度
this.heigth = img.getHeight(null); //获取行星图片的高度
}
Star(){
}
public void draw(Graphics g) { //把行星图片画在窗口显示出来
g.drawImage(img, (int)x, (int)y, null);
}
}
星球类(Planet.java):
继承父类行星类, 在添加一些星球需要的变量,把父类对象也作为该类的成员变量,重写父类的draw方法,增加一些方法去实现画椭圆轨迹以及星球绕着额太阳椭圆运转。
package duxuan.zqx.Util;
import java.awt.Color;
import java.awt.Graphics;
/**
* 星球的定义,围绕着太阳椭圆旋转
* @author ZQX
*
*/
public class Planet extends Star {
double longAxris; //椭圆的长轴
double shortAxris; //椭圆的短轴
double degree; //角度
double speed; //旋转的速度
Star center; //旋转中心,太阳
// double x1,y1;
public Planet(Star center,String path,double longAxris, double shortAxris, double degree, double d) { //重载构造方法
this.center = center;
this.img = GameUtil.getImage(path); //获取图片的路径
// this.x1 = center.x+longAxris;
// this.y1 = center.y;
this.x = center.x+longAxris; //初始化统一星球的x坐标在太阳右边加自身的长轴
this.y = center.y; //初始化统一星球的y坐标是太阳的y坐标
this.degree = degree; //给角度赋值
this.speed = d; //给旋转速度赋值
this.longAxris = longAxris; //给长轴赋值
this.shortAxris = shortAxris; //给短轴赋值
}
public Planet(String path, double x, double y) {
super(path, x, y); //调用父类的构造方法
}
public void draw(Graphics g) { //重写父类的draw方法
// g.drawImage(img, (int)x1, (int)y1, null);
// x1 = center.x+longAxris*Math.cos(degree);
// y1 = center.y+shortAxris*Math.sin(degree);
super.draw(g); //调用父类方法进行行星图片画在窗口显示出来
drawOval(g); //调用画椭圆轨迹的方法
move(); //调用星球绕太阳椭圆运转
}
public void move() { //行星椭圆运转
x = (center.x+center.width/2)+longAxris*Math.cos(degree);
y = (center.y+center.heigth/2)+shortAxris*Math.sin(degree);
degree +=speed;
}
public void drawOval(Graphics g) {
double ovalX,ovalY,ovalWidth,ovalHeight; //定义画椭圆的x,y坐标,以及宽度和高度
ovalX = (center.x+center.width/2) -longAxris; //椭圆的x坐标等于太阳的中心x坐标减去长轴
ovalY = (center.y+center.heigth/2) -shortAxris;//椭圆的y坐标等于太阳的中心y坐标减去短轴
ovalWidth = longAxris*2; //椭圆宽度是长轴的二倍
ovalHeight = shortAxris*2; //椭圆高度是短轴的二倍
Color c = g.getColor(); //获取毛笔的颜色
g.setColor(Color.blue); //把笔的颜色改为蓝色
g.drawOval((int)ovalX, (int)ovalY, (int)ovalWidth, (int)ovalHeight); //画椭圆轨迹
g.setColor(c); //把笔再改回原来毛笔的颜色
}
}
主类(SolarSystem.java):
太阳系的主窗口
package duxuan.zqx.Solar;
import java.awt.Graphics;
import java.awt.Image;
import duxuan.zqx.Util.Constant;
import duxuan.zqx.Util.GameUtil;
import duxuan.zqx.Util.MyFrame;
import duxuan.zqx.Util.Planet;
import duxuan.zqx.Util.Star;
/**
* 太阳系的主窗口
* @author ZQX
*
*/
public class SolarSystem extends MyFrame{
Image img = GameUtil.getImage("images/bg.jpg"); //获取背景图片的路径
Star sun = new Star("images/sun.jpg",Constant.MAX_WIDTH/2,Constant.MAX_HEIGHT/2); //定义太阳的属性
Planet earth = new Planet(sun, "images/Earth.jpg", 150, 80, 3.14/3, 0.17); //定义地球的属性
Planet mercury = new Planet(sun, "images/Mercury.jpg", 100, 50, 3.14/3, 0.2);
Planet venus = new Planet(sun, "images/Venus.jpg", 70, 30, 3.14/3, 0.25);
Planet mars = new Planet(sun, "images/Mars.jpg", 180, 100, 3.14/3, 0.15);
Planet jupiter = new Planet(sun, "images/Jupiter.jpg", 250, 150, 3.14/3, 0.13);
Planet saturn = new Planet(sun, "images/Saturn.jpg", 300, 180, 3.14/3, 0.11);
Planet uranus = new Planet(sun, "images/Uranus.jpg", 350, 210, 3.14/3, 0.09);
// Planet neptune = new Planet(sun, "images/Ueptune.jpg", 400, 240, 3.14/3, 0.08);
public void paint(Graphics g) {
g.drawImage(img, 0, 0, null);
sun.draw(g);
earth.draw(g);
mercury.draw(g);
venus.draw(g);
mars.draw(g);
jupiter.draw(g);
saturn.draw(g);
uranus.draw(g);
// neptune.draw(g); 图片加载异常
}
public static void main(String[] args) {
new SolarSystem().LoadWindow(); //调用MyFram类的LoadWindow()加载窗口。
// Star sun = new Star();
// sun.Star(i, Constant.MAX_WIDTH/2, Constant.MAX_HEIGHT/2);
}
}
文件夹Images:
各种星球的图片包括太阳
运行效果:
下一篇: 用Unity3D实现太阳系仿真