"飞机大战"游戏_Java
2016-12-09 20:09
274 查看
1 package cn.xiaocangtian.Util; import java.awt.Frame; import java.awt.Graphics; import java.awt.Image; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class MyFrame extends Frame { //加载窗口 public void launchFrame() { 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); } }); } //双缓冲技术解决屏幕闪烁 private Image offScreenImage = null; //利用双缓冲技术消除闪烁 public void update(Graphics g) { if (offScreenImage == null) offScreenImage = this.createImage(Constant.GAME_WIDTH, Constant.GAME_HEIGHT); Graphics gOff = offScreenImage.getGraphics(); paint(gOff); g.drawImage(offScreenImage, 0, 0, null); } /** * 定义一个重画窗口的线程类 * 是一个内部类(方便访问外部类属性) */ class PaintThread extends Thread { public void run() { while (true) { repaint(); //重画 try { Thread.sleep(40); //1s = 1000ms } catch (InterruptedException e) { e.printStackTrace(); } } } } }
package cn.xiaocangtian.Util; import java.awt.Image; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; import javax.imageio.ImageIO; import javax.swing.ImageIcon; /** * 游戏开发中常用的工具类(比如:加载图片等方法) * @author admin * */ public class GameUtil { private GameUtil () {} //工具类通常将构造方法私有 public static Image getImage(String path) { // return Toolkit.getDefaultToolkit().getImage(GameUtil.class.getClassLoader().getResource(path)); BufferedImage bi = null; try { URL u = GameUtil.class.getClassLoader().getResource(path); bi = javax.imageio.ImageIO.read(u); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return bi; } }
package cn.xiaocangtian.Util; /** * 游戏项目中用到的常量 * 单独负责常量 * @author admin */ public class Constant { public static final int GAME_WIDTH = 350; public static final int GAME_HEIGHT = 600; }
//以上是常用工具
//下面实现游戏功能
package cn.xiaocangtian.plane; import java.awt.Image; import java.awt.Rectangle; /** * 让 plane, Bullet继承之 * @author admin * */ public class GameObject { Image img; double x, y; int speed = 5; int width, height; //获取飞机所在矩形 public Rectangle getRect() { return new Rectangle((int)x, (int)y, width, height); } 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; } public GameObject() {} }
package cn.xiaocangtian.plane; import java.awt.Graphics; import java.awt.Image; import java.awt.Rectangle; import java.awt.event.KeyEvent; import cn.xiaocangtian.Util.GameUtil; public class Plane extends GameObject { private boolean left, up, right, down; private boolean live = true; public void draw(Graphics g) { if (live) { g.drawImage(img, (int)x, (int)y, null); move(); } } //根据方向来改变坐标位置 public void addDirection(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: //左 left = true; break; case KeyEvent.VK_UP: //上 up = true; break; case KeyEvent.VK_RIGHT: //右 right = true; break; case KeyEvent.VK_DOWN: //下 down = true; break; default: break; } } public void minusDirection(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: //左 left = false; break; case KeyEvent.VK_UP: //上 up = false; break; case KeyEvent.VK_RIGHT: //右 right = false; break; case KeyEvent.VK_DOWN: //下 down = false; break; default: break; } } public void move() { if (left) { x -= speed; } if (right) { x += speed; } if (up) { y -= speed; } if (down) { y += speed; } } public Plane(String imgpath, double x, double y) { this.img = GameUtil.getImage(imgpath); this.width = img.getWidth(null); this.height = img.getHeight(null); this.x = x; this.y = y; } //无参构造器 public Plane() {} public void setLive(boolean live) { this.live = live; } public boolean isLive() { return live; } }
package cn.xiaocangtian.plane; import java.awt.Color; import java.awt.Graphics; import java.awt.Image; import java.awt.Rectangle; import cn.xiaocangtian.Util.Constant; public class Bullet extends GameObject { double degree; public Bullet() { degree = Math.random() * Math.PI * 2; x = Constant.GAME_WIDTH / 2; //设置子弹发射位置 y = Constant.GAME_HEIGHT / 2; width = 10; height = 10; } //获取子弹矩形 public Rectangle getRect() { return new Rectangle((int)x, (int)y, width, height); } public void draw(Graphics g) { Color oldColor = g.getColor(); //画一个子弹 g.setColor(Color.yellow); g.fillOval((int)x, (int)y, width, height); x += speed * Math.cos(degree); y += speed * Math.sin(degree); //使子弹遇到窗口边缘反弹 if (y > Constant.GAME_HEIGHT - height || y < 30) { degree = -degree; } if (x < 0 || x > Constant.GAME_WIDTH - width) { degree = Math.PI - degree; } g.setColor(oldColor); } }
package cn.xiaocangtian.plane; import java.awt.Graphics; import java.awt.Image; import cn.xiaocangtian.Util.GameUtil; /** * 爆炸类 * @author admin */ public class Explode { double x, y; //一堆图片,直接用static,只加载一遍,所有爆炸对象共享 static Image[] imgs = new Image[10]; int count; //imgs数量 //加载图片 static { //利用static方法改写static对象 for (int i = 0; i < 10; i++) { imgs[i] = GameUtil.getImage("images/explode/e" + i + ".png"); imgs[i].getWidth(null); //可真实的将image加载进来 } } //爆炸行为 就是 数组图片的切换 public void draw(Graphics g) { if (count < 10) { g.drawImage(imgs[count], (int)x, (int)y, null); count++; } } public Explode(double x, double y) { this.x = x; this.y = y; } }
package cn.xiaocangtian.plane; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.Date; import cn.xiaocangtian.Util.Constant; import cn.xiaocangtian.Util.GameUtil; import cn.xiaocangtian.Util.MyFrame; public class PlaneGameFrame extends MyFrame { Image bg = GameUtil.getImage("images/bg.png"); Plane p = new Plane("images/plane.png", 50, 50); //容器(泛型未学,暂时不加) ArrayList bulletList = new ArrayList(); Date startTime; Date endTime; Explode boom; public void paint(Graphics g) { g.drawImage(bg, 0, 0, null); p.draw(g); //在这里画子弹 for (int i = 0; i < bulletList.size(); i++) { Bullet b = (Bullet)bulletList.get(i); b.draw(g); //检测跟飞机的碰撞 boolean peng = b.getRect().intersects(p.getRect()); if (peng) { p.setLive(false); //飞机死掉 if (boom == null) { //都只执行一次 endTime = new Date(); boom = new Explode(p.x, p.y); } boom.draw(g); break; } } if (!p.isLive()) { int period = ((int)endTime.getTime() - (int)startTime.getTime()) / 1000; //转换成秒 printInfo(g, "时间: " + period + "秒", 20, 115, 300, Color.white); switch (period / 10) { case 0: case 1: printInfo(g, "菜鸟", 40, 115, 270, Color.white); break; case 2: printInfo(g, "入门", 40, 115, 270, Color.yellow); break; case 4: printInfo(g, "精通", 40, 115, 270, Color.white); break; case 5: printInfo(g, "大师", 40, 115, 270, Color.white); break; } } // printInfo(g, "分数: 100", 10, 50, 50, Color.yellow); } /** * 在窗口 上打印信息 * @param g * @param str * @param size */ public void printInfo(Graphics g, String str, int size, int x, int y, Color color) { Color c = g.getColor(); g.setColor(color); Font f = new Font("宋体", Font.BOLD, size); g.setFont(f); g.drawString(str, x, y); g.setColor(c); } //重写父类的 launchFrame() public void launchFrame() { super.launchFrame(); //增加键盘的监听 addKeyListener(new KeyMonitor()); //应该在加载窗口的时候生成子弹 for (int i = 0; i < 10; i++) { Bullet b = new Bullet(); bulletList.add(b); } startTime = new Date(); //从启动窗口开始计时 } //定义成内部类,可以方便使用外部类的普通属性 //键盘适配器 //定义完需要注册,然后才能用(在父类的launchFrame中注册,这里需要在 //子类中重写launchFrame,如上) class KeyMonitor extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { p.addDirection(e); } @Override public void keyReleased(KeyEvent e) { p.minusDirection(e); } } public static void main(String[] args) { new PlaneGameFrame().launchFrame(); } }
相关文章推荐
- Java 课程设计 "Give it up"小游戏设计(个人) 201521123077
- 我三年前的JAVA习作"扫雷"游戏已运行在今天的M8手机上
- 我三年前的JAVA习作"扫雷"游戏已运行在今天的M8手机上
- [Java细节]"hi there".equals("cheers !") == true
- Java游戏开发起步
- JAVA与游戏开发
- 完全掌握 Java 中的"包"机制(zt)
- "欺骗你的眼睛" -- 视觉游戏
- 追忆"游戏"的日子
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java)
- 老大"发飙"---台湾技术总监给我们JavaTeam的Mail
- 有感"Java is not platform-independent, it is the platform"
- J2ME技術使"Java無所不在" (一)
- 谁持彩练当空舞"-- 看Java、C#大比拚(1)
- 谁持彩练当空舞"-- 看Java、C#大比拚(2)
- 谁持彩练当空舞"-- 看Java、C#大比拚(3)
- "Java Library Path" in VOBSEnhydra 5.1SE under Linux
- Java vs C++ "Shootout" Revisited
- java中如何向水晶报表传参数--补充"haibodotnet的专栏"中"传参数"的内容
- "Thinking in Java 3rd Edition"[JAVA书籍]