JAVA GUI 植物大战僵尸

发布于:2024-05-16 ⋅ 阅读:(77) ⋅ 点赞:(0)

公众号:编程驿站

没有做太多封装。难免有冗余。源码全部放出,有兴趣者可以再改之。

1. pea 类

package com.hm;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**

 */
public class Pea {

    BufferedImage image;
    int x;
    int y;
    Rectangle rectangle;
    //宽度
    //高度
    int size;

    public Pea(int x, int y) throws IOException {
        this.image= ImageIO.read(new File("images/background/pea.png"));
        this.x=x;
        this.y=y;
        this.size=25;
        this.rectangle=new Rectangle(this.x,this.y,this.size,this.size);
    }

    public void draw(Graphics g){
        g.drawImage(this.image,this.x,this.y,this.size,this.size,null);
        this.rectangle=new Rectangle(this.x,this.y,this.size,this.size);
        this.x+=50;
    }
}

2. PeaShooter

package com.hm;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class PeaShooter {
    BufferedImage image;
    int x;
    int y;
    Rectangle rectangle;
    //预加载所有豌豆射手图片
    BufferedImage[] images=new BufferedImage[13];
    int index=0;
    int live=40;

    public PeaShooter(int x,int y) throws IOException {
        this.x=x;
        this.y=y;
        for (int i = 0; i <13 ; i++) {
            String code=i<9?"0"+(i+1):(i+1)+"";
            images[i]= ImageIO.read(new File("images/peashooter/PeaShooter_"+code+".png"));
        }
        this.image=images[index];
        this.rectangle=new Rectangle(this.x,this.y,this.image.getWidth(),this.image.getHeight());
    }

    public void draw(Graphics graphics){
        index=++index%13;//0 12
        this.image=images[index];
        this.rectangle=new Rectangle(this.x,this.y,this.image.getWidth(),this.image.getHeight());
       // graphics.drawRect(this.x,this.y,this.image.getWidth(),this.image.getHeight());
        graphics.drawImage(this.image,this.x,this.y,this.image.getWidth(),this.image.getHeight(),null);
    }
}

3. Sun

package com.hm;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * 自然光(随机)
 * 向日葵生产(与向日葵)
 */
public class Sun {

    BufferedImage image;
    int x;
    int y;
    Rectangle rectangle;
    //宽度
    //高度
    int size;
    //是否被鼠标点击
    int isMeetMouse=0;
    //x长度
    int xlength;
    //y
    int ylength;


    public Sun(int x,int y) throws IOException {
        this.image= ImageIO.read(new File("images/background/Sun.png"));
        this.x=x;
        this.y=y;
        this.size=60;
        this.rectangle=new Rectangle(this.x,this.y,this.size,this.size);
    }

    public void draw(Graphics g){
        this.rectangle=new Rectangle(this.x,this.y,this.size,this.size);
        g.drawImage(this.image,this.x,this.y,this.size,this.size,null);
    }
}

4. SunFlower

package com.hm;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class SunFlower {
    BufferedImage image;
    int x;
    int y;
    Rectangle rectangle;
    //预加载所有豌豆射手图片
    BufferedImage[] images=new BufferedImage[18];
    int index=0;
    //生命值
    int live=30;

    public SunFlower(int x, int y) throws IOException {
        this.x=x;
        this.y=y;
        for (int i = 0; i <18 ; i++) {
            String code=i<9?"0"+(i+1):(i+1)+"";
            images[i]= ImageIO.read(new File("images/SunFlower/SunFlower_"+code+".png"));
        }
        this.image=images[index];
        this.rectangle=new Rectangle(this.x,this.y,this.image.getWidth(),this.image.getHeight());
    }

    public void draw(Graphics graphics){
        index=++index%18;//0 12
        this.image=images[index];
        this.rectangle=new Rectangle(this.x,this.y,this.image.getWidth(),this.image.getHeight());
        //graphics.drawRect(this.x,this.y,this.image.getWidth(),this.image.getHeight());
        graphics.drawImage(this.image,this.x,this.y,this.image.getWidth(),this.image.getHeight(),null);
    }
}

5. Zombie

package com.hm;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class Zombie {
    BufferedImage image;
    int x;
    int y;
    Rectangle rectangle;
    //预加载所有豌豆射手图片
    BufferedImage[] walkImages = new BufferedImage[31];
    BufferedImage[] dieImages = new BufferedImage[10];
    BufferedImage[] headImages = new BufferedImage[10];
    //吃播图片
    BufferedImage[] eatImages = new BufferedImage[21];
    //索引号
    int index = 0;
    int index_ = 0;
    int indexEat = 0;

    //走 1 正在走,0停
    int run = 1;

    //生命值
    int live = 4;

    public Zombie(int x, int y) throws IOException {
        this.x = x;
        this.y = y;
        for (int i = 0; i < 31; i++) {
            String code = i < 9 ? "0" + (i + 1) : (i + 1) + "";
            walkImages[i] = ImageIO.read(new File("images/Zombie/Walk/Walk_" + code + ".png"));
        }
        for (int i = 0; i < 10; i++) {
            String code = i < 9 ? "0" + (i + 1) : (i + 1) + "";
            dieImages[i] = ImageIO.read(new File("images/Zombie/Die/Die_" + code + ".png"));
        }
        for (int i = 0; i < 10; i++) {
            String code = i < 9 ? "00" + (i + 1) : "0" + (i + 1);
            headImages[i] = ImageIO.read(new File("images/Zombie/Head/Head_" + code + ".png"));
        }
        for (int i = 0; i < 21; i++) {
            String code = i < 9 ? "0" + (i + 1) : (i + 1) + "";
            eatImages[i] = ImageIO.read(new File("images/Zombie/Eat/Eat_" + code + ".png"));
        }
        this.image = walkImages[index];
        this.rectangle = new Rectangle(this.x, this.y, this.image.getWidth(), this.image.getHeight());
    }

    public void draw(Graphics graphics) {
        if (this.live > 0) {
            if (this.run == 1) {
                index = ++index % 31;//0 30
                this.image = walkImages[index];
                this.x -= 5;
            } else {
                indexEat = ++indexEat % 21;//0 30
                this.image = eatImages[indexEat];
            }
        } else {
            index_ = ++index_ % 10;//0 30
            this.image = dieImages[index_];
            graphics.drawImage(this.headImages[index_], this.x, this.y, this.headImages[index_].getWidth() - 20, this.headImages[index_].getHeight() - 20, null);
        }
        this.rectangle = new Rectangle(this.x, this.y, this.image.getWidth() - 20, this.image.getHeight() - 20);
        //graphics.drawRect(this.x, this.y, this.image.getWidth()-20, this.image.getHeight()-20);
        graphics.drawImage(this.image, this.x, this.y, this.image.getWidth() - 20, this.image.getHeight() - 20, null);
    }
}

6. MainFrm

package com.hm;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Random;

/**
 * AudionClip sound_choose=Applet.newAdudioClip(sound1.toURL());
 */
public class MainFrm extends JFrame {

    //创建
    BackGround backGround = new BackGround();
    //太阳光数量卡片
    Card sunCountCard;
    //生产向日葵
    Card sunFlowerCard;
    //生产碗豆射手
    Card peaShooterCard;
    //阳光(自然光):定时随时创建
    Sun sun = null;
    //随机
    Random random = new Random();
    //定时器
    Timer timer;
    //阳光从天上移动目标Y
    int sunTargetY;
    //鼠标是否点击到阳光
    int sunMeetMouse = 0;
    //阳光离收集面板x方向长度
    int xlength;
    //阳光离收集面板y方向长度
    int ylength;
    Image offScreenImage = null;
    //阳光数量
    int sunCount = 500;
    //射手是否已经创建
    int isCreatePeaShooter = 0;
    //射手
    PeaShooter peaShooter;
    //是否种下来
    int isPeaFloor = 0;
    //子弹
    Pea pea;
    //容器(子弹)
    LinkedList<Pea> peas = new LinkedList();
    //容器(豌豆射手)
    LinkedList<PeaShooter> peaShooters = new LinkedList();
    //僵尸
    Zombie zombie;
    LinkedList<Zombie> zombies = new LinkedList();
    //一个箱子变量向日葵
    SunFlower sunFlower;
    //保存所有向日葵
    LinkedList<SunFlower> sunFlowers = new LinkedList<>();
    //是否已经存下
    int isSunFlowerDown = 0;

    //向日葵生产阳光
    Sun sun_;
    //容器,保存所有向口葵生产出来的阳光
    LinkedList<Sun> suns = new LinkedList<>();

    //开始
    BufferedImage startImage;

    int total = 50; //总量
    int total_ = total;
    int count = 0;
    //房子
    int isFail=0;
    //成功
    BufferedImage okImage;
    //失败
    BufferedImage noImage;

    public MainFrm() throws IOException {
        startImage = ImageIO.read(new File("images/background/start.jpg"));

        okImage = ImageIO.read(new File("images/background/trophy.png"));
        noImage = ImageIO.read(new File("images/background/ZombiesWon.png"));

        BufferedImage image = ImageIO.read(new File("images/card/plants/SunBank.png"));
        sunCountCard = new Card(image, 200, 40);
        sunCountCard.rectangle.setBounds(200, -10, 100, 100);

        image = ImageIO.read(new File("images/card/plants/SunFlower.png"));
        sunFlowerCard = new Card(image, 265, 40);

        image = ImageIO.read(new File("images/card/plants/Peashooter.png"));
        peaShooterCard = new Card(image, 325, 40);

        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        //大小
        this.setSize(1400, 600);
        //位置
        this.setLocation(200, 100);
        //标题
        this.setTitle("植物大战僵尸");
        //
        this.setResizable(false);

        //使用定时器
        timer = new Timer(100, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                if (sun == null) {
                    try {
                        //创建阳光(自然光)
                        createSun();
                        //定制一个目标点
                        sunTargetY = random.nextInt(300) + 100;

                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                } else {
                    //阳光存在让其移动
                    sunMove();
                }
                //创建子弹
                if (pea == null && peaShooters.size() != 0) {
                    try {
                        //根据武器数量调整生产子弹的频率
                        int wuCount = peaShooters.size();
                        int num_ = 5;
                        if (wuCount > 5) {
                            num_ = 1;
                        }
                        int randNum = random.nextInt(num_);//0~9
                        if (randNum == 0) { //1/5
                            int num = random.nextInt(peaShooters.size());//
                            //从武器库中根据随机数字得到武器
                            PeaShooter ps = peaShooters.get(num);
                            if (ps != peaShooter) {
                                //随机出来的武器不是正在移动的武器
                                pea = new Pea(ps.x + 80, ps.y);
                                //添加容器中
                                peas.addLast(pea);
                                pea = null;
                            }
                        }

                    } catch (Exception ioException) {
                        ioException.printStackTrace();
                    }
                }

                //向日葵生产阳光
                if (sun_ == null && sunFlowers.size() != 0) {
                    try {
                        //频率
                        int wuCount = sunFlowers.size();
                        int num_ = 20;
                        if (wuCount > 10) {
                            num_ = 10;
                        }
                        int randNum = random.nextInt(num_);//0~9
                        if (randNum == 0) { //1/5
                            int num = random.nextInt(sunFlowers.size());//
                            //根据随机数字得到太阳花
                            SunFlower ps = sunFlowers.get(num);
                            if (ps != sunFlower) {
                                sun_ = new Sun(ps.x, ps.y);
                                //添加容器中
                                suns.addLast(sun_);
                                sun_ = null;
                            }
                        }
                    } catch (Exception ioException) {
                        ioException.printStackTrace();
                    }
                }
                if (suns.size() != 0) {
                    sunMove_();
                }

                //生产僵尸
                if (zombie == null && count != total_) {
                    int jsNum = random.nextInt(30);
                    if (jsNum == 10) {
                        int y = random.nextInt(350) + 50;//0~9
                        try {
                            zombie = new Zombie(1300, y);
                            count++;
                            zombies.addLast(zombie);
                            zombie = null;

                        } catch (IOException ioException) {
                            ioException.printStackTrace();
                        }
                    }
                }
                peaIsMeetZombie();
                isZombieMeetSunFlowerOrPeaShooter();
                repaint();
            }
        });

        timer.start();
        //窗体接收鼠标点击
        this.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                if (peaShooter != null) {
                    if (isPeaFloor == 0) {
                        //没有种下时与鼠标一起移动
                        peaShooter.x = e.getX();
                        peaShooter.y = e.getY();
                    } else {
                        //种下之后恢复变量到初始状态
                        peaShooter = null;
                        isPeaFloor = 0;
                    }
                }
                if (sunFlower != null) {
                    if (isSunFlowerDown == 0) {
                        //没有种下时与鼠标一起移动
                        sunFlower.x = e.getX();
                        sunFlower.y = e.getY();
                    } else {
                        //种下之后恢复变量到初始状态
                        sunFlower = null;
                        isSunFlowerDown = 0;
                    }
                }
            }
        });
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                //鼠标坐标是否和阳光的坐标叠
                if (sunMeetMouse == 0 && sun != null) {
                    if (sun.rectangle.contains(e.getX(), e.getY())) {
                        sunMeetMouse = 1;
                        xlength = Math.abs(sun.x - 200);
                        ylength = Math.abs(sun.y - 40);
                    }
                }
                //检查鼠标是不是点击到了向日葵所生产的阳光
                if (suns.size() != 0) {
                    for (Sun s : suns) {
                        if (s.rectangle.contains(e.getX(), e.getY())) {
                            //有阳光碰到鼠标
                            s.isMeetMouse = 1;
                            s.xlength = Math.abs(s.x - 200);
                            s.ylength = Math.abs(s.y - 40);
                            break;
                        }
                    }
                }

                //种植武器
                if (peaShooter == null) {
                    if (peaShooterCard.rectangle.contains(e.getX(), e.getY())) {
                        if (sunCount >= 100) {
                            try {
                                //创建一个 武器
                                peaShooter = new PeaShooter(e.getX(), e.getY());
                                //放置武器容器
                                peaShooters.addLast(peaShooter);
                                sunCount -= 100;
                            } catch (IOException ioException) {
                                ioException.printStackTrace();
                            }
                        }
                    }
                } else {
                    isPeaFloor = 1;
                }
                //种植太阳花
                if (sunFlower == null) {
                    if (sunFlowerCard.rectangle.contains(e.getX(), e.getY())) {
                        if (sunCount >= 50) {
                            try {
                                //创建一个 武器
                                sunFlower = new SunFlower(e.getX(), e.getY());
                                //放置武器容器
                                sunFlowers.addLast(sunFlower);
                                sunCount -= 50;
                            } catch (IOException ioException) {
                                ioException.printStackTrace();
                            }
                        }
                    }
                } else {
                    isSunFlowerDown = 1;
                }
            }
        });
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        if (offScreenImage == null) {
            offScreenImage = this.createImage(1400, 600);
        }
        g.drawImage(offScreenImage, 0, 0, null);

        Graphics gOffScreen = offScreenImage.getGraphics();
        //2D
        Graphics2D graphics2D = (Graphics2D) gOffScreen;

        gOffScreen.fillRect(0, 0, 1400, 600);
        gOffScreen.setColor(Color.white);

        this.backGround.draw(gOffScreen);
        this.sunCountCard.draw(gOffScreen);
        this.sunFlowerCard.draw(gOffScreen);
        this.peaShooterCard.draw(gOffScreen);

        //绘制分值
        gOffScreen.setFont(new Font("黑体", Font.BOLD, 20));
        gOffScreen.setColor(Color.red);
        gOffScreen.drawString(this.sunCount + "", 215, 110);

        //绘制所有武器
        if (this.peaShooters != null) {
            for (int i = 0; i < peaShooters.size(); i++) {
                peaShooters.get(i).draw(gOffScreen);
            }
        }

        //绘制所有太阳花
        if (this.sunFlowers != null) {
            for (int i = 0; i < sunFlowers.size(); i++) {
                sunFlowers.get(i).draw(gOffScreen);
            }
        }

        //绘制阳光
        if (this.sun != null)
            this.sun.draw(gOffScreen);

        //绘制所有僵尸
        if (zombies.size() != 0) {
            for (int i = 0; i < zombies.size(); i++) {
                zombies.get(i).draw(gOffScreen);
            }
        }
        //绘制豌豆子弹
        if (peas != null) {
            for (int i = 0; i < peas.size(); i++) {
                if (peas.get(i).x > 1400) {
                    peas.remove(peas.get(i));
                    continue;
                }
                peas.get(i).draw(gOffScreen);
            }
        }

        //绘制豌豆子弹
        if (suns != null) {
            for (int i = 0; i < suns.size(); i++) {
                if (suns.get(i).x > 1400) {
                    suns.remove(suns.get(i));
                    continue;
                }
                suns.get(i).draw(gOffScreen);
            }
        }

        gOffScreen.setFont(new Font("黑体", Font.BOLD, 30));
        //绘制数量
        gOffScreen.drawString("当前的僵尸数量:" + this.total, 400, 100);
        //全部消灭之后
        if (this.total == 0) {
            gOffScreen.drawImage(this.okImage, 600, 200, this.okImage.getWidth(), this.okImage.getHeight(), null);


        }
        if (this.isFail==1){
            gOffScreen.drawImage(this.noImage, 400, 100, this.noImage.getWidth(), this.noImage.getHeight(), null);
        }
    }

    /**
     * 生产自然光
     */
    public void createSun() throws IOException {
        //指定位置
        int y = -100;
        int x = this.random.nextInt(500) + 260;//260 760
        sun = new Sun(x, y);
    }

    /**
     * 移动阳光
     */
    public void sunMove() {
        //确定目标坐标
        if (sunMeetMouse == 0) {
            if (this.sun.y < this.sunTargetY)
                this.sun.y += 25;
        } else if (sunMeetMouse == 1) {
            if (this.sunCountCard.rectangle.contains(this.sun.x + 50, this.sun.y + 50)) {
                this.sunCount += 25;
                //重置阳光数据
                this.sun = null;
                this.sunMeetMouse = 0;
            } else {
                //设定y速度
                int yspeed = 15;
                //求解X轴
                int xspeed = (yspeed * xlength) / ylength;
                this.sun.x -= xspeed;
                this.sun.y -= yspeed;
            }
        }
        if (this.sun != null)
            this.sun.rectangle.setBounds(this.sun.x, this.sun.y, this.sun.size, this.sun.size);
    }

    public void sunMove_() {
        //确定目标坐标
        for (int i = 0; i < suns.size(); i++) {
            Sun s = suns.get(i);
            if (s == null)
                continue;
            if (s.isMeetMouse == 1) {
                if (this.sunCountCard.rectangle.intersects(s.rectangle)) {
                    this.sunCount += 25;
                    //重置阳光数据
                    s.isMeetMouse = 0;
                    suns.remove(s);
                } else {
                    //设定y速度
                    int yspeed = 15;
                    //求解X轴
                    int xspeed = (yspeed * s.xlength) / s.ylength;
                    s.x -= xspeed;
                    s.y -= yspeed;
                }
            }
        }
    }

    //添加方法:检查子弹是不是碰到了僵尸
    public void peaIsMeetZombie() {
        //
        for (int i = 0; i < zombies.size(); i++) {
            //僵尸
            Zombie zb = zombies.get(i);
            if (zb == null)
                continue;
            //回收
            if (zb.index_ >= 9) {
                zombies.remove(zb);
                this.total--;
                if (this.total == 0) {
                    //timer.stop();
                    //repaint();
                   // return;
                }
                break;
            }
            //检查是否已经全部死亡

            for (int j = 0; j < peas.size(); j++) {
                Pea p = peas.get(j);
                if (p == null)
                    continue;
                if (zb.rectangle.intersects(p.rectangle)) {
                    if (zb.live > 0)
                        zb.live -= 1;
                    peas.remove(p);
                }
            }
        }
    }

    /**
     * 僵尸碰到植物
     */
    public void isZombieMeetSunFlowerOrPeaShooter() {
        for (int i = 0; i < zombies.size(); i++) {
            Zombie zb = zombies.get(i);
            if (zb == null) continue;
            if (zb.x<150){
                this.isFail=1;
            }
            if (zb.x<130){
                timer.stop();
                return;
            }
            //太阳花
            for (int j = 0; j < sunFlowers.size(); j++) {
                SunFlower sf = sunFlowers.get(j);
                if (sf == null) continue;
                if (zb.rectangle.contains(sf.rectangle) && sunFlower == null) {
                    if (sf.live > 0) {
                        zb.run = 0;
                        sf.live--;
                    } else {
                        zb.run = 1;
                        sunFlowers.remove(sf);
                    }
                    break;
                }
            }
            for (int j = 0; j < peaShooters.size(); j++) {
                PeaShooter ps = peaShooters.get(j);
                if (ps == null) continue;
                if (zb.rectangle.contains(ps.rectangle) && peaShooter == null) {
                    if (ps.live > 0) {
                        zb.run = 0;
                        ps.live--;
                    } else {
                        zb.run = 1;
                        peaShooters.remove(ps);
                    }
                    break;
                }
            }
        }

    }
}

7. Card

package com.hm;

import java.awt.*;
import java.awt.image.BufferedImage;

public class Card {
    //图片
    BufferedImage image;
    int x;
    int y;
    //范围
    Rectangle rectangle;

    public Card(BufferedImage image,int x,int y){
        this.image=image;
        this.x=x;
        this.y=y;
        this.rectangle=new Rectangle(this.x,this.y,60,75);
    }

    /**
     * 绘制
     */
    public void draw(Graphics graphics){
        graphics.drawImage(this.image,this.x,this.y,60,75,null);
    }
}

8.BackGround

package com.hm;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * 背景有关代码
 */
public class BackGround {
    //图片
    BufferedImage image;
    //位置 x
    int x;
    //y
    int y;

    public BackGround() throws IOException {
        //加载图片
        this.image= ImageIO.read(new File("images/background/background1.jpg"));
        this.x=0;
        this.y=0;
    }

    /**
     * 绘制
     */
    public  void draw(Graphics graphics){
        graphics.drawImage(this.image,this.x,this.y,1400,600,null);
    }
}

公众号里回复   植物大战僵尸  获取源代码和素材!```