欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

飞机大战 (递归版)

程序员文章站 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;
     }
}