使用Java怎么模擬行星運(yùn)動(dòng)?相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。
創(chuàng)新互聯(lián)建站專注于中大型企業(yè)的做網(wǎng)站、成都做網(wǎng)站和網(wǎng)站改版、網(wǎng)站營銷服務(wù),追求商業(yè)策劃與數(shù)據(jù)分析、創(chuàng)意藝術(shù)與技術(shù)開發(fā)的融合,累計(jì)客戶千余家,服務(wù)滿意度達(dá)97%。幫助廣大客戶順利對(duì)接上互聯(lián)網(wǎng)浪潮,準(zhǔn)確優(yōu)選出符合自己需要的互聯(lián)網(wǎng)運(yùn)用,我們將一直專注品牌網(wǎng)站建設(shè)和互聯(lián)網(wǎng)程序開發(fā),在前進(jìn)的路上,與客戶一起成長(zhǎng)!
一、類的設(shè)計(jì):
Star繼承自JPanel。Star類是行星的基類,所有運(yùn)動(dòng)的行星都是繼承自Star類。內(nèi)部draw()方法主要繪制了一個(gè)實(shí)心圓形,目的是在每次繪制時(shí),可以保證中心行星始終顯示。paintComponent()方法重寫了JPanel的繪制方法,目的是保證繼承自Star類的Stars類的實(shí)例對(duì)象可以繪制出自己的行星。如下:
package Star; import java.awt.Color; import java.awt.Graphics; import javax.swing.JPanel; public class Star extends JPanel{ /** * 基本的行星類 */ private static final long serialVersionUID = 1L; int x,y; int width,height; public Star() { width = 10; height = 10; } public Star(int x, int y){ this.x = x; this.y = y; width = 10; height = 10; } public void draw(Graphics g){ g.setColor(Color.blue); g.fillOval(x, y, width, height); } protected void paintComponent(Graphics g){ super.paintComponent(g); g.fillOval(x, y, width, height); } }
Stars類繼承自Star類,是對(duì)Star類的進(jìn)一步細(xì)化,表示運(yùn)動(dòng)的行星。Stars類中的alfa表示運(yùn)動(dòng)行星的運(yùn)動(dòng)起始角度,speed表示運(yùn)動(dòng)速度,可對(duì)其進(jìn)行修改。Long,Short分別表示橢圓軌跡的長(zhǎng)軸與短軸。center表示其實(shí)例化對(duì)象的中心行星。paintComponent()函數(shù)重寫了paintComponent(),內(nèi)部引用了父類的draw()函數(shù),并且根據(jù)Long,,Short繪制了橢圓軌道,Long、Short由實(shí)例化對(duì)象調(diào)用構(gòu)造方法來決定。move()函數(shù)描述了x,y的變化方程,即圍繞著橢圓軌道變化,同時(shí)規(guī)定了alfa的變化方式。start()函數(shù)表示線程開始,pause()函數(shù)表示線程暫停,accelerate()函數(shù)表示對(duì)行星的加速操作,decelerate()函數(shù)表示對(duì)行星減速的操作。
Pthread類目的是控制線程,即通過對(duì)Pthread類的實(shí)例化可以控制行星的開始運(yùn)動(dòng),暫停運(yùn)動(dòng),加速,減速。Pthread類繼承自Thread類,且包含于Starts類中,因而,PThread類不能被定義為共有類。PThread類提供了run()方法,不斷調(diào)用repaint()方法,對(duì)畫面進(jìn)行重新繪制。setsuspend()方法利用改變boolean變量對(duì)線程進(jìn)行暫停操作(調(diào)用notifyall()方法)。因?yàn)镻thread類是Starts的內(nèi)部類,所以之后Starts類中將生成一個(gè)PThread類的對(duì)象,并且利用該對(duì)象,對(duì)線程進(jìn)行操作。
設(shè)計(jì)如下:
package Star; import java.awt.Color; import java.awt.Graphics; public class Stars extends Star{ /** * 運(yùn)動(dòng)的行星 */ private static final long serialVersionUID = 1L; double alfa ; double speed ; Star center; int Long ; //長(zhǎng)軸 int Short;//短軸 public Stars(int Px,int Py,Star center){ super(Px,Py); this.center = center; Long = (Px - center.x)*2; Short = (Py - center.y)*2; this.setOpaque(true); // move(); alfa = 0; speed = 0.001; } protected void paintComponent(Graphics g){ super.paintComponent(g); center.draw(g);//畫出中心點(diǎn) move(); g.setColor(Color.GREEN); g.drawOval(center.x-Long/2, center.y-Short/2, Long, Short); } public void move(){ x = center.x + (int)(Long/2*Math.cos(alfa)); y = center.y + (int)(Short/2*Math.sin(alfa)); //沿橢圓軌跡運(yùn)行 alfa += speed; //角度不斷變化 } class PThread extends Thread{ //重畫線程類 private boolean suspend = true; private String control = ""; public void run(){ while(true){ synchronized (control) { if(suspend){ //move(); repaint(); } } } } public void setsuspend(boolean s){ //設(shè)置線程暫停方法 if (!suspend) { synchronized (control) { control.notifyAll(); } } this.suspend = s; } } public PThread pt = new PThread(); public void start(){ pt.setsuspend(true); pt.start(); } public void pause(){ pt.setsuspend(false); } public void accelerate(){ //加速的方法 if(speed > 0){ //角度每次加速0.0002 speed += 0.0002; } else speed = 0.001; } public void decelerate(){ //減速的方法 if(speed > 0){ speed -= 0.0002; //角度每次減速0.0002 } //若減速到0,則不能繼續(xù)減速,另速度為0,停止運(yùn)動(dòng) else speed = 0; } }
StarFrame類是本程序的啟動(dòng)面板,通過實(shí)例化該類,生成主程序界面,并且將行星部件,按鈕,標(biāo)簽添加進(jìn)面板。內(nèi)部的getPanel()方法對(duì)兩個(gè)按鈕進(jìn)行了設(shè)置,并且返回一個(gè)JPanel(將四個(gè)按鈕添加進(jìn)該JPanel中)。getLabel()方法返回一個(gè)文字描述的JLabel。Center對(duì)象是Star類的實(shí)例化,p1是Stars類的實(shí)例化,分別表示中心行星與環(huán)繞行星。jb1,jb2,jb3,jb4分別是行星的啟動(dòng),暫停,加速,減速的控制按鈕。image表示界面背景圖,LayeredPanel是界面的層次面板,方便背景圖的設(shè)置。jp,jl是設(shè)置背景圖的部件。設(shè)計(jì)如下:
package Star; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JLayeredPane; import javax.swing.JPanel; public class StarFrame extends JFrame{ /** *行星模擬啟動(dòng)面板 */ private static final long serialVersionUID = 1L; Star center = new Star(300,200);//定義中心行星 Stars p1 = new Stars(300+230,200+130,center);//環(huán)繞中心的行星 Stars p2 = new Stars(300+230+20,200+130+20,p1); JButton jb1 = new JButton("start"); JButton jb2 = new JButton("pause"); JButton jb3 = new JButton("accelerate"); JButton jb4 = new JButton("decelerate"); ImageIcon image=new ImageIcon("timg.jpg");//背景圖,利用相對(duì)路徑定義 JLayeredPane layeredPane; //定義一個(gè)層次面板,用于放置背景圖片 JPanel jp; JLabel jl; public StarFrame(){ //為p1設(shè)置位置,與大小 p1.setBounds(40,40,600,400); // p2.setBounds(40,40,600,400); //定義背景圖,將背景圖放于JLabel中,將JLabel放于JPanel中 layeredPane = new JLayeredPane(); jp = new JPanel(); jp.setBounds(0,0,image.getIconWidth(),image.getIconHeight()); jl=new JLabel(image); jp.add(jl); //將jp放到最底層。 layeredPane.add(jp,JLayeredPane.DEFAULT_LAYER); //將jb放到高一層的地方 layeredPane.add(p1,JLayeredPane.MODAL_LAYER); // layeredPane.add(p2,JLayeredPane.MODAL_LAYER); layeredPane.add(getPanel(),JLayeredPane.MODAL_LAYER); layeredPane.add(getLabel(),JLayeredPane.MODAL_LAYER); //分別為jb1、jb2、jb3、jb4設(shè)置相關(guān)動(dòng)作 jb1.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub p1.start(); } } ); jb2.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub p1.pause(); } }); jb3.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub p1.accelerate(); } }); jb4.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub p1.decelerate(); } }); this.setLayeredPane(layeredPane); this.setTitle("Star"); this.setBounds(100,100,1000, 600); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } private JPanel getPanel(){ //返回定義的四個(gè)按鈕 JPanel jp = new JPanel(); jp.add(jb1); jp.add(jb2); jp.add(jb3); jp.add(jb4); jp.setBounds(750,450,200,70); return jp; } private JPanel getLabel(){ //返回文字描述 JLabel jl = new JLabel("行星模擬"); jl.setForeground(Color.RED);//設(shè)置字體顏色 jl.setFont(new Font("Dialog",0,20));//設(shè)置字體 JPanel jp = new JPanel(); jp.add(jl,BorderLayout.CENTER); jp.setBounds(800,0,150,40); return jp; } public static void main(String[] args) { @SuppressWarnings("unused") StarFrame f = new StarFrame(); } }
運(yùn)行效果:
二、對(duì)象:
因?yàn)閖ava是面向?qū)ο蟮恼Z言,當(dāng)然不能像c語言一樣,僅僅靠函數(shù)實(shí)現(xiàn),課設(shè)里豈能沒有對(duì)象?
主要對(duì)象:
對(duì)象center,即中心行星
對(duì)象p1,即環(huán)繞行星
對(duì)象pt,即負(fù)責(zé)控制線程的對(duì)象
對(duì)象f,即程序啟動(dòng)面板
三、對(duì)象之間的關(guān)系(交互)
p1與center的關(guān)系:Star類是行星的基類,繼承自JPanel,其內(nèi)部定義了基本的半徑與坐標(biāo),其實(shí)例化對(duì)象center即是運(yùn)動(dòng)行星的中心行星。而繼承自Star的Stars類表示運(yùn)動(dòng)行星,是其進(jìn)一步的細(xì)化,因此其實(shí)例化對(duì)象p1表示運(yùn)動(dòng)的行星1,且圍繞著center運(yùn)動(dòng),同時(shí)center作為參數(shù)傳遞給p1的構(gòu)造方法,完成二者交互。對(duì)象p1與center便是這樣的關(guān)系。實(shí)例化對(duì)象center后,便會(huì)在指定坐標(biāo)下繪制實(shí)心圓形,center對(duì)象的x,y坐標(biāo)不會(huì)變化。而對(duì)象p1在實(shí)現(xiàn)繪制實(shí)心圓形的基礎(chǔ)上,又根據(jù)center的坐標(biāo)繪制了指定長(zhǎng)軸,短軸的橢圓軌道,同時(shí)其內(nèi)部實(shí)現(xiàn)了Thread類,不中斷的執(zhí)行線程。相互的繼承關(guān)系,使得center和p1可以互不干擾的繪制圖形,值得一提的是,在Stras類中的paintComponent()方法中,仍需要調(diào)用center對(duì)象的draw()方法,因?yàn)榫€程開始時(shí)會(huì)調(diào)用repaint()方法,如果不實(shí)現(xiàn)center的draw()方法,那么最終結(jié)果將不會(huì)顯示中心行星。
pt與p1的關(guān)系:PThread類繼承自Thread類,定義了run()方法,通過其實(shí)例化對(duì)象p1,可以調(diào)用start()方法啟動(dòng)線程,而PThread類在Starts類內(nèi)部,因而通過p1內(nèi)的方法可以控制線程,即控制其速度,加速減速,控制其運(yùn)行與否。
f與各對(duì)象的關(guān)系:StarFrame繼承自JFrame,其實(shí)例化對(duì)象f將各對(duì)象添加進(jìn)繪畫布里,制作了界面,并控制了每個(gè)部件的大小、位置,是程序運(yùn)行的關(guān)鍵。
看完上述內(nèi)容,你們掌握使用Java怎么模擬行星運(yùn)動(dòng)的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!