准备工作
- 理解java中的面向对象
- 理解GUI编程
- 理解多线程的使用
- java中集合的使用
实体类
- 背景类
public class BackGround {
//设置背景图标的坐标和宽、高
private int x;
private int y;
private int width;
private int height;
//获取背景图标
private ImageIcon icon=new ImageIcon("src\\image\\bg.jpg");
public BackGround(int x, int y) {
this.x = x;
this.y = y;
//获取背景图标的固定宽度
this.width = icon.getIconWidth();
//获取背景图标的固定高度
this.height = icon.getIconHeight();
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public ImageIcon getIcon() {
return icon;
}
//设置背景图标移动的方法(每次移动1像素)
public void move(){
this.y+=1;
}
}
- 爆炸类
public class Bomb {
//设置爆炸的坐标
private int x;
private int y;
//设置爆炸效果停留多长时间
public int time;
//获取爆炸图标
private ImageIcon icon=new ImageIcon("src\\image\\bomb.png");
public void setTime(int time) {
this.time = time;
}
public Bomb(int x, int y, int time) {
this.x = x;
this.y = y;
this.time=time;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public ImageIcon getIcon() {
return icon;
}
}
- 子弹类
public class Bullet {
//子弹的坐标和宽、高
private int x;
private int y;
private int width;
private int height;
//获取子弹的图标
private ImageIcon icon=new ImageIcon("src\\image\\bullet.png");
public Bullet(int x, int y) {
this.x = x;
this.y = y;
//获取子弹图标固定宽度
this.width = icon.getIconWidth();
//获取子弹图标的固定高度
this.height = icon.getIconHeight();
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public ImageIcon getIcon() {
return icon;
}
//子弹移动的方法(每次向上移动3像素)
public void move(){
this.y-=3;
}
}
- 敌机类
public class Enemy {
//敌机的坐标和宽、高
private int x;
private int y;
private int width;
private int height;
//获取敌机图标
private ImageIcon icon=new ImageIcon("src\\image\\enemy.png");
public Enemy(int x, int y) {
this.x = x;
this.y = y;
//获取敌机图标固定的宽度
this.width = icon.getIconWidth();
//获取敌机图标的固定高度
this.height = icon.getIconHeight();
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public ImageIcon getIcon() {
return icon;
}
//敌机移动的方法(每次移动4像素)
public void move(){
this.y+=4;
}
}
- 英雄飞机摧毁类
public class HeroDestroy {
//设置飞机销毁的坐标和宽、高
private int x;
private int y;
private int width;
private int height;
//获取飞机销毁的图标
private ImageIcon icon=new ImageIcon("src/image/hero_destory.png");
public HeroDestroy(int x, int y) {
this.x = x;
this.y = y;
//获取飞机销毁图标的固定宽度
this.width = icon.getIconWidth();
//获取飞机销毁图标的固定高度
this.height = icon.getIconHeight();
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public ImageIcon getIcon() {
return icon;
}
}
- 英雄飞机类
public class HeroPlane {
//定义飞机的坐标和宽、高
private int x;
private int y;
private int width;
private int height;
//获取飞机图标
private ImageIcon icon=new ImageIcon("src\\image\\hero.png");
public HeroPlane(int x, int y) {
this.x = x;
this.y = y;
//获取飞机图标的固定宽度
this.width = icon.getIconWidth();
//获取飞机图标的固定高度
this.height = icon.getIconHeight();
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public ImageIcon getIcon() {
return icon;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
}
- 登录窗口类
public class LoginFrame extends JFrame {
//创建一个登陆按钮
private JLabel label=new JLabel();
public LoginFrame(){
//设置按钮的边界
label.setBounds(0,0,480,800);
//设置按钮的图标
label.setIcon(new ImageIcon("src/image/login.jpg"));
//将按钮添加进窗体
this.add(label);
//点击按钮事件监听
label.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
//如果鼠标事件在某个范围内点击
if (e.getX()>=120 &&e.getX()<=355 &&e.getY()>=565 && e.getY()<=630){
//隐藏当前窗口,由于垃圾回收未执行,调用线程创建窗口
LoginFrame.this.setVisible(false);
new Thread(new GameJFrame("飞机大战")).start();
}
}
});
//移动监听器(鼠标)
label.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
super.mouseMoved(e);
//如果鼠标事件在某个范围内移动
if (e.getX()>=120 &&e.getX()<=355 &&e.getY()>=565 && e.getY()<=630) {
//设置鼠标按钮的形状
label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}else {
//设置回原来的形状
label.setCursor(Cursor.getDefaultCursor());
}
}
});
//设置当前窗体的边界
this.setBounds(750,100,480,800);
//设置窗体可见
this.setVisible(true);
}
}
- 游戏窗口类(多线程)
public class GameJFrame extends JFrame implements Runnable{
//将面板添加到窗体中
private GameJPanel panel=new GameJPanel();
public GameJFrame(String title){
//标题
super(title);
//添加其他元素(面板等等)
this.addElements();
//添加其他监听事件
this.addAction();
//设置窗体自己的属性
this.setJFrameSelf();
}
public void addElements(){
this.add(panel);
}
public void addAction(){
this.addMouseMotionListener(panel);
}
public void setJFrameSelf(){
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBounds(750,100,480,700);
this.setResizable(false);
}
//多线程控制面板的初始化界面
@Override
public void run() {
panel.init();
}
}
- 游戏面板类(鼠标监听器)
public class GameJPanel extends JPanel implements MouseMotionListener {
//设置飞机作为属性
private HeroPlane hero=new HeroPlane(200,520);
//设置一堆子弹作为属性
private ArrayList<Bullet> bullets=new ArrayList<>();
//设置一堆敌机作为属性
private ArrayList<Enemy> enemyArrayList=new ArrayList<>();
//设置背景图作为属性
private ArrayList<BackGround> backGroundArrayList=new ArrayList<>();
//设置一堆敌机爆炸图作为属性
private ArrayList<Bomb> bombArrayList=new ArrayList<>();
//设置飞机爆炸图片作为属性
private HeroDestroy heroDestroy;
//设置一个积分
private int score=0;
//初始化界面方法
public void init() {
//定义一个基数,用来判断
int count = 0;
//初始化时添加一张背景图
backGroundArrayList.add(new BackGround(0,0));
//不断重复界面的行为
while (true) {
count++;
//如果存在一张背景图则添加一张背景图在背景图最上边
if (backGroundArrayList.size()==1){
backGroundArrayList.add(new BackGround(0,-700));
}
//设置背景图的移动和移除
for (int i = 0; i <backGroundArrayList.size() ; i++) {
BackGround backGround = backGroundArrayList.get(i);
if (backGround!=null){
backGround.move();
//背景图超出界面则移除
if (backGround.getY()>700){
backGroundArrayList.remove(backGround);
}
}
}
//经过200毫秒添加一颗子弹
if (count%20==0) {
bullets.add(new Bullet(hero.getX() + 45, hero.getY() - 15));
}
//设置子弹的移动和移除
for (int i = 0; i <bullets.size() ; i++) {
Bullet bullet = bullets.get(i);
if (bullets!=null){
bullet.move();
//如果子弹超出边界则移除子弹
if (bullet.getY()<-15){
bullets.remove(bullet);
}
}
}
//经过800毫秒添加一架随机敌机
if (count%80==0){
enemyArrayList.add(new Enemy((int)(Math.random()*430),-30));
}
//设置敌机的移动和移除以及是否被击中行为
for (int i = 0; i <enemyArrayList.size() ; i++) {
Enemy enemy = enemyArrayList.get(i);
if (enemy!=null){
enemy.move();
//如果超出边界敌机没被击中则移除
if (enemy.getY()>700){
enemyArrayList.remove(enemy);
}
for (int j = 0; j <bullets.size() ; j++) {
Bullet bullet = bullets.get(j);
if (bullet!=null){
//如果子弹和敌机被击中则把子弹和敌机移除,添加敌机爆炸图
if (isHit(enemy,bullet)){
//如果子弹与敌机碰撞添加爆炸效果图
bombArrayList.add(new Bomb(enemy.getX(),enemy.getY(),0));
//将敌机移除
enemyArrayList.remove(enemy);
//将子弹移除
bullets.remove(bullet);
//分数加10
score+=10;
}
}
}
//判断飞机与敌机是否碰撞
if (isHit(enemy,hero)){
//如果碰撞则添加爆炸图标
bombArrayList.add(new Bomb(enemy.getX(),enemy.getY(),0));
//将敌机移除
enemyArrayList.remove(enemy);
//将英雄飞机的当前位置设置飞机摧毁图片
heroDestroy =new HeroDestroy(hero.getX(),hero.getY());
//再将英雄飞机变为null
hero=null;
//弹出消息框,游戏结束
JOptionPane.showMessageDialog(this,"游戏结束,您的得分为"+score);
return;
}
}
}
//设置time,经过100毫秒把爆炸的敌机移除
for (int i = 0; i <bombArrayList.size() ; i++) {
Bomb bomb = bombArrayList.get(i);
bomb.setTime(bomb.time+1);
if (bomb!=null && bomb.time==10){
//100毫秒后移除爆炸效果
bombArrayList.remove(bomb);
}
}
//重新绘制画面(刷新)
repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//设置子弹和敌机碰撞方法
public boolean isHit(Enemy enemy,Bullet bullet){
//画出当前子弹和敌机的边界范围
Rectangle renemy=new Rectangle(enemy.getX(),enemy.getY(),enemy.getWidth(),enemy.getHeight());
Rectangle benemy=new Rectangle(bullet.getX(),bullet.getY(),bullet.getWidth(),bullet.getHeight());
//返回两个边界是否有交叉来判断是否被碰撞
return renemy.intersects(benemy);
}
//设置敌机和飞机碰撞方法
public boolean isHit(Enemy enemy,HeroPlane hero){
//画出当前飞机和敌机的边界范围
Rectangle renemy=new Rectangle(enemy.getX(),enemy.getY(),enemy.getWidth(),enemy.getHeight());
Rectangle rhero=new Rectangle(hero.getX(),hero.getY(),hero.getWidth(),hero.getHeight());
//返回两个边界是否有交叉来判断是否被碰撞
return renemy.intersects(rhero);
}
//画图方法
@Override
public void paint(Graphics g) {
super.paint(g);
//画背景图
for (int i = 0; i <backGroundArrayList.size() ; i++) {
BackGround backGround = backGroundArrayList.get(i);
if (backGround!=null){
g.drawImage(backGround.getIcon().getImage(),backGround.getX(),backGround.getY(),null);
}
}
//画当前飞机图
if (hero!=null) {
g.drawImage(hero.getIcon().getImage(), hero.getX(), hero.getY(), null);
}
//画一堆飞机的子弹
for (int i = 0; i <bullets.size() ; i++) {
Bullet bullet = bullets.get(i);
if (bullet!=null){
g.drawImage(bullet.getIcon().getImage(),bullet.getX(),bullet.getY(),null);
}
}
//画一堆敌机
for (int i = 0; i <enemyArrayList.size() ; i++) {
Enemy enemy = enemyArrayList.get(i);
if (enemy!=null){
g.drawImage(enemy.getIcon().getImage(),enemy.getX(),enemy.getY(),null);
}
}
//画敌机被子弹击中图
for (int i = 0; i <bombArrayList.size() ; i++) {
Bomb bomb = bombArrayList.get(i);
if (bomb!=null){
g.drawImage(bomb.getIcon().getImage(),bomb.getX(),bomb.getY(),null);
}
}
//画飞机被敌机击中图
if (heroDestroy !=null){
g.drawImage(heroDestroy.getIcon().getImage(), heroDestroy.getX(), heroDestroy.getY(),null);
}
//画积分数
if (hero!=null){
setFont(new Font("宋体",Font.BOLD,24));
g.drawString("当前积分"+score,10,30);
}
}
@Override
public void mouseDragged(MouseEvent e) {
//鼠标拉拽移动
}
@Override
//鼠标移动监听事件
public void mouseMoved(MouseEvent e) {
//控制飞机的移动范围
int x = e.getX();
int y = e.getY();
if (hero!=null){
if (x>0 && x<480) {
hero.setX(x - 50);
}
if (y>100 && y<650) {
hero.setY(y - 100);
}
}
//重新绘制画面
repaint();
}
}
- 测试类
public class StartTest {
public static void main(String[] args) {
//启动程序
new LoginFrame();
}
}
图片素材