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了。