在学习了java入门的课程之后,自己动手跟着老师写的一个小游戏,用的是Frame。总共有七个类。
1.飞机游戏的主窗口(MyGameFrame)继承Frame。
1package com.bjsxt.plane; 2 3import java.awt.Color; 4import java.awt.Font; 5import java.awt.Frame; 6import java.awt.Graphics; 7import java.awt.Image; 8import java.awt.event.KeyAdapter; 9import java.awt.event.KeyEvent; 10import java.awt.event.WindowAdapter; 11import java.awt.event.WindowEvent; 12import java.io.Writer; 13import java.util.Date; 14 15import javax.swing.JFrame; 16 17/** 18 * 飞机游戏的主窗口 19 * @author 机械师 20 * 21 */ 22public class MyGameFrame extends Frame{ 23 24 //导入图片 25 Image planeImage=GameUtil.getImage("images/plane.png"); 26 Image bg=GameUtil.getImage("images/bg.jpg"); 27 28 Plane plane=new Plane(planeImage,250,250); 29 Shell[] shells=new Shell[50]; 30 Explode bao; 31 Date startTime=new Date(); 32 Date endTime; 33 int period; 34 //帮助绘制窗口 35 @Override 36 public void paint(Graphics g) {//自动调用 37 g.drawImage(bg, 0, 0, null); 38 plane.drawSelf(g);//画飞机 39 // 画出所有的炮弹 40 for(int i=0;i<shells.length;i++){ 41 shells[i].draw(g); 42 boolean peng=shells[i].getRect().intersects(plane.getRect()); 43 44 if (peng) { 45 plane.live=false; 46 if (bao==null) { 47 bao=new Explode(plane.x, plane.y); 48 endTime=new Date(); 49 period=(int)((endTime.getTime()-startTime.getTime())/1000); 50 } 51 52 } 53 if (!plane.live) { 54 Color c=g.getColor(); 55 Font f=new Font("楷体", Font.BOLD, 25); 56 g.setFont(f); 57 g.setColor(Color.red); 58 g.drawString("游戏结束!! 您已存活:"+period+"秒", 110, 250); 59 bao.draw(g); 60 g.setColor(c); 61 } 62 } 63 } 64 65 class PaintThread extends Thread{ 66 //帮助我们反复的重画窗口 67 @Override 68 public void run() { 69 while (true) { 70 repaint(); 71 72 try { 73 Thread.sleep(40);//一秒画25次窗口 74 } catch (InterruptedException e) { 75 e.printStackTrace(); 76 } 77 } 78 } 79 } 80 81 //定义键盘监听 82 class KeyMonitor extends KeyAdapter{ 83 84 @Override 85 public void keyPressed(KeyEvent e) { 86 plane.addDirection(e); 87 } 88 89 @Override 90 public void keyReleased(KeyEvent e) { 91 plane.minusDirection(e); 92 } 93 94 } 95 96 /** 97 * 初始化窗口 98 */ 99 public void launchFrame(){ 100 setTitle("bjsxt_yxf--飞机躲避子弹小游戏游戏"); 101 setVisible(true);//true表示窗口可见 102 setSize(Constant.GAME_WIDTH,Constant.GAME_HEIGHT); 103 setLocation(300,300); 104 //增加监听事件,关闭动作,点击窗口的关闭按钮,程序便已经结束。 105 this.addWindowListener(new WindowAdapter() { 106 @Override 107 public void windowClosing(WindowEvent e) { 108 System.exit(0); 109 } 110 111 }); 112 new PaintThread().start();//启动重画窗口的线程 113 addKeyListener(new KeyMonitor());//增加键盘的监听 114 115 //初始化50个炮弹 116 for (int i = 0; i < shells.length; i++) { 117 shells[i]=new Shell(); 118 } 119 } 120 public static void main(String[] args) { 121 MyGameFrame f=new MyGameFrame(); 122 f.launchFrame(); 123 } 124 125 //解决闪烁问题(双缓冲) 126 private Image offScreenImage = null; 127 128 public void update(Graphics g) { 129 if(offScreenImage == null) 130 offScreenImage = this.createImage(Constant.GAME_WIDTH,Constant.GAME_HEIGHT);//这是游戏窗口的宽度和高度 131 132 Graphics gOff = offScreenImage.getGraphics(); 133 paint(gOff); 134 g.drawImage(offScreenImage, 0, 0, null); 135 } 136} 137
2.游戏的图片导入工具类(GameUtil)
1package com.bjsxt.plane; 2 3import java.awt.Image; 4import java.awt.image.BufferedImage; 5import java.io.IOException; 6import java.net.URL; 7 8import javax.imageio.ImageIO; 9 10public class GameUtil { 11 //将工具类私有化 12 private GameUtil(){ 13 14 } 15 /** 16 * 返回指定文件的路径对象 17 * @param path 18 * @return 19 */ 20 public static Image getImage(String path){ 21 BufferedImage bi=null; 22 try { 23 URL u= GameUtil.class.getClassLoader().getResource(path); 24 bi=ImageIO.read(u); 25 } catch (IOException e) { 26 e.printStackTrace(); 27 } 28 return bi; 29 30 } 31} 32
3.游戏物体的父类,游戏里的炮弹,飞机的属性都是继承这个类(GameObject)
1package com.bjsxt.plane; 2 3import java.awt.Graphics; 4import java.awt.Image; 5import java.awt.Rectangle; 6 7/** 8 * 游戏物体的父类 9 * @author 机械师 10 * 11 */ 12public class GameObject { 13 Image image; 14 double x,y; 15 int speed; 16 int width,height; 17 18 public void drawSelf(Graphics g){ 19 g.drawImage(image, (int)x, (int)y, null); 20 } 21 22 public GameObject(Image image, double x, double y, int speed, int width, 23 int height) { 24 super(); 25 this.image = image; 26 this.x = x; 27 this.y = y; 28 this.speed = speed; 29 this.width = width; 30 this.height = height; 31 } 32 33 public GameObject(Image image, double x, double y) { 34 super(); 35 this.image = image; 36 this.x = x; 37 this.y = y; 38 } 39 40 public GameObject() { 41 42 } 43 /** 44 * 返回物体所在的矩形 45 * @return 46 */ 47 public Rectangle getRect(){ 48 return new Rectangle((int)x, (int)y, width, height); 49 50 } 51 52} 53
4.爆炸类,飞机死亡的一系列动画操作(Explode)
1package com.bjsxt.plane; 2 3import java.awt.Graphics; 4import java.awt.Image; 5 6/** 7 * 爆炸类 8 * @author 机械师 9 * 10 */ 11public class Explode { 12 double x,y; 13 14 static Image[] imgs=new Image[16]; 15 static{ 16 for (int i = 0; i < imgs.length; i++) { 17 imgs[i]=GameUtil.getImage("explode/e"+(i+1)+".gif"); 18 imgs[i].getWidth(null); 19 } 20 } 21 22 int count; 23 24 public void draw(Graphics g){ 25 if (count<=15) { 26 g.drawImage(imgs[count], (int)x, (int)y, null); 27 count++; 28 } 29 } 30 31 public Explode(double x,double y){ 32 this.x=x; 33 this.y=y; 34 } 35} 36
5.飞机类,里面有飞机的速度,键盘按键设置等属性(Plane)
1package com.bjsxt.plane; 2 3import java.awt.Graphics; 4import java.awt.Image; 5import java.awt.event.KeyEvent; 6/** 7 * 飞机类 8 * @author 机械师 9 * 10 */ 11public class Plane extends GameObject { 12 boolean left,right,down,up; 13 int speed=4; 14 boolean live=true; 15 16 public void drawSelf(Graphics g){ 17 18 if (live) { 19 g.drawImage(image, (int)x, (int)y, null); 20 if (left) { 21 x-=speed; 22 } 23 if (right) { 24 x+=speed; 25 26 } 27 if (up) { 28 y-=speed; 29 30 } 31 if (down) { 32 y+=speed; 33 34 } 35 } 36 } 37 38 public Plane(Image image,double x,double y){ 39 this.image=image; 40 this.x=x; 41 this.y=y; 42 this.speed=speed; 43 this.width=image.getWidth(null); 44 this.height=image.getHeight(null); 45 } 46 47 public void addDirection(KeyEvent e){ 48 switch (e.getKeyCode()) { 49 case KeyEvent.VK_LEFT: 50 left=true; 51 speed++; 52 break; 53 case KeyEvent.VK_UP: 54 up=true; 55 speed++; 56 break; 57 case KeyEvent.VK_RIGHT: 58 right=true; 59 speed++; 60 break; 61 case KeyEvent.VK_DOWN: 62 down=true; 63 speed++; 64 break; 65 } 66 } 67 68 public void minusDirection(KeyEvent e){ 69 switch (e.getKeyCode()) { 70 case KeyEvent.VK_LEFT: 71 left=false; 72 break; 73 case KeyEvent.VK_UP: 74 up=false; 75 break; 76 case KeyEvent.VK_RIGHT: 77 right=false; 78 break; 79 case KeyEvent.VK_DOWN: 80 down=false; 81 break; 82 } 83 } 84} 85
6.炮弹类,里面包含了炮弹在固定位向任意方向发出数个炮弹,以及碰撞边界弹回。(Shell)
1package com.bjsxt.plane; 2 3import java.awt.Color; 4import java.awt.Graphics; 5 6/** 7 * 炮弹类 8 * @author 机械师 9 * 10 */ 11public class Shell extends GameObject{ 12 13 double degree; 14 public Shell(){ 15 x=200; 16 y=200; 17 speed=3; 18 width=10; 19 height=10; 20 degree=Math.random()*Math.PI*2;//o-2π之间的随机数 21 } 22 23 public void draw(Graphics g){ 24 Color c=g.getColor(); 25 g.setColor(Color.yellow); 26 g.fillOval((int)x, (int)y, width, height); 27 x+=speed*Math.cos(degree); 28 y+=speed*Math.sin(degree); 29 30 if (x<0||x>Constant.GAME_WIDTH-width) { 31 degree=Math.PI-degree; 32 speed++; 33 } else if(y<30||y>Constant.GAME_HEIGHT-height){ 34 degree=-degree; 35 speed++; 36 } 37 g.setColor(c); 38 } 39 40} 41
7.常数类。存储游戏边界的大小(Constant)
1package com.bjsxt.plane; 2 3public class Constant { 4 public static final int GAME_WIDTH=500; 5 public static final int GAME_HEIGHT=500; 6} 7
此小游戏在一开始,我们是继承Jframe的,但是由于在写到后面,看运行画面的时候还是有很多点闪烁,因此我们就改回到Frame,并且在主窗口类中使用了双缓冲。
1 private Image offScreenImage = null; 2 3 public void update(Graphics g) { 4 if(offScreenImage == null) 5 offScreenImage = this.createImage(Constant.GAME_WIDTH,Constant.GAME_HEIGHT);//这是游戏窗口的宽度和高度 6 7 Graphics gOff = offScreenImage.getGraphics(); 8 paint(gOff); 9 g.drawImage(offScreenImage, 0, 0, null); 10 }
改完之后,画面有很大的改善,看着非常的舒服。
