展示图:
玩家
public class PlayerOne extends Plane{
public PlayerOne(String image, int x, int y, Panel panel, String upImg, String leftImg, String rightImg, String downImg) {
super(image, x, y, panel, upImg, leftImg, rightImg, downImg);
}
//添加键盘响应事件
public void keyPressed(KeyEvent e){
int key=e.getKeyCode();
switch (key){
case KeyEvent.VK_W:
upWard();
break;
case KeyEvent.VK_A:
leftWard();
break;
case KeyEvent.VK_D:
rightWard();
break;
case KeyEvent.VK_S:
downWard();
break;
case KeyEvent.VK_SPACE:
attack();
break;
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
switch (key) {
case KeyEvent.VK_W:
upWard();
break;
case KeyEvent.VK_A:
leftWard();
break;
case KeyEvent.VK_D:
rightWard();
break;
case KeyEvent.VK_S:
downWard();
break;
case KeyEvent.VK_SPACE:
attack();
break;
}
}
@Override
public void paintSelf(Graphics g) {
g.drawImage(image,x,y,null);
}
@Override
public Rectangle getRec() {
return new Rectangle(x,y,width,height);
}
}
方向
public enum Direction {
UP,LEFT,RIGHT,DOWN;
}
敌人
public class Enemy extends Plane {
//定义一个moveCount变量,方便定义随机方向
int moveCount=0;
public Enemy(String image, int x, int y, Panel panel, String upImg, String leftImg, String rightImg, String downImg) {
super(image, x, y, panel, upImg, leftImg, rightImg, downImg);
}
// //定义一个随机方向的方法(但是敌方飞机的方向只能是向下的)
public Direction getRandom(){
Random random=new Random();
int rNum=random.nextInt(4);
switch (rNum){
case 0:
return Direction.DOWN;
case 1:
return Direction.LEFT;
case 2:
return Direction.RIGHT;
case 3:
return Direction.UP;
default:
return null;
}
}
public void move(){
attack();
if (moveCount>=20){
direction=getRandom();
moveCount=0;
}else {
moveCount++;
}
switch (direction){
case LEFT:
leftWard();
break;
case RIGHT:
rightWard();
break;
}
}
public void attack(){
Point point=getEnemyHeadOne();
Point point2 = getEnemyHeadTwo();
Random r = new Random();
int rNum = r.nextInt(300);
if (rNum < 2) {//攻击频率
this.panel.bulletList.add(new EnemyBullet("src/main/resources/images/bullet_02.png", point.x, point.y, this.panel, direction));
this.panel.bulletList.add(new EnemyBullet("src/main/resources/images/bullet_02.png", point2.x, point2.y, this.panel, direction));
}
}
@Override
public void paintSelf(Graphics g) {
g.drawImage(image,x,y,null);
this.move();
}
@Override
public Rectangle getRec() {
return new Rectangle(x,y,width,height);
}
}
子弹
public class Bullet extends Object{
//尺寸
int width=10;
int height=10;
//速度
int speed=5;
//初始化方向
public Direction direction;
public Bullet(String image, int x, int y, Panel panel,Direction direction) {
super(image, x, y, panel);
this.direction=direction;
}
//玩家子弹向上移动
public void upWard(){
this.y-=speed;
}
public void downWard(){
this.y-=speed;
}
public void leftWard(){
this.y-=speed;
}
public void rightWard(){
this.y-=speed;
}
//子弹朝某个方向移动
public void go() {
switch (direction) {
case UP:
upWard();
break;
case DOWN:
downWard();
break;
case LEFT:
leftWard();
break;
case RIGHT:
rightWard();
break;
}
this.moveToBorder(x,y);
}
//玩家子弹与敌方飞机的碰撞检测
public void hitEnemy(){
//敌方飞机列表
ArrayList<Enemy> enemyList=this.panel.enemyList;
for (Enemy enemy : enemyList) {
if (this.getRec().intersects(enemy.getRec())){
//添加动态血条
this.panel.blastTwoList.add(new BlastTwo("",enemy.x,enemy.y,this.panel));
//添加爆炸的画面
this.panel.blastList.add(new Blast("",enemy.x,enemy.y,this.panel));
//添加毁灭音效
String musicPath="src/main/resources/sounds/Break.wav";
MusicPlay musicPlay=new MusicPlay();
musicPlay.playMusic(musicPath);
//删除子弹和敌方飞机
this.panel.enemyList.remove(enemy);
this.panel.bulletRemoveList.add(this);
enemy.alive=false;
break;
}
}
}
//判断子弹是否出界
public void moveToBorder(int x,int y){
if (y<0||y+height>this.panel.getHeight()) {
this.panel.bulletRemoveList.add(this);
}else if (x<0||x+width>this.panel.getWidth()){
this.panel.bulletRemoveList.add(this);
}
}
//敌方子弹向下移动
public void enemyLeftWard(){
this.y+=speed;
}
public void enemyRightWard(){
this.y+=speed;
}
public void enemyUpWard(){
this.y+=speed;
}
public void enemyDownWard(){
this.y+=speed;
}
public void go2(){
switch (direction){
case UP:
enemyUpWard();
break;
case DOWN:
enemyDownWard();
break;
case LEFT:
enemyLeftWard();
break;
case RIGHT:
enemyRightWard();
break;
}
this.moveToBorder(x,y);
}
@Override
public void paintSelf(Graphics g) {
g.drawImage(image,x,y,null);
this.go();
this.hitEnemy();
}
@Override
public Rectangle getRec() {
return new Rectangle(x,y,width,height);
}
}
敌人子弹
public class EnemyBullet extends Bullet{
public EnemyBullet(String image, int x, int y, Panel panel, Direction direction) {
super(image, x, y, panel, direction);
}
//敌方子弹与我方飞机的碰撞检测
public void hitPlayer() {
//玩家列表
ArrayList<Plane> playerList = this.panel.playerList;
for (Plane player : playerList) {
if (this.getRec().intersects(player.getRec())) {
//添加动态血条
this.panel.blastTwoList.add(new BlastTwo("",player.x,player.y,this.panel));
//添加爆炸的画面
this.panel.blastList.add(new Blast("",player.x,player.y,this.panel));
//添加爆炸音效
String musicPath="src/main/resources/sounds/Break.wav";
MusicPlay musicPlay=new MusicPlay();
musicPlay.playMusic(musicPath);
//删除子弹和玩家飞机
this.panel.playerList.remove(player);
this.panel.bulletRemoveList.add(this);
player.alive=false;
break;
}
}
}
@Override
public void paintSelf(Graphics g) {
g.drawImage(image,x,y,null);
this.go2();
this.hitPlayer();
}
@Override
public Rectangle getRec() {
return new Rectangle(x,y,width,height);
}
}
爆炸
public class Blast extends Object {
static Image[] images=new Image[8];
//爆炸的次数
int explodeCount=0;
static {
for (int i = 0; i <8 ; i++) {
images[i]=Toolkit.getDefaultToolkit().getImage("src/main/resources/images/blast"+(i+1)+".gif");
}
}
public Blast(String image, int x, int y, Panel panel) {
super(image, x, y, panel);
}
@Override
public void paintSelf(Graphics g) {
if (explodeCount<8) {
g.drawImage(images[explodeCount],x,y,null);
explodeCount++;
}
}
@Override
public Rectangle getRec() {
return null;
}
}
地形
public class BackGround extends Object {
public BackGround(String image, int x, int y, Panel panel) {
super(image, x, y, panel);
}
@Override
public void paintSelf(Graphics g) {
g.drawImage(image,x,y,null);
}
@Override
public Rectangle getRec() {
return new Rectangle(x,y,0,0);
}
}
抽象类
public abstract class Object {
//图片
public Image image;
//坐标
int x;
int y;
//界面
public Panel panel;
public Object(String image,int x, int y, Panel panel) {
this.image=Toolkit.getDefaultToolkit().getImage(image);
this.x = x;
this.y = y;
this.panel = panel;
}
public abstract void paintSelf(Graphics g);
public abstract Rectangle getRec();
}
飞机抽象类
public abstract class Plane extends Object{
//尺寸
int width=40;
int height=50;
//速度
int speed=7;
//初始化方向
public Direction direction=Direction.UP;
//飞机生命状态
Boolean alive=false;
//攻击冷却状态
Boolean attackCoolDownDate=true;
//攻击的冷却时间
int attackCoolDownTime=300;
//方向的图片
String upImg;
String leftImg;
String rightImg;
String downImg;
public Plane(String image, int x, int y, Panel panel, String upImg, String leftImg, String rightImg, String downImg) {
super(image, x, y, panel);
this.upImg = upImg;
this.leftImg = leftImg;
this.rightImg = rightImg;
this.downImg = downImg;
}
//坦克移动
public void upWard(){
direction=Direction.UP;
setImg(upImg);
if (!moveToBorder(x,y-speed)) {
this.y -= speed;
}
}
public void leftWard(){
direction=Direction.LEFT;
setImg(leftImg);
if (!moveToBorder(x-speed,y)) {
this.x -= speed;
}
}
public void rightWard(){
direction=Direction.RIGHT;
setImg(rightImg);
if (!moveToBorder(x+speed,y)) {
this.x += speed;
}
}
public void downWard(){
direction=Direction.DOWN;
setImg(downImg);
if (!moveToBorder(x,y+speed)) {
this.y += speed;
}
}
//定义设置图片和获取图片的方法
public void setImg(String img){this.image=Toolkit.getDefaultToolkit().getImage(img);}
//获取飞机的左右两个发射头
public Point getHeadOne(){
switch (direction){
case UP:
return new Point(x-15,y);
case LEFT:
return new Point(x-15,y);
case RIGHT:
return new Point(x-15,y);
case DOWN:
return new Point(x-15,y);
}
return null;
}
public Point getHeadTwo(){
switch (direction){
case UP:
return new Point(x+width+40,y);
case LEFT:
return new Point(x+width+40,y);
case RIGHT:
return new Point(x+width+40,y);
case DOWN:
return new Point(x+width+40,y);
}
return null;
}
public Point getEnemyHeadOne(){
switch (direction){
case UP:
return new Point(x+width+35,y+20);
case LEFT:
return new Point(x+width+35,y+20);
case RIGHT:
return new Point(x+width+35,y+20);
case DOWN:
return new Point(x+width+35,y+20);
}
return null;
}
public Point getEnemyHeadTwo(){
switch (direction){
case UP:
return new Point (x,y+20);
case LEFT:
return new Point (x,y+20);
case RIGHT:
return new Point (x,y+20);
case DOWN:
return new Point (x,y+20);
}
return null;
}
public void attack(){
if (attackCoolDownDate&&alive) {
Point pointOne = getHeadOne();
Bullet bullet1 = new Bullet("src/main/resources/images/red_bullet_goods.png", pointOne.x, pointOne.y, this.panel, direction);
this.panel.bulletList.add(bullet1);
Point pointTwo=getHeadTwo();
Bullet bullet2 = new Bullet("src/main/resources/images/red_bullet_goods.png", pointTwo.x, pointTwo.y, this.panel, direction);
this.panel.bulletList.add(bullet2);
String musicPath="src/main/resources/sounds/ClickSound.wav";
MusicPlay musicPlay=new MusicPlay();
musicPlay.playMusic(musicPath);
new AttackCD().start();
}
}
public void attack2(){
if (attackCoolDownDate&&alive) {
Point pointOne = getHeadOne();
Bullet bullet1 = new Bullet("src/main/resources/images/bullet_02.png", pointOne.x, pointOne.y, this.panel, direction);
this.panel.bulletList.add(bullet1);
Point pointTwo=getHeadTwo();
Bullet bullet2 = new Bullet("src/main/resources/images/bullet_02.png", pointTwo.x, pointTwo.y, this.panel, direction);
this.panel.bulletList.add(bullet2);
String musicPath="src/main/resources/sounds/ClickSound.wav";
MusicPlay musicPlay=new MusicPlay();
musicPlay.playMusic(musicPath);
new AttackCD().start();
}
}
//新建一个线程执行任务
class AttackCD extends Thread{
@Override
public void run() {
attackCoolDownDate=false;
try {
Thread.sleep(attackCoolDownTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
attackCoolDownDate=true;
this.stop();
}
}
//添加飞机与边界的碰撞检测
public Boolean moveToBorder(int x,int y){
if (x<0||x+width+100>this.panel.getWidth()){
return true;
}else if (y<0||y+height+70>this.panel.getHeight()){
return true;
}
return false;
}
@Override
public abstract void paintSelf(Graphics g);
@Override
public abstract Rectangle getRec();
}
模型
public class Model extends Object{
public Model(String image, int x, int y, Panel panel) {
super(image, x, y, panel);
}
@Override
public void paintSelf(Graphics g) {
g.drawImage(image,x,y,null);
}
@Override
public Rectangle getRec() {
return new Rectangle(x,y,0,0);
}
}
面板
public class Panel extends JFrame {
//双缓存图片解决闪动问题
Image offScreenImg=null;
//定义窗口尺寸
int width=500;
int height=770;
//定义num变量,方便选择模式
int num=0;
//定义a 变量,方便给num赋值
int a=1;
//指针图片
Image pointer=Toolkit.getDefaultToolkit().getImage("src/main/resources/images/bullet_02.png");
//定义一个纵坐标,方便切换模式
int y=170;
//玩家一:
PlayerOne p1=new PlayerOne("src/main/resources/images/Plane03.png",50,600,this,"src/main/resources/images/Plane03.png","src/main/resources/images/Plane03.png","src/main/resources/images/Plane03.png","src/main/resources/images/Plane03.png");
//玩家二:
PlayerTwo p2=new PlayerTwo("src/main/resources/images/Plane02.png",320,600,this,"src/main/resources/images/Plane02.png","src/main/resources/images/Plane03.png","src/main/resources/images/Plane03.png","src/main/resources/images/Plane03.png");
//敌方坦克的数量
int enemyCount=0;
//重绘的次数
int count=0;
//添加游戏元素
ArrayList<Model> modelList=new ArrayList<Model>();
ArrayList<Plane> playerList=new ArrayList<Plane>();
ArrayList<BackGround> backGroundList=new ArrayList<BackGround>();
ArrayList<Bullet> bulletList=new ArrayList<Bullet>();
ArrayList<Enemy> enemyList=new ArrayList<Enemy>();
ArrayList<Bullet> bulletRemoveList=new ArrayList<Bullet>();
ArrayList<Blast> blastList=new ArrayList<Blast>();
ArrayList<BlastTwo> blastTwoList=new ArrayList<BlastTwo>();
//定义窗口启动的方法
public void windowStart(){
//设置标题
setTitle(" 飞机大战 ");
//设置尺寸
setSize(width,height);
//设置默认关闭操作
setDefaultCloseOperation(3);
//设置用户不能调整窗口大小
setResizable(false);
//设置窗口居中
setLocationRelativeTo(null);
//设置窗口可见
setVisible(true);
//添加键盘响应
this.addKeyListener(new Panel.KeyMonitor());
//界面添加声音
String musicPath="src/main/resources/sounds/start.wav";
MusicPlay musicPlay=new MusicPlay();
musicPlay.playMusic(musicPath);
//添加模式集合
modelList.add(new Model("src/main/resources/images/backgroundAlbee.jpg",10,0,this));
modelList.add(new Model("src/main/resources/images/SinglePlayer.gif",170,180,this));
modelList.add(new Model("src/main/resources/images/DoublePlayer.gif",170,240,this));
//添加背景集合
backGroundList.add(new BackGround("src/main/resources/images/mapback.png",0,0,this));
//重绘
while (true){
//判定游戏胜利
if (enemyList.size()==0&&enemyCount==15){
num=5;
}
//判定游戏失败
if (playerList.size()==0&&(num==1||num==2)){
num=4;
}
if (count%100==1&&enemyCount<15&&(num==1||num==2)){
//随机位置
Random random=new Random();
int randomPosition=random.nextInt(400);
enemyList.add(new Enemy("src/main/resources/images/bullet01.png",randomPosition,80,this,"src/main/resources/images/bullet01.png","src/main/resources/images/bullet01.png","src/main/resources/images/bullet01.png","src/main/resources/images/bullet01.png"));
enemyCount++;
}
repaint();
try {
Thread.sleep(15);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//paint()进行描绘 可以添加图片和文字
@Override
public void paint(Graphics g){
if (offScreenImg==null){
offScreenImg=this.createImage(width,height);
}
Graphics gImg=offScreenImg.getGraphics();
gImg.setColor(Color.gray);
//描绘实心举行
gImg.fillRect(0,0,width,height);
if (num==0) {
//添加游戏界面
for (Model model : modelList) {
model.paintSelf(gImg);
}
gImg.setFont(new Font("仿宋", Font.BOLD, 50));
gImg.setColor(Color.YELLOW);
gImg.drawString("开始游戏", 150, 150);
//添加指针
gImg.drawImage(pointer,120,y,null);
}else if (num==1||num==2){
for (BackGround backGround : backGroundList) {
backGround.paintSelf(gImg);
}
for (Plane player : playerList) {
player.paintSelf(gImg);
}
for (Enemy enemy : enemyList) {
enemy.paintSelf(gImg);
}
for (Bullet bullet : bulletList) {
bullet.paintSelf(gImg);
}
bulletList.removeAll(bulletRemoveList);
for (BlastTwo blastTwo : blastTwoList) {
blastTwo.paintSelf(gImg);
}
for (Blast blast : blastList) {
blast.paintSelf(gImg);
}
gImg.setFont(new Font("仿宋",Font.BOLD,30));
gImg.setColor(Color.red);
gImg.drawString("剩余敌人:"+enemyList.size(),20,70);
//坦克重绘的次数
count++;
}else if (num==3){
for (int i = 0; i <2 ; i++) {
gImg.drawImage(Toolkit.getDefaultToolkit().getImage("src/main/resources/images/background.png"),i*10,0,Color.CYAN,null);
}
gImg.setFont(new Font("仿宋",Font.BOLD,50));
gImg.setColor(Color.red);
gImg.drawString("游戏暂停",140,260);
}else if (num==4){
for (int i = 0; i <2 ; i++) {
gImg.drawImage(Toolkit.getDefaultToolkit().getImage("src/main/resources/images/background.png"),i*10,0,Color.CYAN,null);
}
gImg.setFont(new Font("仿宋",Font.BOLD,50));
gImg.setColor(Color.red);
gImg.drawString("游戏失败",140,260);
bulletList.removeAll(bulletRemoveList);
}else if (num==5){
for (int i = 0; i <2 ; i++) {
gImg.drawImage(Toolkit.getDefaultToolkit().getImage("src/main/resources/images/background.png"),i*10,0,Color.CYAN,null);
}
gImg.setFont(new Font("仿宋",Font.BOLD,50));
gImg.setColor(Color.red);
gImg.drawString("游戏胜利",140,260);
bulletList.removeAll(bulletRemoveList);
}
g.drawImage(offScreenImg,0,0,null);
}
//添加键盘响应事件
class KeyMonitor extends KeyAdapter{
@Override
public void keyPressed(KeyEvent e){
int key=e.getKeyCode();
switch (key){
case KeyEvent.VK_1:
a=1;
y=170;
break;
case KeyEvent.VK_2:
a=2;
y=230;
break;
case KeyEvent.VK_ENTER:
num=a;
playerList.add(p1);
p1.alive=true;
if (num==2){
playerList.add(p2);
p2.alive=true;
}
break;
case KeyEvent.VK_P:
if (num!=3){
a=num;
num=3;
}else {
num=a;
if (a==0){
a=1;
}
}
break;
default:
p1.keyPressed(e);
p2.keyPressed(e);
}
}
@Override
public void keyReleased(KeyEvent e){
p1.keyReleased(e);
p2.keyReleased(e);
}
}
启动
public class Controller{
public static void main(String[] args) {
Panel panel=new Panel();
panel.windowStart();
}
}