最近闲来无事,花了一天多的时间写了一个小游戏,虽然说游戏本身很无聊吧,但是自己也从这个过程中学到了许多东西。。。分享一下。
代码内容自行理解吧。。。
层次结构:


1 package cn.sxt.game;
2
3 import java.awt.Color;
4 import java.awt.Font;
5 import java.awt.Frame;
6 import java.awt.Graphics;
7 import java.awt.Image;
8 import java.awt.event.KeyAdapter;
9 import java.awt.event.KeyEvent;
10 import java.awt.event.WindowAdapter;
11 import java.awt.event.WindowEvent;
12 import java.util.Date;
13
14 import javax.swing.JFrame;
15
16 /*
17 * 飞机游戏的主窗口
18 * @author Brave_WTZ
19 */
20 public class MyGameFrame extends Frame{
21
22 Image bgImg = GameUtil.getImage("images/bg.jpg");
23 Image planeImg = GameUtil.getImage("images/plane.png");
24
25 Plane plane = new Plane(planeImg,250,250);
26 Shell[] shells = new Shell[20];//声明50个炮弹
27
28 Explode bao;
29
30 Date startTime = new Date();
31 Date endTime;
32 int period;//游戏持续的时间
33
34 @Override
35 public void paint(Graphics g) {//自动被调用
36 Color c = g.getColor();
37
38 g.drawImage(bgImg,0,0,null);
39
40 plane.drawSelf(g);//画飞机
41
42 /*画出所有的炮弹*/
43 for( int i=0; i<shells.length; i++ ) {
44 shells[i].draw(g);//画炮弹
45
46 /*飞机和炮弹的碰撞检测!!!*/
47 boolean peng = shells[i].getRect().intersects(plane.getRect());
48 if(peng) {
49 plane.live = false;
50 if(bao==null) {
51 bao = new Explode(plane.x,plane.y);
52
53 endTime = new Date();
54 period = (int)((endTime.getTime()-startTime.getTime())/1000);
55 }
56 bao.draw(g);
57 }
58 if(!plane.live) {
59 g.setColor(Color.white);
60 Font f = new Font("宋体",Font.BOLD,50);
61 g.setFont(f);
62 g.drawString("时间:"+period+"秒", (int)plane.x, (int)plane.y);
63 }
64 }
65
66 g.setColor(c);
67 }
68
69 /*定义内部类,方便实用外部类的属性*/
70 class PaintThread extends Thread{
71 @Override
72 public void run() {
73 while(true) {//帮助我们反复重画窗口
74 repaint();//重画
75
76 try {
77 Thread.sleep(40);/*动态视觉效果是由一帧帧照片连续而成*/
78 } catch (InterruptedException e) {
79 // TODO Auto-generated catch block
80 e.printStackTrace();
81 }
82 }
83 }
84 }
85
86 /*
87 * 定义键盘监听的内部类
88 */
89 class KeyMonitor extends KeyAdapter{
90 @Override
91 public void keyPressed(KeyEvent e) {
92 plane.addDirection(e);
93 }
94 @Override
95 public void keyReleased(KeyEvent e) {
96 plane.minusDirection(e);
97 }
98 }
99
100 /*
101 * 初始化窗口
102 */
103 public void launchFrame() {
104 this.setTitle("Brave_WZT");
105 this.setVisible(true);
106 this.setSize(Constant.GAME_WIDTH,Constant.GAME_HEIGHT);
107 this.setLocation(300,300);
108 //正常情况下推出虚拟机操作
109 this.addWindowListener(new WindowAdapter(){
110 public void windowClosing(WindowEvent e) {
111 System.exit(0);
112 }
113 });
114
115 new PaintThread().start();//启动线程
116 addKeyListener(new KeyMonitor());//启动键盘监听
117
118 //初始化50个炮弹
119 for( int i=0; i<shells.length; i++ ) {
120 shells[i] = new Shell();
121 }
122 }
123
124 /*
125 * 双缓冲技术,解决Frame中画面闪烁问题
126 */
127 private Image offScreenImage = null;
128
129 public void update(Graphics g) {
130 if(offScreenImage == null)
131 offScreenImage = this.createImage(Constant.GAME_WIDTH,Constant.GAME_HEIGHT);//这是游戏窗口的宽度和高度
132
133 Graphics gOff = offScreenImage.getGraphics();
134 paint(gOff);
135 g.drawImage(offScreenImage, 0, 0, null);
136 }
137
138
139 public static void main(String[] args) {
140 MyGameFrame f = new MyGameFrame();
141 f.launchFrame();
142
143 }
144 }


1 package cn.sxt.game;
2
3 import java.awt.Graphics;
4 import java.awt.Image;
5 import java.awt.event.KeyEvent;
6
7 /*
8 * 飞机类
9 * @author Brave_WTZ
10 */
11
12 public class Plane extends GameObject{
13
14 boolean left,up,right,down;
15
16 boolean live = true;
17
18 public Plane(Image img,double x,double y) {
19 this.img=img;
20 this.x=x;
21 this.y=y;
22 this.speed=6;
23 this.width=100;
24 this.height=100;
25 }
26
27 public void drawSelf(Graphics g) {
28 if(live) {
29 g.drawImage(img,(int)x,(int)y,null);
30 if(left) {
31 x-=speed;
32 }
33 if(right) {
34 x+=speed;
35 }
36 if(up) {
37 y-=speed;
38 }
39 if(down) {
40 y+=speed;
41 }
42 }else {
43
44 }
45 }
46
47
48 //按下某个键,启动这个方向
49 public void addDirection(KeyEvent e) {
50 switch(e.getKeyCode()) {
51 case KeyEvent.VK_LEFT:
52 left=true;
53 break;
54 case KeyEvent.VK_UP:
55 up=true;
56 break;
57 case KeyEvent.VK_RIGHT:
58 right=true;
59 break;
60 case KeyEvent.VK_DOWN:
61 down=true;
62 break;
63 }
64 }
65 //松开某个键,取消相应的方向
66 public void minusDirection(KeyEvent e) {
67 switch(e.getKeyCode()) {
68 case KeyEvent.VK_LEFT:
69 left=false;break;
70 case KeyEvent.VK_UP:
71 up=false;break;
72 case KeyEvent.VK_RIGHT:
73 right=false;break;
74 case KeyEvent.VK_DOWN:
75 down=false;break;
76 }
77 }
78 }


1 package cn.sxt.game;
2
3 import java.awt.Color;
4 import java.awt.Graphics;
5
6 /*
7 * 炮弹类
8 * @author Brave_WTZ
9 */
10
11 public class Shell extends GameObject{
12
13 double degree;
14 public Shell(){
15 x=200;
16 y=200;
17 width=7;
18 height=7;
19 speed=3;
20
21 degree=Math.random()*Math.PI*2;//定义炮弹类方向
22 }
23
24 public void draw(Graphics g) {
25 Color c = g.getColor();//tip:预先将原Graphics颜色加以保留
26 g.setColor(Color.pink);
27
28 g.fillOval((int)x,(int)y, width, height);/*填充pink色炮弹*/
29
30 /*炮弹沿任意角度去飞*/
31 x+=speed*Math.cos(degree);
32 y+=speed*Math.sin(degree);
33
34 if(x<0||x>Constant.GAME_WIDTH-width) {
35 degree = Math.PI-degree;
36 // System.out.println("嘤嘤嘤");
37 }
38 if(y<30||y>Constant.GAME_HEIGHT-height) {
39 degree = -degree;
40 // System.out.println("嘤嘤嘤");
41 }
42
43 g.setColor(c);
44 }
45 }


1 package cn.sxt.game;
2
3 import java.awt.Graphics;
4 import java.awt.Image;
5
6 /*
7 * 爆炸类
8 * @author Brave_WTZ
9 */
10 public class Explode {
11 double x,y;
12
13 static Image[] imgs = new Image[16];
14 static {
15 for( int i=0; i<16; i++ ) {
16 imgs[i] = GameUtil.getImage("images/explode/e"+(i+1)+".gif");
17 imgs[i].getWidth(null);
18 }
19 }
20
21 int count;
22
23 public void draw(Graphics g) {
24 if(count<=15) {
25 g.drawImage(imgs[count], (int)x, (int)y, null);
26 count++;
27 }
28 }
29 public Explode(double x,double y) {
30 this.x=x;
31 this.y=y;
32 }
33 }


1 package cn.sxt.game;
2
3 import java.awt.Graphics;
4 import java.awt.Image;
5 import java.awt.Rectangle;
6
7 /*
8 * 游戏物体的父类
9 * @author Brave_WTZ
10 */
11 public class GameObject {
12 Image img;
13 double x,y;
14 int speed;
15 int width,height;
16
17 public void drawSelf(Graphics g) {
18 g.drawImage(img,(int)x,(int)y,null);
19 }
20
21 public GameObject(Image img, double x, double y, int speed, int width, int height) {
22 super();
23 this.img = img;
24 this.x = x;
25 this.y = y;
26 this.speed = speed;
27 this.width = width;
28 this.height = height;
29 }
30
31 public GameObject(double x, double y) {
32 super();
33 this.x = x;
34 this.y = y;
35 }
36
37 public GameObject() {
38
39 }
40 /*
41 * 返回物体所在矩形,便于碰撞检测
42 */
43 public Rectangle getRect() {
44 return new Rectangle((int)x,(int)y,width,height);
45 }
46
47 }


1 package cn.sxt.game;
2
3 import java.awt.Image;
4 import java.awt.image.BufferedImage;
5 import java.io.IOException;
6 import java.net.URL;
7 import javax.imageio.ImageIO;
8
9 public class GameUtil {
10 // 工具类最好将构造器私有化。
11 private GameUtil() {
12
13 }
14 /*
15 * 返回指定路径文件的图片对象
16 *
17 */
18 public static Image getImage(String path) {
19 BufferedImage bi = null;
20 try {
21 URL u = GameUtil.class.getClassLoader().getResource(path);
22 bi = ImageIO.read(u);
23 } catch (IOException e) {
24 e.printStackTrace();
25 }
26 return bi;
27 }
28 }


1 package cn.sxt.game;
2
3 public class Constant {
4
5 public static final int GAME_WIDTH = 1024;
6 public static final int GAME_HEIGHT = 700;
7 }
看看效果图:
下面是游戏代码用到的游戏素材:
来源:oschina
链接:https://my.oschina.net/u/4258874/blog/3656088