"飞机大战"游戏_Java

"飞机大战"游戏_Java

 1 package cn.xiaocangtian.Util;
 2 
 3 import java.awt.Frame;
 4 import java.awt.Graphics;
 5 import java.awt.Image;
 6 import java.awt.event.WindowAdapter;
 7 import java.awt.event.WindowEvent;
 8 
 9 
10 public class MyFrame extends Frame {
11 
12         //加载窗口
13         public void launchFrame() {
14             setSize(Constant.GAME_WIDTH, Constant.GAME_HEIGHT);       //设置窗口大小
15             setLocation(100, 100);   //设置左上角坐标,开始位置, 也就是窗口开始位置
16             setVisible(true);        //设置为可见(默认为不可见)
17             
18             //启动重画线程
19             new PaintThread().start();
20             
21             //匿名内部类---用来关闭窗口
22             addWindowListener(new WindowAdapter() {
23                 @Override
24                 public void windowClosing(WindowEvent e) {
25                     System.exit(0);
26                 }
27             });
28             
29         }
30         
31         //双缓冲技术解决屏幕闪烁
32         private Image offScreenImage = null;   //利用双缓冲技术消除闪烁
33         public void update(Graphics g) {
34             if (offScreenImage == null)
35                 offScreenImage = this.createImage(Constant.GAME_WIDTH, Constant.GAME_HEIGHT);
36             
37             Graphics gOff = offScreenImage.getGraphics();
38             
39             paint(gOff);
40             g.drawImage(offScreenImage, 0, 0, null);
41         }
42         
43         /**
44          * 定义一个重画窗口的线程类
45          * 是一个内部类(方便访问外部类属性)
46          */
47         class PaintThread extends Thread {
48             public void run() {
49                 while (true) {
50                     repaint();             //重画
51                     try {
52                         Thread.sleep(40);  //1s = 1000ms
53                     } catch (InterruptedException e) {
54                         e.printStackTrace();
55                     }  
56                 }
57             }
58         }
59         
60 }
 1 package cn.xiaocangtian.Util;
 2 
 3 import java.awt.Image;
 4 import java.awt.Toolkit;
 5 import java.awt.image.BufferedImage;
 6 import java.io.IOException;
 7 import java.net.URL;
 8 
 9 import javax.imageio.ImageIO;
10 import javax.swing.ImageIcon;
11 
12 /**
13  * 游戏开发中常用的工具类(比如:加载图片等方法)
14  * @author admin
15  *
16  */
17 public class GameUtil {
18     
19     private GameUtil () {} //工具类通常将构造方法私有
20     
21     public static Image getImage(String path) {
22 //        return Toolkit.getDefaultToolkit().getImage(GameUtil.class.getClassLoader().getResource(path));
23         BufferedImage bi = null;
24         try {
25             URL u = GameUtil.class.getClassLoader().getResource(path);
26             bi = javax.imageio.ImageIO.read(u);
27         } catch (IOException e) {
28             // TODO Auto-generated catch block
29             e.printStackTrace();
30         }
31         return bi;
32     }
33 }
 1 package cn.xiaocangtian.Util;
 2 
 3 /**
 4  * 游戏项目中用到的常量
 5  * 单独负责常量
 6  * @author admin
 7  */
 8 public class Constant {
 9     
10     public static final int GAME_WIDTH = 350;
11     public static final int GAME_HEIGHT = 600;
12     
13 }

//以上是常用工具

//下面实现游戏功能

 1 package cn.xiaocangtian.plane;
 2 
 3 import java.awt.Image;
 4 import java.awt.Rectangle;
 5 
 6 /**
 7  * 让 plane, Bullet继承之
 8  * @author admin
 9  *
10  */
11 public class GameObject {
12     Image img;
13     double x, y;
14     int speed = 5;
15     
16     int width, height;
17     
18     //获取飞机所在矩形
19     public Rectangle getRect() {
20         return new Rectangle((int)x, (int)y, width, height);
21     }
22 
23     public GameObject(Image img, double x, double y, int speed, int width,
24             int height) {
25         super();
26         this.img = img;
27         this.x = x;
28         this.y = y;
29         this.speed = speed;
30         this.width = width;
31         this.height = height;
32     }
33     
34     public GameObject() {}
35     
36 }
 1 package cn.xiaocangtian.plane;
 2 
 3 import java.awt.Graphics;
 4 import java.awt.Image;
 5 import java.awt.Rectangle;
 6 import java.awt.event.KeyEvent;
 7 
 8 import cn.xiaocangtian.Util.GameUtil;
 9 
10 public class Plane extends GameObject {
11     
12     private boolean left, up, right, down;
13     private boolean live = true;
14     
15     public void draw(Graphics g) {
16         if (live) {
17             g.drawImage(img, (int)x, (int)y, null);
18             move();
19         }
20     }
21     
22     //根据方向来改变坐标位置
23     public void addDirection(KeyEvent e) {
24         switch (e.getKeyCode()) {
25         case KeyEvent.VK_LEFT:             //
26             left = true; break;
27         case KeyEvent.VK_UP:               //
28             up = true; break;
29         case KeyEvent.VK_RIGHT:            //
30             right = true; break;
31         case KeyEvent.VK_DOWN:             //
32             down = true; break;
33         default: break;
34         }
35     }
36     
37     public void minusDirection(KeyEvent e) {
38         switch (e.getKeyCode()) {
39         case KeyEvent.VK_LEFT:             //
40             left = false; break;
41         case KeyEvent.VK_UP:               //
42             up = false; break;
43         case KeyEvent.VK_RIGHT:            //
44             right = false; break;
45         case KeyEvent.VK_DOWN:             //
46             down = false; break;
47         default: break;
48         }
49     }
50     
51     
52     public void move() {
53         if (left) {
54             x -= speed;
55         }
56         if (right) {
57             x += speed;
58         }
59         if (up) {
60             y -= speed;
61         }
62         if (down) {
63             y += speed;
64         }
65     }
66     
67     public Plane(String imgpath, double x, double y) {
68         this.img = GameUtil.getImage(imgpath);
69         this.width = img.getWidth(null);
70         this.height = img.getHeight(null);
71         this.x = x;
72         this.y = y;
73     }
74     
75     //无参构造器
76     public Plane() {}
77 
78     public void setLive(boolean live) {
79         this.live = live;
80     }
81 
82     public boolean isLive() {
83         return live;
84     }
85      
86     
87     
88     
89     
90     
91 }
 1 package cn.xiaocangtian.plane;
 2 
 3 import java.awt.Color;
 4 import java.awt.Graphics;
 5 import java.awt.Image;
 6 import java.awt.Rectangle;
 7 
 8 import cn.xiaocangtian.Util.Constant;
 9 
10 public class Bullet extends GameObject {
11 
12     double degree;
13     
14     public Bullet() {
15         degree = Math.random() * Math.PI * 2;
16         x = Constant.GAME_WIDTH / 2;    //设置子弹发射位置
17         y = Constant.GAME_HEIGHT / 2;
18         width = 10;
19         height = 10;
20     }
21     
22     //获取子弹矩形
23     public Rectangle getRect() {
24         return new Rectangle((int)x, (int)y, width, height);
25     }
26     
27     public void draw(Graphics g) {
28         Color oldColor = g.getColor();
29         //画一个子弹
30         g.setColor(Color.yellow);     
31         g.fillOval((int)x, (int)y, width, height);
32         
33         x += speed * Math.cos(degree);
34         y += speed * Math.sin(degree);
35         
36         //使子弹遇到窗口边缘反弹
37         if (y > Constant.GAME_HEIGHT - height || y < 30) {
38             degree = -degree;
39         }
40         if (x < 0 || x > Constant.GAME_WIDTH - width) {
41             degree = Math.PI - degree;
42         }
43         
44         g.setColor(oldColor);
45         
46     }
47     
48 }
 1 package cn.xiaocangtian.plane;
 2 
 3 import java.awt.Graphics;
 4 import java.awt.Image;
 5 
 6 import cn.xiaocangtian.Util.GameUtil;
 7 
 8 /**
 9  * 爆炸类
10  * @author admin
11  */
12 public class Explode {
13     double x, y;
14 
15     //一堆图片,直接用static,只加载一遍,所有爆炸对象共享
16     static Image[] imgs = new Image[10];
17     int count;             //imgs数量
18     
19     //加载图片
20     static {               //利用static方法改写static对象
21         for (int i = 0; i < 10; i++) {
22             imgs[i] = GameUtil.getImage("images/explode/e" + i + ".png");
23             imgs[i].getWidth(null);  //可真实的将image加载进来
24         }
25     }
26     
27     //爆炸行为  就是  数组图片的切换
28     public void draw(Graphics g) {
29         if (count < 10) {
30             g.drawImage(imgs[count], (int)x, (int)y, null);
31             count++;
32         }
33     }
34     
35     public Explode(double x, double y) {
36         this.x = x;
37         this.y = y;
38     }
39     
40 }
  1 package cn.xiaocangtian.plane;
  2 
  3 import java.awt.Color;
  4 import java.awt.Font;
  5 import java.awt.Graphics;
  6 import java.awt.Image;
  7 import java.awt.event.KeyAdapter;
  8 import java.awt.event.KeyEvent;
  9 import java.util.ArrayList;
 10 import java.util.Date;
 11 
 12 import cn.xiaocangtian.Util.Constant;
 13 import cn.xiaocangtian.Util.GameUtil;
 14 import cn.xiaocangtian.Util.MyFrame;
 15     
 16 public class PlaneGameFrame extends MyFrame {
 17     Image bg = GameUtil.getImage("images/bg.png");
 18     
 19     Plane p = new Plane("images/plane.png", 50, 50);
 20 
 21     //容器(泛型未学,暂时不加)
 22     ArrayList bulletList = new ArrayList();
 23 
 24     Date startTime;
 25     Date endTime;
 26     
 27     Explode boom;
 28     
 29     public void paint(Graphics g) {
 30         g.drawImage(bg, 0, 0, null);
 31         p.draw(g);
 32         
 33         //在这里画子弹
 34         for (int i = 0; i < bulletList.size(); i++) {
 35             Bullet b = (Bullet)bulletList.get(i);
 36             b.draw(g);
 37             //检测跟飞机的碰撞
 38             boolean peng = b.getRect().intersects(p.getRect());
 39             if (peng) {
 40                 p.setLive(false);     //飞机死掉
 41                 if (boom == null) {   //都只执行一次
 42                     endTime = new Date(); 
 43                     boom = new Explode(p.x, p.y);
 44                 }
 45                 boom.draw(g);
 46                 
 47                 break;
 48             }
 49         }
 50         
 51         if (!p.isLive()) {
 52             int period = ((int)endTime.getTime() - (int)startTime.getTime()) / 1000;  //转换成秒
 53             printInfo(g, "时间: " + period + "秒", 20, 115, 300, Color.white);
 54             
 55             switch (period / 10) {
 56             case 0:
 57             case 1:
 58                 printInfo(g, "菜鸟", 40, 115, 270, Color.white);
 59                 break;
 60             case 2:
 61                 printInfo(g, "入门", 40, 115, 270, Color.yellow);
 62                 break;
 63             case 4:
 64                 printInfo(g, "精通", 40, 115, 270, Color.white);
 65                 break;
 66             case 5:
 67                 printInfo(g, "大师", 40, 115, 270, Color.white);
 68                 break;
 69             }
 70         }
 71 //        printInfo(g, "分数: 100", 10, 50, 50, Color.yellow);
 72         
 73     }
 74     
 75     /**
 76      * 在窗口 上打印信息
 77      * @param g
 78      * @param str
 79      * @param size
 80      */
 81     public void printInfo(Graphics g, String str, int size, int x, int y, Color color) {
 82         Color c = g.getColor();
 83         g.setColor(color);
 84         Font f = new Font("宋体", Font.BOLD, size);
 85         g.setFont(f);
 86         g.drawString(str, x, y);
 87         g.setColor(c);
 88     }
 89     
 90     //重写父类的 launchFrame()
 91     public void launchFrame() {
 92         super.launchFrame();
 93         //增加键盘的监听
 94         addKeyListener(new KeyMonitor());
 95         //应该在加载窗口的时候生成子弹
 96         for (int i = 0; i < 10; i++) {
 97             Bullet b = new Bullet();
 98             bulletList.add(b);
 99         }
100         
101         startTime = new Date();          //从启动窗口开始计时
102     }
103     
104     //定义成内部类,可以方便使用外部类的普通属性
105     //键盘适配器
106     //定义完需要注册,然后才能用(在父类的launchFrame中注册,这里需要在
107     //子类中重写launchFrame,如上)
108     class KeyMonitor extends KeyAdapter {
109 
110         @Override
111         public void keyPressed(KeyEvent e) {
112             p.addDirection(e);
113         }
114 
115         @Override
116         public void keyReleased(KeyEvent e) {
117             p.minusDirection(e);
118         }
119         
120     }
121     
122     
123     public static void main(String[] args) {
124         new PlaneGameFrame().launchFrame();
125     }
126 }

       

 

posted @ 2016-12-09 20:09 douzujun 阅读( ...) 评论( ...) 编辑 收藏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值