java飞机游戏小项目

一、功能:

1、实现键盘控制飞机超八个方向移动  2、碰撞事件   3、双缓冲技术消除屏幕闪烁问题     4、游戏等级的判断等等

二、特点:1、本代码的结构合理清晰,重构得好(所以你会看到较多的包和工具类) 2、增加了必要的代码注释


三、最终效果



四、package和class的关系图



  

五、代码部分:

1、Constants类

package com.liang.util;

public class Constants {

public static final double FRAME_WIDTH = 400; 

public static final double FRAME_HEIGTH = 600; 

}

2、获取图片的工具类

package com.liang.util;

import java.awt.Image;

import java.awt.image.BufferedImage;

import java.net.URL;

import javax.imageio.ImageIO;

//工具类:获取图片

public class GameUtil {

public static Image getImage(String imagepath){

URL url  = GameUtil.class.getClassLoader().getResource(imagepath);

BufferedImage image = null;

try{

image = ImageIO.read(url);

}catch(Exception e){

e.printStackTrace();

}

return image;

}

}

3、JFrame父类

package com.liang.util;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import javax.swing.JFrame;

public class MyFrame extends JFrame{

/**

* 工具类:框架

*/

private static final long serialVersionUID = 1L;

public void launchFrame(){

this.setBounds(200,  100, (int)Constants.FRAME_WIDTH, (int)Constants.FRAME_HEIGTH);

this.setVisible(true);

this.setResizable(false);

this.addWindowListener(new WindowAdapter() {

@Override

public void windowClosing(WindowEvent arg0) {

System.exit(0);

}

});

new PaintThread().start();

}

/*//利用双缓冲处理闪烁问题

private Image offScreenImage = null;

private Graphics goff = null;

@Override

public void update(Graphics g) {

//super.update(g);

if(offScreenImage == null){

offScreenImage = this.createImage((int)Constants.FRAME_WIDTH, (int)Constants.FRAME_HEIGTH);

goff = offScreenImage.getGraphics();

paint(goff);//自己调用这个函数

g.drawImage(offScreenImage, 0, 0, null);

}

}*/

//内部类,线程

public class PaintThread extends Thread{

@Override

public void run() {

while(true){

try{

repaint();

Thread.sleep(33);

}catch(Exception e){

e.printStackTrace();

}

}

}

}

}

4、Bullet类

package com.liang.planeGame; import java.awt.Color; import java.awt.Graphics; import com.liang.util.Constants; public class Bullet extends Substance{ //image, body_x, body_y,speed,degree //private Image image; private double degree; public Bullet(){ } public Bullet(double x,double y,double speed, double width, double height){ super(); //this.image = image; this.x = x; this.y = y; this.speed = speed; degree = Math.random()*Math.PI * 2; this.width = width; this.height = height; } public void draw(Graphics g){ //g.drawImage(image, (int)x, (int)y, null); Color c = g.getColor(); g.setColor(Color.yellow); g.fillOval((int)x, (int)y, (int)width, (int)height); g.setColor(c); move(); } private void move(){ x += speed * Math.cos(degree); y += speed * Math.sin(degree); if(x < 0 || x > Constants.FRAME_WIDTH){ degree = Math.PI - degree; } if(y < 0 || y > Constants.FRAME_HEIGTH){ degree = -degree; } } }

5、plane类

package com.liang.planeGame; import java.awt.Graphics; import java.awt.Image; import com.liang.util.GameUtil; public class Plane extends Substance{ //判断键盘的方向 private boolean left, right , up, down; private boolean alive = true; //飞机是否被击中 public Plane(){ } public Plane(Image image){ this.image = image; } public Plane(String imagePath){ this.image = GameUtil.getImage(imagePath); } public Plane(String imagePath,double x, double y, double speed) { super(); this.image = GameUtil.getImage(imagePath); this.x = x; this.y = y; this.speed = speed; this.width = image.getWidth(null); this.height = image.getWidth(null); } public void draw(Graphics g){ if(alive){ g.drawImage(image, (int)x, (int)y, null); move(); } } private void move(){ if(left){ x -= speed; } if(right){ x += speed; } if(up){ y -= speed; } if(down){ y += speed; } } public boolean isAlive() { return alive; } public void setAlive(boolean alive) { this.alive = alive; } public boolean isLeft() { return left; } public void setLeft(boolean left) { this.left = left; } public boolean isRight() { return right; } public void setRight(boolean right) { this.right = right; } public boolean isDown() { return down; } public void setDown(boolean down) { this.down = down; } public boolean isUp() { return up; } public void setUp(boolean up) { this.up = up; } }

6、框架父类

package com.liang.planeGame; 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 com.liang.util.Constants; import com.liang.util.GameUtil; import com.liang.util.MyFrame; public class GameFrame extends MyFrame{ /** * */ private static final long serialVersionUID = 1L; Image bg = GameUtil.getImage("Images/background.jpg"); Plane plane = new Plane("Images/plane.PNG",200, 200, 4);//image, 初始化x和y,speed ArrayList<Bullet> bulletList = new ArrayList<Bullet>(); Date startTime; Date endTime; int count = 0;//防止计时数改变 //String rankInfo; @Override public void paint(Graphics g) { g.drawImage(bg, 0, 0, null); plane.draw(g); //draw bullets for(int i = 0; i < bulletList.size(); i++){ Bullet b = (Bullet)bulletList.get(i); if(plane.isAlive() == true){ b.draw(g); } boolean hit = b.getRect().intersects(plane.getRect()); if(hit){ plane.setAlive(false); //防止再次碰到,导致计时数改变 if(count == 0){ endTime = new Date(); count++; } } } if(! plane.isAlive()){ paintInfo(g, " GameOver", 70,260,32,Color.yellow); paintInfo(g, "key ENTER to again", 65, 60, 23, Color.white); //计时 long time = (endTime.getTime() - startTime.getTime())/1000; // 时间 paintInfo(g, time+" seccond", 290, 60, 20, Color.orange); //等级信息 String rankInformation = Ranking(time); paintInfo(g, rankInformation, 130, 300, 34, Color.white); } } public void paintInfo(Graphics g, String string, double x, double y, int word_size, Color color){ Font font = new Font("正楷",Font.BOLD, word_size); Color c = g.getColor(); g.setColor(color); g.setFont(font); g.drawString(string, (int)x, (int)y); g.setColor(c); } //等级 public String Ranking(long time){ String rankInfo = null; switch((int)time/10){ case 0: case 1: rankInfo = "菜鸟"; break; case 2: rankInfo = "小鸟"; break; case 3: rankInfo = "大鸟"; break; case 4: rankInfo = "鸟人"; break; default:rankInfo = "凤凰"; } return rankInfo; } //内部类,键盘事件 public class MyKeyEvent extends KeyAdapter{ @Override public void keyPressed(KeyEvent event) { switch(event.getKeyCode()){ case KeyEvent.VK_LEFT: plane.setLeft(true); break; case KeyEvent.VK_RIGHT: plane.setRight(true); break; case KeyEvent.VK_UP: plane.setUp(true); break; case KeyEvent.VK_DOWN: plane.setDown(true); break; default: } } @Override public void keyReleased(KeyEvent event) { switch(event.getKeyCode()){ case KeyEvent.VK_LEFT: plane.setLeft(false); break; case KeyEvent.VK_RIGHT: plane.setRight(false); break; case KeyEvent.VK_UP: plane.setUp(false); break; case KeyEvent.VK_DOWN: plane.setDown(false); break; default: } } } //重写父类的方法,以便加入监听器 @Override public void launchFrame() { super.launchFrame(); startTime = new Date(); addKeyListener(new MyKeyEvent()); //增加子弹对象 for(int i = 0; i < 20; i++){ Bullet bullet = new Bullet(Constants.FRAME_WIDTH/2, 20, 3, 10, 10);//x, y, speed bulletList.add(bullet); //bullet.get(i).draw(g); } } public static void main(String args[]){ new GameFrame().launchFrame(); } }

7、bullet和plane的父类

package com.liang.planeGame; import java.awt.Graphics; import java.awt.Image; import java.awt.Rectangle; public class Substance { //image, body_x, body_y,speech, Image image; protected double x , y , speed; protected double width, height;//the width and height of image //空构造方法 public Substance(){ } public Substance(Image image, double x, double y, double speed, double width, double height) { super(); this.image = image; this.x = x; this.y = y; this.speed = speed; this.width = width; this.height = height; } public void draw(Graphics g){ g.drawImage(image, (int)x, (int)y, null); } //绘制飞机图片所在的长方形,以便进行碰撞事件的判断 public Rectangle getRect(){ return new Rectangle((int)x, (int)y, (int)width, (int)height); } }

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值