制作背景:学校组织的就业培训(其实有点像在推销他们的培训。。),要求做点东西出来,看看微信打飞机看上去蛮简单的,于是乎就模仿了。
Java代码,一年多以前写的,总有那么点缺陷,感觉不是怎么面向对象。
package com.raikou.practise.plane; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.io.File; import java.util.ArrayList; import java.util.List; import javax.swing.ImageIcon; import javax.swing.Timer; import javax.swing.JPanel; public class PlaneJPanel extends JPanel implements MouseMotionListener, MouseListener { /** * */ private static final long serialVersionUID = -3729222788769506535L; private int time = 0, timepre = 0; private List newenemys; private List newbullet; private List newPE; private List newS; private int px = 180, py = 450; //本机的坐标 private int boomnum = 0; private int doubleBulletstime = 0; private boolean isend = false; private boolean isstart = false; private boolean issuspend = false; private boolean isdoubleBullets = false; private int score = 0; private Timer timer, timer2, timerpre; private PlaySound BGM; private PlaySound BulletM; private PlaySound ButtonM; private PlaySound EDM1; private PlaySound EDM2; private PlaySound EDM3; private PlaySound GBM; private PlaySound GDLM; private PlaySound UBM; private int BGy = -252; private int BGx; private Image SI; private Image BGI; private Font font; public PlaneJPanel() { BGx = 150; // 创建计时器 timerpre = new Timer(1000, new TimerPre()); timer = new Timer(80, new TimerListener()); timer2 = new Timer(80, new Timercounter()); // 初始化各变量 newenemys = new ArrayList(); newbullet = new ArrayList(); newPE = new ArrayList(); newS = new ArrayList(); SI = new ImageIcon("./images/shoot.png").getImage(); BGI = new ImageIcon("./images/shoot_background.png").getImage(); font = new Font("黑体", Font.BOLD, 24); // 创建音乐线程 MusicInit(); // 添加监听 this.addMouseMotionListener(this); this.addMouseListener(this); // 开启游戏线程 startGame(); timerpre.start(); } public void paint(Graphics g) { super.paint(g); Graphics2D g2 = (Graphics2D) g; g2.setStroke(new BasicStroke(10)); g2.setColor(Color.BLACK); g2.setFont(font); // 背景图 g.drawImage(BGI, 0, BGy, 480, BGy + 852, 0, 75, 480, 927, null); g.drawImage(BGI, 0, BGy - 852, 480, BGy, 0, 75, 480, 927, null); // 欢迎页 if (!isstart) { g.drawImage(BGI, 22, getHeight() / 2 - 112, 456, getHeight() / 2 + 113, 484, 702, 918, 927, null); if (timepre % 3 == 0) g.drawImage(BGI, 151, getHeight() / 2 + 147, 200, getHeight() / 2 + 182, 0, 38, 49, 73, null); else if (timepre % 3 == 1) g.drawImage(BGI, 151, getHeight() / 2 + 147, 265, getHeight() / 2 + 182, 0, 0, 114, 35, null); else g.drawImage(BGI, 151, getHeight() / 2 + 147, 329, getHeight() / 2 + 182, 489, 666, 667, 701, null); // g.drawImage(BGW1, BGx, getHeight()/2+147, null); } else { timer.start(); timer2.start(); for (int i = 0; i < newbullet.size(); i++) { newbullet.get(i).drawBullet(g); } for (int i = 0; i < newenemys.size(); i++) { newenemys.get(i).drawEnemys(g); } for (int i = 0; i < newPE.size(); i++) { newPE.get(i).drawExplode(g); } for (int i = 0; i < newS.size(); i++) { newS.get(i).drawSupplies(g); } if (boomnum >= 0) { g.drawImage(SI, 10, 520, 71, 574, 812, 694, 872, 745, null); g2.drawString("X" + boomnum, 75, 560); } if (!isend) { g.drawImage(SI, px, py, px + 98, py + 124, 2, 100, 100, 224, null); } else g2.drawString("Game Over", getWidth() / 2 - 50, getHeight() / 2 - 10); if (!issuspend) g.drawImage(SI, 5, 0, 46, 41, 275, 252, 316, 293, null); else g.drawImage(SI, 5, 0, 46, 41, 819, 648, 860, 689, null); g2.drawString("" + score, 60, 30); } } public void startGame() { new Thread() { public void run() { try { sleep(100); } catch (InterruptedException e1) { // TODO 自动生成的 catch 块 e1.printStackTrace(); } while (true) { while (isstart && !isend && !issuspend) { BGy++; if (BGy >= 600) BGy = -252; // 判断子弹和敌机的撞击,机型1撞击次数1次,机型2撞击次数6次,机型3撞击次数12次,满次数后敌机爆炸 for (int i = 0; i < newbullet.size(); i++) { newbullet.get(i).startBullet(); if (newbullet.get(i).getBy() <= 0) newbullet.remove(i); else for (int j = 0; j < newenemys.size(); j++) { if (newenemys.get(j).getType() == 1) { if ((newbullet.get(i).getBy() - newenemys.get(j).getY() <= 36 && newbullet .get(i).getBy() - newenemys.get(j).getY() >= 0) && (newbullet.get(i).getBx() - newenemys.get(j) .getX() >= 0 && newbullet .get(i).getBx() - newenemys.get(j) .getX() <= 39)) { if (newenemys.get(j).getHit() > 0) { newenemys.get(j).setHit( newenemys.get(j) .getHit() - 1); } if (newenemys.get(j).getHit() == 0) { newPE.add(new PlaneExplode( newenemys.get(j).getX(), newenemys.get(j).getY(), newenemys.get(j) .getType())); score += newenemys.get(j) .getScore(); EDM1.Play(); newenemys.remove(j); } newbullet.remove(i); break; } } else if (newenemys.get(j).getType() == 2) { if ((newbullet.get(i).getBy() - newenemys.get(j).getY() <= 93 && newbullet .get(i).getBy() - newenemys.get(j).getY() >= 0) && (newbullet.get(i).getBx() - newenemys.get(j) .getX() >= 0 && newbullet .get(i).getBx() - newenemys.get(j) .getX() <= 59)) { if (newenemys.get(j).getHit() > 0) { newenemys.get(j).setHit( newenemys.get(j) .getHit() - 1); newenemys.get(j).setHited( !newenemys.get(j) .isHited()); } if (newenemys.get(j).getHit() == 0) { newPE.add(new PlaneExplode( newenemys.get(j).getX(), newenemys.get(j).getY(), newenemys.get(j) .getType())); score += newenemys.get(j) .getScore(); EDM2.Play(); newenemys.remove(j); } newbullet.remove(i); break; } } else { if ((newbullet.get(i).getBy() - newenemys.get(j).getY() <= 256 && newbullet .get(i).getBy() - newenemys.get(j).getY() >= 0) && (newbullet.get(i).getBx() - newenemys.get(j) .getX() >= 0 && newbullet .get(i).getBx() - newenemys.get(j) .getX() <= 146)) { if (newenemys.get(j).getHit() > 0) { newenemys.get(j).setHit( newenemys.get(j) .getHit() - 1); newenemys.get(j).setHited( !newenemys.get(j) .isHited()); } if (newenemys.get(j).getHit() == 0) { newPE.add(new PlaneExplode( newenemys.get(j).getX(), newenemys.get(j).getY(), newenemys.get(j) .getType())); score += newenemys.get(j) .getScore(); EDM3.Play(); newenemys.remove(j); } newbullet.remove(i); break; } } } } // 本机的爆炸效果 for (int i = 0; i < newenemys.size(); i++) { newenemys.get(i).startMoving(); if (newenemys.get(i).getY() >= 600) newenemys.remove(i); else { if (newenemys.get(i).getType() == 1) { if ((newenemys.get(i).getX() - px >= -28 && newenemys .get(i).getX() - px <= 48) && (py - newenemys.get(i).getY() <= 34 && py - newenemys.get(i).getY() >= -124)) { newPE.add(new PlaneExplode(px, py, 0)); isend = true; } } else if (newenemys.get(i).getType() == 2) { if ((newenemys.get(i).getX() - px >= -40 && newenemys .get(i).getX() - px <= 28) && (py - newenemys.get(i).getY() <= 93 && py - newenemys.get(i).getY() >= -124)) { newPE.add(new PlaneExplode(px, py, 0)); isend = true; } } else if (newenemys.get(i).getType() == 3) { if ((newenemys.get(i).getX() - px >= -90 && newenemys .get(i).getX() - px <= -68) && (py - newenemys.get(i).getY() <= 256 && py - newenemys.get(i).getY() >= -124)) { newPE.add(new PlaneExplode(px, py, 0)); isend = true; } } } } // 显示完爆炸效果后消失 for (int i = 0; i < newPE.size(); i++) { if (newPE.get(i).getTime() >= 6) newPE.remove(i); } // 控制补给品 for (int i = 0; i < newS.size(); i++) { newS.get(i).startMoving(); if ((newS.get(i).getX() - px >= -newS.get(i) .getWidth() + 10 && newS.get(i).getX() - px <= 88 + newS .get(i).getWidth()) && (py - newS.get(i).getY() <= newS.get(i).getHeight() && py - newS.get(i).getY() >= -102)) { if (newS.get(i).getType() == 1) { isdoubleBullets = true; doubleBulletstime = 50; GDLM.Play(); } else { GBM.Play(); boomnum++; } newS.remove(i); } } try { sleep(20); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } repaint(); } repaint(); } } }.start(); } public void setIsstart(boolean isstart) { this.isstart = isstart; } @Override public void mouseDragged(MouseEvent e) { // TODO 自动生成的方法存根 // 滑动开始 if (!isstart) { if ((e.getY() >= getHeight() / 2 + 147 && e.getY() <= getHeight() / 2 + 182) && (e.getX() >= 150 && e.getX() <= 285)) BGx = e.getX(); if (BGx >= 283) { isstart = true; issuspend = false; } } if (isstart) { px = e.getX() - 49; py = e.getY() - 62; repaint(); } } public void MusicInit() { BGM = new PlaySound(new File("./sound/game_music.mp3")); BulletM = new PlaySound(new File("./sound/bullet.mp3")); ButtonM = new PlaySound(new File("./sound/button.mp3")); EDM1 = new PlaySound(new File("./sound/enemy1_down.mp3")); EDM2 = new PlaySound(new File("./sound/enemy2_down.mp3")); EDM3 = new PlaySound(new File("./sound/enemy3_down.mp3")); GBM = new PlaySound(new File("./sound/get_bomb.mp3")); GDLM = new PlaySound(new File("./sound/get_double_laser.mp3")); UBM = new PlaySound(new File("./sound/use_bomb.mp3")); BGM.Play(); } @Override public void mouseMoved(MouseEvent e) { // TODO 自动生成的方法存根 } class Timercounter implements ActionListener { public void actionPerformed(ActionEvent e) { for (int i = 0; i < newPE.size(); i++) { newPE.get(i).setTime(newPE.get(i).getTime() + 1); } } } class TimerPre implements ActionListener { public void actionPerformed(ActionEvent e) { timepre++; } } class TimerListener implements ActionListener { public void actionPerformed(ActionEvent e) { time++; if (!isend && isstart && !issuspend) { if (!isdoubleBullets) { newbullet.add(new Bullet(px + 48, py, 1)); BulletM.Play(); } else { if (doubleBulletstime > 0) { newbullet.add(new Bullet(px + 33, py, 2)); newbullet.add(new Bullet(px + 63, py, 2)); BulletM.Play(); doubleBulletstime--; } else isdoubleBullets = false; } if (Math.random() > 0.9) { double typerandom = Math.random(); if (typerandom < 0.85) newenemys.add(new Enemys((int) (Math.random() * 380), -36, 1)); else if (typerandom < 0.99) newenemys.add(new Enemys((int) (Math.random() * 430),-93, 2)); else newenemys.add(new Enemys((int) (Math.random() * 285),-256, 3)); } if (time > 100 && Math.random() > 0.995) { double typerandom = Math.random(); if (typerandom < 0.7) newS.add(new Supplies((int) (Math.random() * 380), 25,1)); else newS.add(new Supplies((int) (Math.random() * 380), 25,2)); } } } } @Override public void mouseClicked(MouseEvent e) { // TODO 自动生成的方法存根 if ((e.getY() >= 0 && e.getY() <= 41)&& (e.getX() >= 5 && e.getX() <= 46)) { issuspend = !issuspend; ButtonM.Play(); } if (!issuspend) if ((e.getY() >= 520 && e.getY() <= 574) && (e.getX() >= 10 && e.getX() <= 80) && boomnum > 0) { UBM.Play(); for (int i = 0; i < newenemys.size(); i++) { newPE.add(new PlaneExplode(newenemys.get(i).getX(), newenemys.get(i).getY(), newenemys.get(i).getType())); score += newenemys.get(i).getScore(); } newenemys.removeAll(newenemys); } } @Override public void mousePressed(MouseEvent e) { // TODO 自动生成的方法存根 } @Override public void mouseReleased(MouseEvent e) { // TODO 自动生成的方法存根 } @Override public void mouseEntered(MouseEvent e) { // TODO 自动生成的方法存根 } @Override public void mouseExited(MouseEvent e) { // TODO 自动生成的方法存根 } }
敌机,子弹,补给品,和飞机爆炸效果4个类都放在集合里,个人感觉在这里用集合比数组方便,因为并不知道会有多少个元素,而且感觉打开程序的速度也有提升(后来加上音乐后又变慢了- -).计时器控制一下如敌机,补给品和子弹的出现频率,还有控制爆炸画面不能太快。敌机和补给品的出现率还有Math.Random()控制,可以根据时间或分数来调整概率。
敌机类(子弹类等类似)
package com.raikou.practise.plane; import java.awt.Graphics; import java.awt.Image; import javax.swing.ImageIcon; public class Enemys { private int y; private int x; private int type; private int score; private int hit; private boolean isHited = false; private Image enemyplane; public Enemys(int x, int y, int type) { super(); this.y = y; this.x = x; this.type = type; switch (type) { case 1: score = 1000; hit = 1; break; case 2: score = 6000; hit = 6; break; case 3: score = 30000; hit = 12; break; default: break; } enemyplane = new ImageIcon("./images/shoot.png").getImage(); } public int getHit() { return hit; } public void setHit(int hit) { this.hit = hit; } public void drawEnemys(Graphics g) { if (!isHited) { if (type == 1) g.drawImage(enemyplane, x, y, x + 49, y + 40, 539, 613, 588, 653, null); else if (type == 2) g.drawImage(enemyplane, x, y, x + 69, y + 93, 0, 0, 69, 93, null); else if (type == 3) g.drawImage(enemyplane, x, y, x + 165, y + 256, 338, 750, 503, 1006, null); } else { if (type == 1) g.drawImage(enemyplane, x, y, x + 49, y + 40, 539, 613, 588, 653, null); else if (type == 2) g.drawImage(enemyplane, x, y, x + 69, y + 93, 432, 529, 501, 622, null); else if (type == 3) g.drawImage(enemyplane, x, y, x + 165, y + 256, 165, 750, 330, 1006, null); } } public boolean isHited() { return isHited; } public void setHited(boolean isHited) { this.isHited = isHited; } public void startMoving() { if (type == 1) y += 4; else if (type == 2) y += 3; else y += 2; } public int getScore() { return score; } public int getType() { return type; } public int getY() { return y; } public int getX() { return x; } }
其实包括飞机,子弹之类的,可以抽象出个飞行类。
运行需要java7以上的版本
打包下载
http://yunpan.cn/QCBrHusDXyHpj 访问密码 80c7