飞机大战 (递归版)
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; public class Fight extends JPanel { public static final int H= 1000; public static final int W=(int)(1.618*H); public static BufferedImage beeImg; public static BufferedImage devilImg; public static BufferedImage bossImg; public static BufferedImage bulletImg; public static BufferedImage hero0Img; public static BufferedImage hero1Img; public static BufferedImage startImg; public static BufferedImage stopImg; public static BufferedImage dieImg; static { try{ devilImg =ImageIO.read(Fight.class.getResourceAsStream("Image/devil.jpg")); bossImg =ImageIO.read(Fight.class.getResourceAsStream("Image/boss.jpg")); bulletImg =ImageIO.read(Fight.class.getResourceAsStream("Image/bullet.jpg")); beeImg =ImageIO.read(Fight.class.getResourceAsStream("Image/bee.png")); hero0Img =ImageIO.read(Fight.class.getResourceAsStream("Image/hero0.png")); hero1Img =ImageIO.read(Fight.class.getResourceAsStream("Image/hero1.png")); startImg =ImageIO.read(Fight.class.getResourceAsStream("Image/start.jpg")); stopImg =ImageIO.read(Fight.class.getResourceAsStream("Image/stop.jpg")); dieImg =ImageIO.read(Fight.class.getResourceAsStream("Image/die.jpg")); } catch (IOException e){ e.printStackTrace(); } } int scroe=0; int state=0; // 0开始界面, 1暂停, 2运行游戏 int level=1; // 等级 Flies hero; // 英雄 + 子弹 Flies boss; // boss + 敌机 Flies beeK; // 蜂王 + 工蜂 Fight(){ new FightThread().start();//启动线程 this.addMouseMotionListener(l); this.addMouseListener(l); } MouseAdapter l=new MouseAdapter() { @Override public void mouseClicked(MouseEvent e){ if(state==0 || hero.life==0 ) { state=2; hero =new Flies(W/2-32, H-64, 128, 128, 0, 0, -1, 1, 1, 0, 10); boss =new Flies(-1 , 0, 128, 128, 0, 0, 1, 1, 1, 0, 30); beeK =new Flies(-1 , 0, 128, 128, 0, 0, 1, 1, 1, 0, 50); beeK.vis=boss.vis=false; scroe=100; } } public void mouseMoved(MouseEvent e) { if(state==2){ hero.x=e.getX()- hero.w/2; hero.y=e.getY()- hero.h/2; } } @Override public void mouseEntered(MouseEvent e) { if(state==1) state=2; } @Override public void mouseExited(MouseEvent e) { if(state==2) state=1; } }; public void paint(Graphics g){ super.paint(g); if(state==0){ g.drawImage(startImg, 0,0,W,H, null); paintStr(g, "Play", Color.gray, 40, 60, H/2+30); } else if(state==1) { g.drawImage(stopImg, 0,0,W,H, null); paintStr(g, "暂停", Color.gray, 40, W-140, H/2); } else if(state==2){ paintStr(g, "得分:"+scroe, Color.black, 20, 5, H-20); paintStr(g, "life:"+hero.life, Color.black, 20, W-150, H-20); if(boss.vis) paintStr(g, "Bosslife:"+boss.life, Color.gray, 20, 10, 20); if(hero.life==0){ g.drawImage(dieImg, 0,0,W,H, null); paintStr(g, "HEROES NEVER DIE", Color.black, 60, 0,300); paintStr(g, "Click replay", Color.black, 60, 230, 350); } else { paintFlies(g, hero, hero0Img, bulletImg); paintFlies(g, boss, bossImg, devilImg); paintFlies(g, beeK, beeImg, beeImg); } }else if(state==3){ paintStr(g, "Win", Color.red, 100, W/2-80, H/2); } } public void paintStr(Graphics g, String str, Color col, int siz, int x, int y){ Font font=new Font("宋体", Font.BOLD , siz); g.setFont(font); g.setColor(col); g.drawString(str, x, y); } //递归输出 public void paintFlies(Graphics g, Flies x, BufferedImage FatherImg, BufferedImage SonImg){ if(x.vis && x.life>0){ if(x.depth==0) g.drawImage(SonImg , x.x, x.y, x.w, x.h, null); else g.drawImage(FatherImg , x.x, x.y, x.w, x.h, null); } for(Flies y : x.SonList) paintFlies(g, y, FatherImg, SonImg); } class FightThread extends Thread{ public void run(){ while(true){ //改变坐标 if(state==2 && hero.life>0){ hero.Split(); boss.Split(); beeK.Split(); Shot(beeK, hero, 1); Shot(boss, hero, -1); if(level==28){ boss.vis=true; } if(boss.life<=0) state=3; } //重绘 repaint(); //休眠 try{ Thread.sleep(10); }catch(InterruptedException e){ e.printStackTrace(); } } } void Shot(Flies a, Flies b,int t){ //a与b是否碰撞 if(a.vis && b.vis && a.life>0 && b.life>0) if(a.x+a.w/2>=b.x && a.x+a.w/2<=b.x+b.w) if(a.y<=b.y+b.h && a.y >= b.y){ if(a.life>=b.life) { a.life=a.life-b.life; b.life=0; } else { b.life=b.life-a.life; a.life=0; } //题为标志变量,-1为杀死敌机,非-1为杀死工蜂 if(t==-1) { scroe++; if(scroe>=level*4 &&level<29) { boss.upgrade(++level); hero.upgrade(level); } } else { hero.Switch(); } } //b与a的孩子是否碰撞 for(Flies c : a.SonList) Shot(c, b, t); //a与b的孩子是否碰撞 for(Flies c : b.SonList) Shot(c, a, t); } } public static void main(String[] args) { JFrame jfr =new JFrame("打飞机"); jfr.setSize(W+15, H+38); Fight jpa=new Fight(); jfr.add(jpa); jfr.setAlwaysOnTop(true); jfr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jfr.setLocationRelativeTo(null); jfr.setVisible(true); } }
import java.util.ArrayList; import java.util.List; import java.util.Random; public class Flies{ protected boolean vis=true; // 是否可绘标志 protected boolean RandX=false; // 出生时 横坐标是否随机标志 protected int x, y, bornX; // 坐标 , bornX是出生是的x坐(为了按照给定的函数运动,初始点会参与计算) protected int w, h; // 大小 protected int Vx, Vy; // 横,纵坐标轴飞行速度 protected int dir; // 方向:向上或向下 protected int way=0; // 子弹运动方式 protected int time=0; // 计时器 // 根据等级改变的量 protected int life; // 生命 protected int breadth,depth;// Son广度 ,Son深度 protected int Tshot=30; // 如果有Son, 其生成时间间隔 protected List<Flies> SonList=new ArrayList<Flies>();; // Son表单 //构造函数初始化新生飞机 Flies(int x, int y, int w, int h, int Vx,int Vy, int dir, int depth,int breadth, int way, int Tshot){ Random rand=new Random(); if(x==-1) { this.x=rand.nextInt(Fight.W-10)+10; RandX=true; } else this.x=x; this.bornX=this.x; this.y=y; this.w=w; this.h=h; this.Vx=Vx; this.Vy=Vy; this.dir=dir; this.depth=depth; this.life=w*h; this.breadth=breadth; this.way = way; this.Tshot=Tshot; } void Split(){ int maxV=1000; //速度上限 time++; // 1.先运动。运动方式可以随心所欲,这里假设Vy受加速度为1,速度上限maxV y=y+Vy; x=x+Vx; if(depth==0 && Vy<=maxV && Vy>=-maxV) Vy=Vy+(Vy<0?-1:1); //2.判断是否出界,出界及死亡,然后删除生命值0且孙子飞行物个数为0 的子飞行物 if(vis && (y+h<0 || y>Fight.H)) life = 0; for(int i=0;i<SonList.size();i++) if(SonList.get(i).life==0 && SonList.get(i).SonList.size()==0) SonList.remove(i--); //3.生成子飞行物 if(time>=Tshot && life > 0 && depth > 0){ time=0; for(int i=1;i<=breadth;i++){ SonList.add(new Flies( RandX ? -1 : (x+w/2-w/8), y, //纵坐标固定 w/4, h/4, //假设子大小为父大小16分之一 Vx+(breadth/2-i+(breadth%2==1?1:(breadth/2>=i?1:0))), Vy+dir, dir, depth-1, breadth, way, Tshot )); } } //4.递归:子飞行物生成孙子飞行物 for(Flies x: SonList) if(x.life>0) x.Split(); } // 升级函数 void upgrade(int level){ life=life+1000; Tshot=30-level/2; depth=level/29+1; if(level==29) breadth=5; else breadth=level/5+1; } void Switch(){ way++; way=way%2; } // 横坐标运动函数 int fun(int way){ if(way==1) return (int)(Math.sin(3.14*2/(400/breadth)*y)*(breadth-1)*4)+Vx+x; return x+Vx; } }
相关文章