飞机大战 (递归版)

Posted indefinite

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了飞机大战 (递归版)相关的知识,希望对你有一定的参考价值。

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;
     

 

以上是关于飞机大战 (递归版)的主要内容,如果未能解决你的问题,请参考以下文章

Python版飞机大战

豪华版飞机大战系列

Html5版飞机大战游戏中(Boss战)制作

Java练手小项目飞机大战2.0加强版

飞机大战的操作指南

求一款飞机大战游戏(很经典)