利用小項目加深面向對象的思想---2.太陽系軌跡圖

1.創建包和圖片管理

2.cn.bjsxt.util包裏面是檯球反彈代碼(可看昨天發的小項目)

Constant.java

package cn.bjsxt.util;

/**
 * 遊戲項目中用到的常量
 * @author dell
 *
 */
public class Constant {
	public static final int GAME_WIDTH = 900;
	public static final int GAME_HEIGHT =700;
	
}

GameUtil.java

package cn.bjsxt.util;

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

import javax.imageio.ImageIO;

/**
 * 遊戲開發的工具類(加載圖片)
 * @author Administrator
 *
 */

public class GameUtil {
	public static Image getImage(String  path){
		URL u=GameUtil.class.getClassLoader().getResource(path);
		BufferedImage img=null;
		try {
			img=ImageIO.read(u);
		}catch (IOException e) {
			e.printStackTrace();
		}
		return img;
	}
	
}

MyFrame.java

package cn.bjsxt.util;
import java.awt.Frame;
import java.awt.Image;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class MyFrame extends Frame {
	/**
	 * 加載窗口
	 */
	public void launchFrame(){
		 setTitle("太陽系運行軌跡圖");
		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);
			}
			
		});
	}
class PaintThread extends Thread {
		
		public void run(){
			while(true){
				repaint();
				try {
					Thread.sleep(100); //1s = 1000ms
				} catch (InterruptedException e) {
					e.printStackTrace();
				}   
			}
		}
		
	}
}

此包下的三個方法,主要是構建界面,加載圖片和增加線程使其有動畫效果。

3.cn.bjsxt.solar包下

  Star.java

package cn.bjsxt.solar;

import java.awt.Graphics;
import java.awt.Image;
import cn.bjsxt.util.GameUtil;
public class Star {
	Image img;
	double x,y;
	int width,height;
	
	public void draw(Graphics g) {
		g.drawImage(img, (int)x,(int)y,null);
	}
	public Star(Image img){
		this.img=img;
		this.width=img.getWidth(null);
		this.height=img.getHeight(null);
		
	}
	public Star() {
		
	}
	public Star(Image img,double x,double y){
		this(img);
		this.x = x;
		this.y = y;
		
		
	}
  public Star(String imgpath,double x,double y) {
	    this(GameUtil.getImage(imgpath),x,y);
  }
}

此代碼定義幾個構造方法,重載SolarFrame.java中只有一處調用此代碼

Star sun=new Star("images/sun.jpg",Constant.GAME_WIDTH/2,Constant.GAME_HEIGHT/2);

定義一個不動的太陽,傳入參數後,通過此來調用別的構造方法,後sun.draw(g),調用g.drawImage(img,(int)x,(int)y,null);來繪製太陽圖像。

 

Planet.java

package cn.bjsxt.solar;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import cn.bjsxt.util.GameUtil;

public class Planet extends Star{	
	//除了圖片,行星沿着某個橢圓運行:長軸、短軸、速度、角度。 繞着某個Star飛。
	double longAxis;    //橢圓的長軸
	double shortAxis;   //橢圓的短軸
	double speed;       //飛行的速度
	double degree;     //角度
	Star center;
	boolean satellite;  //是否畫線,主要還是月亮運作沒有畫線
	
	public void draw(Graphics g) {
		super.draw(g);
		move();
		if(!satellite) {    //判讀是否畫橢圓線,主要是月亮沒畫
			drawTrace(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-img.getWidth(null)/2+longAxis*Math.cos(degree);
	     y=center.y+center.height/2-img.getHeight(null)/2+shortAxis*Math.sin(degree);
			degree+=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;
		this.width=img.getWidth(null);
		this.height=img.getHeight(null);
		
	}
	
	public Planet(Star center,String imgpath, double longAxis,
			double shortAxis, double speed,boolean satellite) {
	  this(center, imgpath, longAxis, shortAxis, speed);
	  this.satellite=satellite;
	}
	
	public Planet(Image img, double x, double y) {
		super(img, x, y);
	}
	public Planet(String imgpath, double x, double y) {
		super(imgpath, x, y);		
	}

}

此代碼,繼承Star.java,Star.java,主要還是繪製太陽,是靜態的,我們通過繼承Star.java來實現行星橢圓動態旋轉

drawTrace(Graphics g)繪畫橢圓線

移動(),繪製行星移動

SolarFrame.java

package cn.bjsxt.solar;

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

import cn.bjsxt.util.Constant;
import cn.bjsxt.util.GameUtil;
import cn.bjsxt.util.MyFrame;

public class SolarFrame extends MyFrame{
    private Image iBuffer;
	private Graphics gBuffer;
	Image bg=GameUtil.getImage("images/bg.jpg");
	//Star bg=new Star("images/bg.jpg",0,0);
	Star sun=new Star("images/sun.jpg",Constant.GAME_WIDTH/2,Constant.GAME_HEIGHT/2);
	
	  Planet mercury=new Planet(sun,"images/Mercury.jpg", 80,50,0.08);
	  Planet venus=new Planet(sun,"images/Venus.jpg", 110,70,0.07);
	  Planet earch=new Planet(sun,"images/earth.jpg", 145,95,0.06);
	  Planet moon=new Planet(earch,"images/moon.jpg", 20,15,0.5,true);
	  Planet mars=new Planet(sun,"images/Mars.jpg", 185,125,0.05);
	  Planet jupier=new Planet(sun,"images/Jupiter.jpg",230,160,0.04);
	  Planet saturn=new Planet(sun,"images/Saturn.jpg", 280,200,0.03);
	  Planet uranus=new Planet(sun,"images/Uranus.jpg", 335,245,0.02);
	  Planet neptune=new Planet(sun,"images/Neptune.jpg",395,295,0.01);
	
	
	  
	
	  public void paint(Graphics g) {
		g.drawImage(bg, 0, 0, null);
		 //bg.draw(g);
		  sun.draw(g);
		  mercury.draw(g);
		  venus.draw(g);
		  earch.draw(g);
		  moon.draw(g);
		  mars.draw(g);
		  jupier.draw(g);
		  saturn.draw(g);
		  uranus.draw(g);
		  neptune.draw(g);
	  }
	    public void update(Graphics scr)
		{
		    if(iBuffer==null)
		    {
		       iBuffer=createImage(this.getSize().width,this.getSize().height);
		       gBuffer=iBuffer.getGraphics();
		    }
		       gBuffer.setColor(getBackground());
		       gBuffer.fillRect(0,0,this.getSize().width,this.getSize().height);
		       paint(gBuffer);
		       scr.drawImage(iBuffer,0,0,this);
		}
	  public static void main(String[] args) {
		new SolarFrame().launchFrame();
	}
}

此代碼爲調用   

注意:  在Java編寫具有連貫變化的窗口程序時,通常的辦法是在子類中覆蓋父類的paint(Graphics)方法,在方法中使用實現窗口重繪的過程。連貫變換的窗口會不斷地調用update(Graphics)函數,該函數自動的調用paint(Graphics)函數。這樣就會出現閃爍的情況。爲了解決這一問題,可以應用雙緩衝技術。可以通過截取上述過程,覆蓋update(Graphics)函數,在內存中創建一個與窗口大小相同的圖形,並獲得該圖形的圖形上下文(Graphics),再將圖片的圖形上下文作爲參數調用paint(Graphics)函數(paint(Graphics)中的GUI函數會在圖片上畫圖),再在update(Graphics)函數調用drawImage函數將創建的圖形直接畫在窗口上。
 

 

總結:此小項目很簡單,裏面用到重載,這個調用和繼承關係,其實這些東西很容易理解,但寫項目就不知道怎麼構架,非常適合新手,而現在我也是新手,好長時間沒學的java了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章