公众号:编程驿站
没有做太多封装。难免有冗余。源码全部放出,有兴趣者可以再改之。
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);
}
}
公众号里回复 植物大战僵尸 获取源代码和素材!```