飞机大战 (递归版)
程序员文章站
2024-01-20 17:42:52
Java入门篇,飞机大战 小游戏 ......
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; } }