建立窗口代码:
/**
* @author coisini1999
* @飞机游戏的主窗口
*/
package cn.coisini.game;
import javax.swing.JFrame; //导入JFrame包
public class MyGameFrame extends JFrame {
public void launchFrame() {
this.setTitle("coisini"); //设置窗口名字
this.setVisible(true); //窗口可视化
this.setSize(500, 500); //设置窗口大小
this.setLocation(400,200); //设置窗口显示位置
}
public static void main(String[] args) { //主方法创建窗口入口
MyGameFrame f = new MyGameFrame(); //由MyGameFrame类新建对象
f.launchFrame(); //调用lanuchFrame()方法
}
}
paint 方法:如果要在窗口中画或者显示什么内容,需要重写paint(Graphics g)方法,这个方法的作用是:画出整个窗口及其内部内容,它会被系统自动调用,不需要自己去调用这个方法
/**
* @author coisini1999
* @飞机游戏的主窗口
*/
package cn.coisini.game;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JFrame; //导入JFrame包
public class MyGameFrame extends JFrame {
public void paint(Graphics g) { //自动被调用,g 相当于一支笔
Color c = g.getColor(); //保存默认的颜色
Font f = g.getFont(); //保存默认的字体
g.setColor(Color.BLUE); //更改颜色
g.drawLine(100, 100, 300, 300); //画线
g.drawRect(100, 100, 300, 300); //画矩形
g.drawOval(100, 100, 300, 300); //画圆
g.fillRect(100, 100, 40, 40); //填充矩形
g.setColor(Color.RED);
g.setFont(new Font("宋体",Font.BOLD,50)); //更改字体
g.drawString("coisini", 200, 200); //画字符串
g.setColor(c); //恢复默认颜色
g.setFont(f); //恢复默认字体
}
public void launchFrame() {
this.setTitle("coisini"); //设置窗口名字
this.setSize(500, 500); //设置窗口大小
this.setLocation(300,300); //设置窗口显示位置
this.setVisible(true); //窗口可视化
}
public static void main(String[] args) { //主方法创建窗口入口
MyGameFrame f = new MyGameFrame(); //由MyGameFrame类新建对象
f.launchFrame(); //调用lanuchFrame()方法
}
}
使用ImageIO类实现图片加载,为了实现代码复用,将图片加载的方法封装到GameUtil的工具类中,便于以后调用
GameUtile类的代码:
package cn.coisini.game;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
public class GameUtil {
//工具类最好将构造器私有化
private GameUtil() {
}
/**
* 返回指定路径文件的图片对象
* @param path
* @return
*/
public static Image getImage(String path) {
BufferedImage bi = null;
try {
URL u = GameUtil.class.getClassLoader().getResource(path);
bi = ImageIO.read(u);
} catch(IOException e) {
e.printStackTrace();
}
return bi;
}
}
先将项目用到的图片拷贝到项目的src下,可以建立新的包images来保存所有的图片
加载图形对象:
/**
* @author coisini1999
* @飞机游戏的主窗口
*/
package cn.coisini.game;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JFrame; //导入JFrame包
public class MyGameFrame extends JFrame {
Image ball = GameUtil.getImage("images/ball.png"); //加载图片对象,指定路径
public void paint(Graphics g) { //自动被调用,g 相当于一支笔
Color c = g.getColor(); //保存默认的颜色
Font f = g.getFont(); //保存默认的字体
g.setColor(Color.BLUE); //更改颜色
g.drawLine(100, 100, 300, 300); //画线
g.drawRect(100, 100, 300, 300); //画矩形
g.drawOval(100, 100, 300, 300); //画圆
g.fillRect(100, 100, 40, 40); //填充矩形
g.setColor(Color.RED);
g.setFont(new Font("宋体",Font.BOLD,50)); //更改字体
g.drawString("coisini", 200, 200); //画字符串
g.drawImage(ball, 250, 250, null); //画出图片
g.setColor(c); //恢复默认颜色
g.setFont(f); //恢复默认字体
}
public void launchFrame() {
this.setTitle("coisini"); //设置窗口名字
this.setSize(500, 500); //设置窗口大小
this.setLocation(300,300); //设置窗口显示位置
this.setVisible(true); //窗口可视化
}
public static void main(String[] args) { //主方法创建窗口入口
MyGameFrame f = new MyGameFrame(); //由MyGameFrame类新建对象
f.launchFrame(); //调用lanuchFrame()方法
}
}
为了实现动态的效果,使用多线程实现动态效果,在MyGameFrame类中定义 重画窗口线程PaintThread类,为了方便使用MyGameFrame类的属性和方法,将PaintThread类定义为内部类
/**
* @author coisini1999
* @飞机游戏的主窗口
*/
package cn.coisini.game;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JFrame; //导入JFrame包
public class MyGameFrame extends JFrame {
Image bg = GameUtil.getImage("images/bg.jpg"); //加载图片对象,指定路径
Image plane = GameUtil.getImage("images/plane.png"); //加载图片对象,指定路径
int planeX = 250, planeY = 250;
public void paint(Graphics g) { //自动被调用,g 相当于一支笔
g.drawImage(bg, 0, 0, null);
g.drawImage(plane, planeX , planeY, null);
x++;
}
//帮助我们反复重画的方法
class PaintThread extends Thread { //内部类,使用此类的所有属性和方法 Thread是线程
@Override
public void run() {
while(true) {
System.out.println("窗口重画了一次");
repaint(); //重画
try {
Thread.sleep(40); //40ms
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void launchFrame() {
this.setTitle("coisini"); //设置窗口名字
this.setSize(500, 500); //设置窗口大小
this.setLocation(300,300); //设置窗口显示位置
this.setVisible(true); //窗口可视化
//实际关闭窗口
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
new PaintThread().start(); //启动重画窗口的线程
}
public static void main(String[] args) { //主方法创建窗口入口
MyGameFrame f = new MyGameFrame(); //由MyGameFrame类新建对象
f.launchFrame(); //调用lanuchFrame()方法
}
}
通过定义变量planeX和planeY可以在每次重画时,x++来改变飞机的位置
对于窗口中的所有对象(飞机,炮弹等等)都有很多共性,图片对象,坐标位置,运行速度,宽度和高度,为了方便使用,需要设计一个GameObject类,它可以作为所有游戏物体的父类,方便我们使用
GameObject类:
package cn.coisini.game;
import java.awt.Graphics;
import java.awt.Image;
/**
* 游戏物体的父类
* @author coisini1999
*
*/
public class GameObject {
//游戏物体的属性
Image img;
double x,y;
int speed;
int width,height;
//画出自己的方法
public void drawSelf(Graphics g) {
g.drawImage(img, (int)x, (int)y, null);
}
//构造器1
public GameObject(Image img, double x, double y, int speed, int width, int height) {
super();
this.img = img;
this.x = x;
this.y = y;
this.speed = speed;
this.width = width;
this.height = height;
}
//构造器2
public GameObject(Image img, double x, double y) {
super();
this.img = img;
this.x = x;
this.y = y;
}
//无参构造
public GameObject() {
}
}
通过GameObject类,可以再构建新的Plane类:
package cn.coisini.game;
import java.awt.Graphics;
import java.awt.Image;
public class Plane extends GameObject {
public void drawSelf(Graphics g) {
g.drawImage(img, (int)x, (int)y, null);
x++;
}
public Plane(Image img, double x, double y) {
this.img = img;
this.x = x;
this.y = y;
}
}
这样Plane类就继承了GameObject类的所有属性和方法,在MyGameFrame类中就可以直接new若干个plane直接使用
/**
* @author coisini1999
* @飞机游戏的主窗口
*/
package cn.coisini.game;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JFrame; //导入JFrame包
public class MyGameFrame extends JFrame {
Image bg = GameUtil.getImage("images/bg.jpg"); //加载图片对象,指定路径
Image planeImg = GameUtil.getImage("images/plane.png"); //加载图片对象,指定路径
Plane plane = new Plane(planeImg, 250 ,250); //创建飞机对象
Plane plane2 = new Plane(planeImg, 350 ,250); //创建飞机对象
Plane plane3 = new Plane(planeImg, 450 ,250); //创建飞机对象
public void paint(Graphics g) { //自动被调用,g 相当于一支笔
g.drawImage(bg, 0, 0, null);
plane.drawSelf(g); //画飞机
plane2.drawSelf(g); //画飞机
plane3.drawSelf(g); //画飞机
}
//帮助我们反复重画方法
class PaintThread extends Thread { //内部类,使用此类的所有属性和方法 Thread是线程
@Override
public void run() {
while(true) {
System.out.println("窗口重画了一次");
repaint(); //重画
try {
Thread.sleep(40); //40ms
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void launchFrame() {
this.setTitle("coisini"); //设置窗口名字
this.setSize(500, 500); //设置窗口大小
this.setLocation(300,300); //设置窗口显示位置
this.setVisible(true); //窗口可视化
//实际关闭窗口
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
new PaintThread().start(); //启动重画窗口的线程
}
public static void main(String[] args) { //主方法创建窗口入口
MyGameFrame f = new MyGameFrame(); //由MyGameFrame类新建对象
f.launchFrame(); //调用lanuchFrame()方法
}
}