效果图(除了行星运动还有滚动代码特效)
主要思想
solarFengzhuang继承自窗口加载类,lunch是父类加载窗口方法,且父类中还有paint方法,paint方法在此子类中被重写,lunch一旦加载就会显示出窗口,之后会启动线程,线程工作是个循环过程,每隔40毫秒循环一次,每次循环会在窗口调用paint方法,在这个项目中,每个循环会画一次太阳、地球、行星、月亮,而这个画的操作我们把它封装到一个类中,先把太阳封装起来,封装的类有需要加载的太阳图片、位置、以及画的方法,类搞好之后我们创建一个太阳对象,创建时候对其初始化,就是把参数传进去然后由对象调用画的方法,对于地球、行星、月亮由于其位置还与围绕的星位置有关故类应该与太阳不同,继承即可
对于字幕来说,先将字幕读入到字符串string,中然后分割到字符串数组str[]中,在paint方法内每次都输出每一个字符串,只不过字符串位置要随着变量变化而变化
同时还要明确,对于字符串、图片、椭圆来说使用g.drawx画的输入位置都是图片左上角位置,要想画理想位置,应该用x-图片宽度
以下是Java详尽注释代码
1.窗口加载类
package nextpackage;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Random;
/**
* 加载出窗口
*
* @author My_2
*
*/
public class gameFrame extends Frame {
/**
* 加载窗口
*/
public void lunch() {
setSize(Constant.Frame_wide, Constant.Frame_high);// 画布大小,windows类下面方法,继承得到的
setLocation(0, 0);// 画布左上角位置
setVisible(true);// 画布可见
// addWindowListener方法作用是调出来的窗口能×掉
// 调用addWindowListener方法,WindowAdapter属于方法addWindowListener的内部类
// new WindowAdapter()为创建对象,这个对象要重写方法
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
new Painthread().start();// 启动线程
}
// window是Frame的父类,paint是Frame的一个方法
class Painthread extends Thread {//加载窗口時候會啟動線程,一啟動就會調用畫窗口,循環調用paint()
public void run() {
while (true) {
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
2.太阳及行星类
package nextpackage;
import java.awt.Graphics;
import java.awt.Image;
public class Star {
String path=null;
Image Img2;
int x,y;//图片左上角
double wide,heigh;//定义图片高度宽度,因为我们输入坐标是图片左上角坐标,我们需要用图片左上角坐标减去图片宽高一半才是图片真正中心坐标
public Star(String path1,int x1,int y1)
{
this.path=path1;
this.x=x1;
this.y=y1;
Img2 = GameFunc.getImage(path);
this.wide=Img2.getWidth(null);
this.heigh=Img2.getHeight(null);
}
public Star()//不能少,因为后面有继承这个类,子类构造方法只初始化了自己变量,故会默认super()
{
}
public void draw(Graphics g) {
g.drawImage(Img2, (int)(this.x-this.wide/2), (int)(this.y-this.heigh/2), null);// 加载图片,图片,位置,null
}
}
package nextpackage;
import java.awt.Graphics;
/**
* 地球继承太阳的类
* @author admin
*参数:所绕的行星,太阳、长短半轴、速度、参数方程角度
*/
public class enrth extends Star {
Star satr;//所绕的行星
Star center;//太阳位置
double a,b;//长短半轴
double spend,angle;//速度、参数方程角度
public enrth(Star satr,Star center,String path,double a,double b,double spend) {
this.satr=satr;
this.center=center;
this.a=a;
this.b=b;
this.spend=spend;
this.path=path;
Img2 = GameFunc.getImage(this.path);
this.wide=Img2.getWidth(null);//图片有高度宽度
this.heigh=Img2.getHeight(null);
}
// public enrth(String path,int x,int y) {
// super(path,x,y);
// }
// 重写
public void draw(Graphics g) {
// 上层paint()方法会反复调用,每次更新x,y
this.x=(int)(satr.x+a*Math.cos(angle));
// System.out.print(this.x+"\n");
this.y=(int)(satr.y+b*Math.sin(angle));
this.angle=this.angle+this.spend;
// 线
if (this.center == this.satr) {
g.drawLine((int)(this.x),(int)(this.y), satr.x, satr.y);
}
// 画地球
g.drawImage(Img2, (int)(this.x-this.wide/2), (int)(this.y-this.heigh/2), null);
// 椭圆轨迹,月亮绕地球不需要
if (this.center == this.satr) {
g.drawOval((int) (satr.x - a), (int) (satr.y - b), (int) (2 * a),(int) (2 * b));
}
}
}
3.调用类
package nextpackage;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class solarFengzhuang extends gameFrame{
String path=null;
Image Img2;
//字幕每行字幕位置
double string_x[];
double string_y[];
String str[];
/**
* 构造函数,创建对象时候首先调用这个方法
* @param path1
*/
public solarFengzhuang()
{
String string= readString("C:/Users/慧天地/Desktop/Java_bao/data/a/data.txt");
str=string.split("\n");
string_x=new double[str.length];
string_y=new double[str.length];
for(int i=0;i<str.length;i++){
System.out.println(str[i]);
string_x[i]=1000;
string_y[i]=1000+20*i;
}
}
/**
* 读文件中东西至字符串
* @param FILE_IN
* @return
*/
private static String readString(String FILE_IN)
{
String str="";
File file=new File(FILE_IN);
try {
FileInputStream in=new FileInputStream(file);
// size 为字串的长度 ,这里一次性读完
int size=in.available();
byte[] buffer=new byte[size];
in.read(buffer);
in.close();
str=new String(buffer,"GB2312");
} catch (IOException e) {
// TODO Auto-generated catch block
return null;
}
return str;
}
Star star = new Star("Image/sun2.png",500,500);//建立太阳对象
enrth QQ=new enrth(star,star,"Image/mu.png",150,80,0.01);//其他行星对象
enrth earth=new enrth(star,star,"Image/earth.png",400,200,0.02);//地球对象
enrth satellite_360=new enrth(earth,star,"Image/month.png",100,60,0.1);//月亮对象
public void paint(Graphics g) {// 回调
//g.drawImage(Img2, 0, 0, null);// 加载图片同时加载一个窗口,图片,位置,null
Color color=g.getColor();//保存画笔颜色
g.setColor(Color.RED);//将画笔颜色置为红色
// 下面也是一种设颜色方法,应首选下面
// Color c=new Color(255, 0, 0);
// g.setColor(c);
Font font=new Font("黑体",Font.BOLD,50);
g.setFont(font);//setFont方法传入内容决定了要建立对象
g.drawString("银河系", Constant.Frame_wide/2-80, 100);
g.setColor(color);
Font font1=new Font("Courier",Font.LAYOUT_LEFT_TO_RIGHT,15);
g.setFont(font1);//setFont方法传入内容决定了要建立对象
for(int i=0;i<str.length;i++){
// System.out.println(str[i]);
g.drawString(str[i], (int)(string_x[i]), (int)(string_y[i]));
//string_x[i]-=10;
string_y[i]-=7;//7这个值控制了字幕速度
}
star.draw(g);//画太阳
earth.draw(g);//画地球
QQ.draw(g);
satellite_360.draw(g);
}
public static void main(String[] arg) {
// solarFengzhuang继承自窗口加载类,lunch是父类加载窗口方法,且父类中还有paint方法,paint方法在此子类中
// 被重写,lunch一旦加载就会显示出窗口,之后会启动线程,线程工作是个循环过程,每隔40毫秒循环一次,每次循环会在窗口调用
// paint方法,在这个项目中,每个循环会画一次太阳、地球、行星、月亮,而这个画的操作我们把它封装到一个类中,先把太阳封装起
// 来,封装的类有需要加载的太阳图片、位置、以及画的方法,类搞好之后我们创建一个太阳对象,创建时候对其初始化,就是把参数传进去
// 然后由对象调用画的方法,对于地球、行星、月亮由于其位置还与围绕的星位置有关故类应该与太阳不同,继承即可
// 对于字幕来说,先将字幕读入到字符串string,中然后分割到字符串数组str[]中,在paint方法内每次都输出每一个字符串,
// 只不过字符串位置要随着变量变化而变化
// 同时还要明确,对于字符串、图片、椭圆来说使用g.drawx画的输入位置都是图片左上角位置,要想画理想位置,应该用x-图片宽度
solarFengzhuang myFrame2 = new solarFengzhuang();
myFrame2.lunch();
}
}