首先,先想想要完成一个飞机大战,需要完成那些步骤呢?
①是不是需要有个界面去显示飞机和子弹之类的组件呢?
这个时候是不是需要去绘制一个界面类呢? 答案是必须的!!!
②既然画完了界面,那界面的上的飞机、子弹、敌机啥的是不是也需要创建一个类去绘制呢?答案也是必须的!!!
在绘制子弹和敌机的时候,需要去考虑敌机遇到子弹爆炸的场景,以及每击毁一架飞机,怎么算我的得分的情况,这些都是需要去考虑的。
通过飞机大战能够学到的知识点有:
①面向对象:其中包括了继承、实现接口以及封装;
②学会使用队列ArrayList进行存储;
③明白如何读取图片,然后将该图片放在窗体上;
④学会使用多线程。
①先绘制飞机大战的界面类GameMain类。
package FlyV4B;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class GameMain {
//窗口的宽度和高度
static int width = 600;
static int height = 800;
public static void main(String[] args) {
//创建一个窗口的大小
JFrame frame = new JFrame();
//设置标题
frame.setTitle("飞机大战");
//设置窗口的大小
frame.setSize(width, height);
//关闭窗口关闭后JVM终止运行
frame.setDefaultCloseOperation(3);
//设置窗口居中
frame.setLocationRelativeTo(null);
//创建JPanel容器
GamePanel panel = new GamePanel();
//把JPanel添加到窗口中
frame.add(panel);
//添加鼠标监听器
frame.addMouseMotionListener(panel);
//设置可见
frame.setVisible(true);
//初始化容器
panel.init();
}
}
在界面类中添加鼠标移动监听器,目的是鼠标放到界面上或者按压界面时能够使得飞机进行移动。
②英雄机类–GamePanel类
package FlyV4B;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.List;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class GamePanel extends JPanel implements MouseMotionListener{
//读取英雄机的图片
ImageIcon heroImage = new ImageIcon("image/hero.png");
//定义一个集合来装所有的敌机
ArrayList<Enemy> enemys = new ArrayList();
//定义一个队列来装所有的子弹
ArrayList<Bullet> bullets = new ArrayList();
//定义一个集合来装爆炸的图片
ArrayList<Bomb> bombs = new ArrayList();
//英雄机的坐标
int heroX = 300;
int heroY = 400;
private int number=0;//分数
public GamePanel() {
//创建10个敌人
for(int i=0; i<10; i++){
enemys.add(new Enemy());
}
}
//鼠标按下去拖动时调用
public void mouseDragged(MouseEvent e) {
System.out.println("鼠标按下去时拖动时调用");
int x = e.getX();//获取鼠标的x
int y = e.getY();
heroX = x-(heroImage.getIconWidth()/2); //把鼠标的x赋值给英雄机
heroY = y-(heroImage.getIconHeight()/2);
if(x+heroImage.getIconWidth() > GameMain.width) {
heroX = GameMain.width - heroImage.getIconWidth() - 20;
}
if(y+heroImage.getIconHeight() > GameMain.height) {
heroY = GameMain.height - heroImage.getIconHeight() - 20;
}
repaint();//x发生变化后需要重新绘制
}
//鼠标移动时调用
public void mouseMoved(MouseEvent e) {
System.out.println("鼠标放上去时调用");
int x = e.getX();//获取鼠标的x值
int y = e.getY();//获取鼠标的y值
heroX = x-(heroImage.getIconWidth()/2); //把鼠标的x赋值给英雄机
heroY = y-(heroImage.getIconHeight()/2);//把鼠标的y赋值给英雄机
if(x+heroImage.getIconWidth() > GameMain.width) {
heroX = GameMain.width - heroImage.getIconWidth() - 20;
}
if(y+heroImage.getIconHeight() > GameMain.height) {
heroY = GameMain.height - heroImage.getIconHeight() - 20;
}
repaint();//x发生变化后需要重新绘制
}
//碰撞方法
public boolean isHit(Enemy e, Bullet b) {
//指定一个区域
Rectangle rect = new Rectangle(e.getX(), e.getY(), e.getWidth(), e.getHeight());
//表示(x,y)坐标空间中的位置的点
Point p = new Point(b.getX()+b.getWidth()/2, b.getY()+b.getHeight());
return rect.contains(p);
}
//重写paint方法,做绘制图片使用
public void paint(Graphics g) {
super.paint(g);
g.setFont(new Font("", Color.RED.getRed(), 30));
g.drawString("得分"+number, 20, 30);
//1.绘制英雄机
g.drawImage(heroImage.getImage(), heroX, heroY, null);
//2.绘制敌机
for(int i=0; i<enemys.size(); i++) {
Enemy enemy = enemys.get(i);
enemy.drawImage(g);//重新绘制
}
//3.绘制子弹
for(int i=0; i<bullets.size(); i++) {
Bullet bullet = bullets.get(i);
bullet.drawImage(g);
}
//4.绘制爆炸图片
for(int i=0; i<bombs.size(); i++) {
Bomb bomb = bombs.get(i);
bomb.drawImage(g);
}
}
/*
* init这个方法做初始化方法使用
* 创建一些组件(英雄机,子弹,敌人)
* */
public void init() {
int flag = 0;
while(true) {
flag++;
//每循环20次创建一个子弹
if(flag % 15 == 0) {
//创建一些子弹
Bullet bullet = new Bullet(heroX+heroImage.getIconWidth()/2, heroY);
//把子弹添加到集合中
bullets.add(bullet);
}
//让敌机往下移动
for(int i=0; i<enemys.size(); i++) {
Enemy enemy = enemys.get(i);
enemy.move();//改变敌机的y值
//判断敌机的y值是否大于整个窗口的高度
if(enemy.getY() > GameMain.height){
//删除敌机
enemys.remove(enemy);
//再添加一个新的敌机
enemys.add(new Enemy());
}
}
//让子弹飞起来
for(int i=0; i<bullets.size(); i++){
Bullet tempBullet = bullets.get(i);
tempBullet.move();
}
System.out.println("子弹数量:"+bullets.size());
//删除越界的子弹
for(int i = 0; i<bullets.size(); i++) {
Bullet bullet = bullets.get(i);
if(bullet.getY() < 0) {
//y轴小于零说明越界了
bullets.remove(bullet);
}
}
//处理子弹碰撞到敌机的效果
for(int i=0; i<enemys.size(); i++) {
Enemy enemy = enemys.get(i);//敌机
for(int j=0; j<bullets.size(); j++) {
Bullet bullet = bullets.get(j);//得到子弹
if(isHit(enemy, bullet)){
//先删除敌机
enemys.remove(enemy);//先删除击中的敌机
enemys.add(new Enemy());//再添加一个新的敌机
bullets.remove(bullet);//删除子弹
//创建一个爆炸图片的对象
Bomb bomb = new Bomb(enemy.getX(), enemy.getY());
bombs.add(bomb);//添加到集合中
number+=10;//每次碰撞加10分
}
}
}
//删除爆炸的图片
for(int i=0; i<bombs.size(); i++) {
Bomb bomb = bombs.get(i);
bomb.move();
if(bomb.getCount()>5) {
bombs.remove(bomb);
}
}
try {
Thread.sleep(5);
} catch (Exception e) {
e.printStackTrace();
}
repaint();
}
}
}
③敌机类–Enemy类
package FlyV4B;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.ImageIcon;
/*
* 敌人对象
*
* */
public class Enemy {
private int width;//敌人图片的宽度
private int height;//敌人图片的高度
//敌人的坐标
private int x;
private int y;
//
private ImageIcon enemyImageIcon = new ImageIcon("image/enemy.png");
public Enemy() {
this.width = enemyImageIcon.getIconWidth();
this.height = enemyImageIcon.getIconHeight();
//设置敌机的位置
Random random = new Random();
random.nextInt(10);
this.x = random.nextInt(GameMain.width - (width/2));
this.y = -random.nextInt(GameMain.height - (height/2));
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void move() {
this.y += 1; //速度
}
public void drawImage(Graphics g){
g.drawImage(enemyImageIcon.getImage(), x, y, null);
}
}
④子弹类–Bullet类
package FlyV4B;
import java.awt.Graphics;
import javax.swing.ImageIcon;
/*
* 子弹对象
* */
public class Bullet {
private int x;
private int y;
private int width;
private int height;
private ImageIcon bulletImageIcon = new ImageIcon("image/bullet.png");
public Bullet(int x, int y) {
this.x = x;
this.y = y;
this.width = bulletImageIcon.getIconWidth();
this.height = bulletImageIcon.getIconHeight();
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public ImageIcon getBulletImageIcon() {
return bulletImageIcon;
}
public void setBulletImageIcon(ImageIcon bulletImageIcon) {
this.bulletImageIcon = bulletImageIcon;
}
public void move() {
this.y -= 4;
}
public void drawImage(Graphics g) {
g.drawImage(bulletImageIcon.getImage(), x, y, null);
}
}
⑤爆炸图效果类–Bomb类
package FlyV4B;
import java.awt.Graphics;
import javax.swing.ImageIcon;
public class Bomb {
private int x;
private int y;
private int width;
private int height;
private ImageIcon bombimg = new ImageIcon("image/bomb.png");
private int count;//删除的次数
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public Bomb(int x, int y) {
this.x = x;
this.y = y;
this.width = bombimg.getIconWidth();
this.height = bombimg.getIconHeight();
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public ImageIcon getBombimg() {
return bombimg;
}
public void setBombimg(ImageIcon bombimg) {
this.bombimg = bombimg;
}
public void drawImage(Graphics g) {
g.drawImage(bombimg.getImage(), x, y, null);
}
public void move() {
count++;
}
}