java太阳系模型
我們知道太陽系有八大行星,圍繞太陽,按照不同的速度轉(zhuǎn)動;月亮圍繞地球轉(zhuǎn)動。星球都有各自的軌道。
我們可以先看實現(xiàn)效果:(真實場景是動態(tài)圖)
可以先照著敲,本項目參考了北京尚學堂高琪老師的教學視頻(感謝尚學堂高琪老師),并加入了一些自己的想法。
? ?注意: ?在Java編寫具有連貫變化的窗口程序時,通常的辦法是在子類中覆蓋父類的paint(Graphics)方法,在方法中使用實現(xiàn)窗口重繪的過程。連貫變換的窗口會不斷地調(diào)用update(Graphics)函數(shù),該函數(shù)自動的調(diào)用paint(Graphics)函數(shù)。這樣就會出現(xiàn)閃爍的情況。為了解決這一問題,可以應用雙緩沖技術??梢酝ㄟ^截取上述過程,覆蓋update(Graphics)函數(shù),在內(nèi)存中創(chuàng)建一個與窗口大小相同的圖形,并獲得該圖形的圖形上下文(Graphics),再將圖片的圖形上下文作為參數(shù)調(diào)用paint(Graphics)函數(shù)(paint(Graphics)中的GUI函數(shù)會在圖片上畫圖),再在update(Graphics)函數(shù)調(diào)用drawImage函數(shù)將創(chuàng)建的圖形直接畫在窗口上。
源碼如下(代碼中有大量注釋):
星球類:
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;// 是否衛(wèi)星/*** * @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* 是否衛(wèi)星*/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* 是否衛(wèi)星*/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);}@Overridepublic 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;/*** 游戲開發(fā)中常用的工具類(比如:加載圖片等方法)* */ 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() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});}private Image offScreenImage = null;/*** 利用雙緩沖技術處理閃爍*/@Overridepublic 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 {@Overridepublic 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,"海王星");@Overridepublic 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();} }
總結(jié)
- 上一篇: 【iOS-iap防护】验证用户付费收据!
- 下一篇: 炉石一键拔网线_炉石传说拔网线插件