java标签做血量_java小项目,重写实现血量的飞机大战

本文介绍了一个使用Java编写的飞机大战小游戏,通过Java标签实现了血量显示,并采用双缓冲技术消除画面闪烁,提供平滑的游戏体验。玩家可以通过键盘控制飞机移动、射击,游戏包含敌人飞机、子弹、爆炸效果以及分数统计等功能。
摘要由CSDN通过智能技术生成

下面有图片,方便大家先看界面!

package 飞机大战;

import java.awt.Color;

import java.awt.Font;

import java.awt.Frame;

import java.awt.Graphics;

import java.awt.Image;

import java.awt.LayoutManager;

import java.awt.RenderingHints.Key;

import java.awt.event.KeyAdapter;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import java.util.ArrayList;

import java.util.List;

import java.util.Random;

import javax.swing.ImageIcon;

import javax.swing.JPanel;

/**

* 主类,线程,所有的事物重绘都在这个类

* @author yan

*

*/

public class WarUI extends Frame{

public static final int WIDTH=410;

public static final int HEIGHT=600;

public ImageIcon img;

public ImageIcon img2;

public static WarUI warui;

public boolean p=true;

public static List planes = new ArrayList();// 敌人飞机容器

public static List bullets = new ArrayList();//子弹容器

public static List explodes=new ArrayList();//爆炸对象

public static int score=0;//计分

private Image offScreenImage = null;//用来实现使用双缓冲,画一个缓冲画布

public Panle myplane=new Panle(150,500,warui,60,true);

private Random random=new Random();

public void lauchFrame() {

setTitle("飞机大战");

setBounds(380, 100, WIDTH, HEIGHT);

// 匿名内部类,短,不涉及将来的扩展

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {

System.exit(0);

}

});

img=new ImageIcon("背景\\back.jpg");//接口,getImage方法返回一个Image对象,repaint方法会调用paint方法

img2=new ImageIcon("背景\\back2.jpg");//接口,getImage方法返回一个Image对象,repaint方法会调用paint方法

setResizable(false);

setVisible(true);

MyKeyListener mkl=new MyKeyListener();

this.addKeyListener(mkl);

new Thread(new PaintThread()).start();

}

public static void main(String[] args) {

warui =new WarUI();

warui.lauchFrame();

}

/**

* 消除闪烁,使用双缓冲

* 线程重画更加均匀,更能控制重化的速度。按键重画不能解决子弹自动飞行的问题;

* 每次重绘调用repaint方法时,必定会先调用update然后paint方法

*/

public void update(Graphics g) {

if (offScreenImage == null) {

offScreenImage = this.createImage(WIDTH, HEIGHT);

}

// 拿到图片上的画笔

Graphics gOffScreen = offScreenImage.getGraphics();

Color c = gOffScreen.getColor();

gOffScreen.setColor(Color.blue);

gOffScreen.fillRect(0, 0, WIDTH,HEIGHT);

gOffScreen.setColor(c);

paint(gOffScreen);// 画在背后图片上

g.drawImage(offScreenImage, 0, 0, null);// 画在屏幕上

}

/**

* 根据线程里面的repaint方法,不断重画面板,飞机,子弹,爆炸效果,等待都是在里面画出来的

*/

public void paint(Graphics g){

//根据不同的分数层切换背景图片

if(score>5000){

g.drawImage(img2.getImage(), 0, 0, warui);

}else{

g.drawImage(img.getImage(), 0, 0, warui);

}

if(!myplane.isLive()){

g.setColor(Color.red);

Font f = g.getFont();

g.setFont(new Font("宋体",Font.BOLD,60));

g.drawString("GAME OVER!!!", 20, 300);

g.setFont(f);

g.drawString("复活按B,重新开始按C!!!", 22, 340);

p=false;

}

myplane.draw(g);

myplane.move();

/**

* 添加 / 重绘敌人

*/

if (planes.size()<3 ) {

for (int j = 0; j < 3; j++) {

Panle p = new Panle(false, warui);

planes.add(p);

}

}

if (planes.size() != 0) {

for (int i = 0; i < planes.size(); i++) {

Panle diren = planes.get(i);

diren.draw(g);

diren.dmove();

int r1=random.nextInt(200);

if(r1==20)

diren.dfire();

}

}

g.setColor(Color.BLUE);

g.drawString("子 弹 个 数 :"+bullets.size(), 20,50);

g.drawString("入侵敌机数:"+planes.size(), 20, 70);

g.drawString("获得分数:"+score, 20, 90);

g.drawString("A 开火,P 暂停", 20, 110);

g.drawString("C重新开始,B 复活:", 20, 130);

g.setColor(Color.BLACK);

for(int i=0;i

Bullet b1=bullets.get(i);

b1.draw(g);

b1.hitplane(planes);

b1.hitplane(myplane);

b1.move();

}

/**

* 创建爆炸对象

*/

for (int i = 0; i < explodes.size(); i++) {

Explode e = explodes.get(i);

e.draw(g);

}

/**

* 血块添加

* 添加飞机吃血块的方法

*/

if(myplane.life<30){

Blood b=new Blood();

b.draw(g);

myplane.eat(b);

}

}

/**

* // 内部类,,方便的访问包装类的方法,不方便公开,

* @author yan

*

*/

private class PaintThread implements Runnable {

public void run() {

while (true) {

if(p==true){

repaint();

}

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

/**

* 键盘事件,直接添加在面板上,然后对飞机的X,Y速度进行控制

* @author yan

*

*/

class MyKeyListener extends KeyAdapter {

public void keyPressed(KeyEvent e) {

switch (e.getKeyCode()) {

case 37:// 左

myplane.left();

break;

case 38:// 上

myplane.up();

break;

case 39:// 右

myplane.right();

break;

case 40:// 下

myplane.down();

break;

case 65://A键

if(myplane.isLive()){

myplane.fire();

}

break;

case 66://B建复活,清空子弹

p=true;

myplane=new Panle(150,500,warui,60,true);

bullets.removeAll(bullets);

break;

case 67://C建重新开始

p=true;

myplane=new Panle(150,500,warui,60,true);

bullets.removeAll(bullets);

planes.removeAll(planes);

break;

case 80://P键,暂停

if(p==false){

p=true;

}else{

p=false;

}

break;

}

}

/**

* 抬起键时,把速度为0

*/

public void keyReleased(KeyEvent e) {

if (e.getKeyCode() == 37 || e.getKeyCode() == 39) {

myplane.initXc();

} else if (e.getKeyCode() == 38 || e.getKeyCode() == 40) {

myplane.initYc();

}

}

}

}

?这只是一个主类,其他完整代码和图片在压缩包里面,需要的话,请下载!

原文:http://qq-24665727.iteye.com/blog/2266079

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值