first commit

This commit is contained in:
octopus_yan 2021-04-29 16:12:47 +08:00
commit 013bc1152d
152 changed files with 1257 additions and 0 deletions

12
Xm.iml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/bin" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="jdk" jdkName="JavaSE-1.8" jdkType="JavaSDK" />
</component>
</module>

BIN
bin/pnf/Bullet.class Normal file

Binary file not shown.

BIN
bin/pnf/Fight.class Normal file

Binary file not shown.

BIN
bin/pnf/Plants.class Normal file

Binary file not shown.

Binary file not shown.

BIN
bin/pnf/StartPanel$1.class Normal file

Binary file not shown.

BIN
bin/pnf/StartPanel$2.class Normal file

Binary file not shown.

BIN
bin/pnf/StartPanel$3.class Normal file

Binary file not shown.

BIN
bin/pnf/StartPanel$4.class Normal file

Binary file not shown.

BIN
bin/pnf/StartPanel.class Normal file

Binary file not shown.

BIN
bin/pnf/Zombles.class Normal file

Binary file not shown.

BIN
dz/dz1_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

BIN
dz/dz1_10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

BIN
dz/dz1_11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

BIN
dz/dz1_12.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

BIN
dz/dz1_13.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

BIN
dz/dz1_14.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

BIN
dz/dz1_15.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

BIN
dz/dz1_16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
dz/dz1_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

BIN
dz/dz1_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

BIN
dz/dz1_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

BIN
dz/dz1_5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

BIN
dz/dz1_6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

BIN
dz/dz1_7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

BIN
dz/dz1_8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

BIN
dz/dz1_9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

BIN
dz/dz2_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
dz/dz2_10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
dz/dz2_11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
dz/dz2_12.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

BIN
dz/dz2_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
dz/dz2_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
dz/dz2_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
dz/dz2_5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
dz/dz2_6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
dz/dz2_7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
dz/dz2_8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
dz/dz2_9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
lib/Win.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 KiB

BIN
lib/bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

BIN
lib/bp_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
lib/bp_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
lib/bp_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lib/bp_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lib/bp_5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
lib/bp_6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
lib/bp_7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
lib/bp_8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
lib/gameover.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
lib/js1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
lib/js2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

BIN
lib/js3.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
lib/js4.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

BIN
lib/js5.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
lib/js6.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
lib/nextLevel.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
lib/pause.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
lib/start_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

BIN
lib/start_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 KiB

BIN
lib/statusBar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
lib/xz_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lib/xz_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lib/xz_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lib/xz_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lib/xz_5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lib/xz_6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
lib/xz_7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lib/xz_8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lib/zd_1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 569 B

BIN
lib/zd_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
lib/zd_2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
lib/zd_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
lib/zl_1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
lib/zl_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lib/zl_2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
lib/zl_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lib/zl_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lib/zl_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lib/zl_5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lib/zl_6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lib/zw1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
lib/zw2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
lib/zw3.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
lib/zw4.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

33
src/pnf/Bullet.java Normal file
View File

@ -0,0 +1,33 @@
package pnf;
import javax.swing.ImageIcon;
public class Bullet {
int x,y,h,w;
int speed;
ImageIcon image;
ImageIcon[] images = new ImageIcon[]{new ImageIcon("lib/zd_1.gif"),new ImageIcon("lib/zd_2.gif")};
/**
*
* @param k 子弹类型
* @throws IOException
*/
public Bullet(int k, int x, int y) {
// TODO Auto-generated constructor stub
this.x = x;
this.y = y;
if(k == 0){
image = images[0];
}else{
image = images[1];
}
w = image.getIconWidth();
h = image.getIconHeight();
speed = 5;
}
/**子弹走一步*/
public void step() {
x += speed;
}
}

110
src/pnf/Fight.java Normal file
View File

@ -0,0 +1,110 @@
package pnf;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Fight {
BufferedImage[] hoof = new BufferedImage[8];
BufferedImage[] rush = new BufferedImage[8];
BufferedImage[] stop = new BufferedImage[6];
BufferedImage[] attack1 = new BufferedImage[10];
BufferedImage[] attack2 = new BufferedImage[11];
BufferedImage[] attack3 = new BufferedImage[9];
BufferedImage image;
/**人物宽高*/
int w,h;
/**人物位置*/
int x,y;
/**速度*/
int[] speed = new int[2];
/**人物状态*/
int state;
/**行走*/
public static final int HOOF = 0;
/**奔跑*/
public static final int RUSH = 1;
/**站立*/
public static final int STOP = 2;
/**攻击*/
public static final int ATTACK = 3;
public Fight() throws IOException {
//人物三次攻击
for (int i = 0; i < attack1.length; i++) {
attack1[i] = ImageIO.read(new File("素材/pg1_"+(i+1)+".png"));
}
for (int i = 0; i < attack2.length; i++) {
attack2[i] = ImageIO.read(new File("素材/pg2_"+(i+1)+".png"));
}
for (int i = 0; i < attack3.length; i++) {
attack3[i] = ImageIO.read(new File("素材/pg3_"+(i+1)+".png"));
}
//人物行进状态
for (int i = 0; i < hoof.length; i++) {
hoof[i] = ImageIO.read(new File("lib/xz_"+(i+1)+".png"));
}
for (int i = 0; i < rush.length; i++) {
rush[i] = ImageIO.read(new File("lib/bp_"+(i+1)+".png"));
}
for (int i = 0; i < stop.length; i++) {
stop[i] = ImageIO.read(new File("lib/zl_"+(i+1)+".png"));
}
state = STOP;
w = attack1[0].getWidth();
h = attack1[0].getHeight();
x = 100;
y = 100;
speed[0] = 7;
speed[1] = 10;
image = stop[0];
}
void rightMove(){
x += speed[state];
if(x >= 1200-w) {
x -= speed[state];
}
}
void leftMove(){
x -= speed[state];
if(x<=-116) {
x += speed[state];
}
}
void upMove(){
y -= speed[0];
if(y<=-30) {
y += speed[0];
}
}
void downMove(){
y += speed[0];
if(y>=660-h) {
y -= speed[0];
}
}
protected static int index = 0;
/**人物图片切换*/
void step(){
BufferedImage[] fight = null;
switch (state) {
case STOP:
fight = stop;
break;
case HOOF:
fight = hoof;
break;
case RUSH:
fight = rush;
break;
}
if (fight != null) {
this.image = fight[index++/2%fight.length];
w = image.getWidth();
h = image.getHeight();
}
}
}

69
src/pnf/Plants.java Normal file
View File

@ -0,0 +1,69 @@
package pnf;
import java.util.Random;
import javax.swing.ImageIcon;
public class Plants {
/**植物数组*/
static ImageIcon[] zw = new ImageIcon[4];
ImageIcon rzw;
int iz,w,h;
//种植格子
static int[] y = new int[5];
static int[] x = new int[10];
static boolean[][] t = new boolean[5][10];
int ix,iy,rx,ry;
/**植物血量*/
int blood;
static {
for (int i = 0; i < zw.length; i++) {
zw[i] = new ImageIcon("lib/zw"+(i+1)+".gif");
}
for (int i = 0; i < x.length; i++) {
x[i] = 110+i*80;
}
for (int i = 0; i < y.length; i++) {
y[i] = 191+i*100;
}
}
public Plants() {//随机植物种类,位置
Random r = new Random();
iz = r.nextInt(zw.length);
switch (iz) {
case 0:
blood = 10;
break;
case 1:
blood = 10;
break;
case 2:
blood = 12;
break;
case 3:
blood = 68;
break;
}
rzw = zw[iz];
w = rzw.getIconWidth();
h = rzw.getIconHeight();
ix = r.nextInt(x.length);
iy = r.nextInt(y.length);
while (t[iy][ix]) {//检查是否重复使用格子
ix = r.nextInt(x.length);
iy = r.nextInt(y.length);
}
rx = x[ix];
ry = y[iy];
t[iy][ix] = true;
}
/**发射子弹*/
public Bullet shoot(){
if(iz == 0){
return new Bullet(iz, rx+60,ry-68);
}else{
return new Bullet(iz, rx+50,ry-60);
}
}
}

View File

@ -0,0 +1,18 @@
package pnf;
import java.io.IOException;
import javax.swing.JFrame;
public class PlantsAndFight extends JFrame {
public static void main(String[] args) throws IOException, InterruptedException {
JFrame jf = new JFrame("Plants And Fight");
StartPanel sp = new StartPanel();
jf.add(sp);
jf.setSize(1214, 674);
jf.setLocationRelativeTo(jf);
jf.setResizable(false); //不许改变窗口大小
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
sp.action();
}
}

962
src/pnf/StartPanel.java Normal file
View File

@ -0,0 +1,962 @@
package pnf;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class StartPanel extends JPanel{
/** 游戏的当前状态: START PAUSE RUNNING NEXT_LEVEL GAME_OVER GAME_WIN */
private int state;
public static final int START = 0;
public static final int RUNNING = 1;
public static final int PAUSE = 2;
public static final int NEXT_LEVEL = 3;
public static final int GAME_OVER = 4;
public static final int GAME_WIN = 5;
/**技能*/
public static final int DZ = 6;
/**记录技能CD*/
long timeDz;
int cd = 10;
/**大招CD*/
int dzcd;
/** 难度级别 */
private int level;
/**分数*/
int score = 0;
/**生命*/
int life;
/**人物方向 初始为右*/
boolean direction = RIGHT;
/**人物方向 左*/
public static final boolean LEFT = false;
/**人物方向 右*/
public static final boolean RIGHT = true;
/**人物攻击状态*/
long time3;
int attack = 1;
/**人物状态判断*/
long time;
long time1;
long time2;
/**植物数组*/
Plants[] plants = {};
int[] indexs = {};
/**僵尸数组*/
Zombles[] zombles = {};
/**子弹数组*/
Bullet[] bullets = {};
/**勇者*/
Fight fight;
public static BufferedImage background;
public static BufferedImage[] starts = new BufferedImage[2];
public static BufferedImage gameWin;
public static BufferedImage gameOver;
public static ImageIcon pause;
public static ImageIcon nextLevel;
public static BufferedImage statusBar;
public static BufferedImage[] jiNengs_1 = new BufferedImage[16];
public static BufferedImage[] jiNengs_2 = new BufferedImage[12];
public static BufferedImage jiNeng;
static{
/** 在StratPanel类中添加 图片引用 */
try {
background = ImageIO.read(new File("lib/bg.jpg"));
starts[0] = ImageIO.read(new File("lib/start_1.png"));
starts[1] = ImageIO.read(new File("lib/start_2.png"));
pause = new ImageIcon("lib/pause.gif");
nextLevel = new ImageIcon("lib/nextLevel.gif");
gameOver = ImageIO.read(new File("lib/gameover.png"));
gameWin = ImageIO.read(new File("lib/Win.png"));
statusBar = ImageIO.read(new File("lib/statusBar.png"));
for (int i = 0; i < jiNengs_1.length; i++) {
jiNengs_1[i] = ImageIO.read(new File("dz/dz1_"+(i+1)+".png"));
}
for (int i = 0; i < jiNengs_2.length; i++) {
jiNengs_2[i] = ImageIO.read(new File("dz/dz2_"+(i+1)+".png"));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public StartPanel() throws IOException {
level = 1;//初始关卡级别
plants = new Plants[level*3];
indexs = new int[plants.length];
zombles = new Zombles[level*5];
life = zombles.length/5;
for (int i = 0; i < plants.length; i++) {
plants[i] = new Plants();
}
for (int i = 0; i < zombles.length; i++) {
zombles[i] = new Zombles();
}
fight = new Fight();
}
@Override
public void paint(Graphics g) {
g.drawImage(background, -150, 0, background.getWidth(), background.getHeight(), null);
paintPlants(g); //画植物
paintBullets(g); //画子弹
paintFight(g); //画人物
paintZmb(g); //画僵尸
paintScoreAndLife(g); //画生命和分数
paintState(g); //画状态
}
/**技能属性*/
int dzindex, dzi;
int dzx = 0, dzy = 80, dzw = 1100, dzh = 491;
int index;
int dztime = 50;
/**画状态*/
public void paintState(Graphics g) {
switch (state) {
case START:
g.drawImage(starts[index++/2000%2], 0, 0, this.getWidth(), this.getHeight(), null);
g.drawString("单击任意位置或者按“ENTER”开始游戏", 300, 630);
break;
case PAUSE:
g.drawImage(pause.getImage(), 300, 50, null);
g.drawString("单击任意位置或者按“C”继续游戏", 350, 460);
break;
case NEXT_LEVEL:
g.drawImage(nextLevel.getImage(), 300, 50, null);
g.drawString("单击任意位置或者按“N”开始下一关", 300, 630);
break;
case GAME_OVER:
g.drawImage(gameOver, 230, 100, (int)(425*1.5), (int)(269*1.5), null);
break;
case GAME_WIN:
g.drawImage(gameWin, -15, -15, null);
g.drawString("单击任意位置或者按“ENTER”重新开始游戏", 300, 650);
break;
case DZ:
if (dzindex++ %dztime == 0) {//切换技能图片
if (dzi > 15) {
if (dzi == 16) {
dztime = 100;
dzw = 272*2;
dzh = 220*2;
dzy = fight.y+fight.h/2-220;
if (direction == RIGHT) {
dzx = fight.x;
}else{
dzx = fight.x - 250;
}
}else if(dzi-15 < 6){
if (direction == RIGHT) {
dzx += 60;
}else{
dzx -= 60;
}
}
if (dzi-16 == 12) {
daZhao();
dzi = dzindex = index = 0;
dzx = 0; dzy = 80; dzw = 1100; dzh = 491;
dztime = 25;
state = RUNNING;
}else{
jiNeng = jiNengs_2[dzi++-16];
}
}else{
jiNeng = jiNengs_1[dzi++];
}
}
g.drawImage(jiNeng, dzx, dzy, dzw, dzh, null);
break;
default:
index = 0;
break;
}
}
/**画系统信息*/
public void paintScoreAndLife(Graphics g) {
int x = 1010;
int y = 55;
Font font = new Font("华文楷体", Font.BOLD, 25);
g.setFont(font);
g.setColor(Color.WHITE);
g.drawImage(statusBar, 1000, 0, null);
g.drawString("当前关卡:"+level, x, y);
y += 30;
g.drawString("分数:"+score, x, y);
y += 30;
g.drawString("生命:"+life, x, y);
y += 30;
g.drawString("僵尸数量:", x, y);
y += 30;
g.drawString(zombles.length+"/"+level*5, x, y);
y += 30;
g.drawString("植物数量:"+plants.length, x, y);
if (state != PAUSE) {
//计算技能CD时间
long t = System.currentTimeMillis();
if (cd - (int)(t - timeDz)/1000 < 0||cd - (int)(t - timeDz)/1000 > 120) {
dzcd = 0;
}else{
dzcd = cd - (int)(t - timeDz)/1000;
}
}
y += 30;
g.drawString("技能CD"+dzcd, x, y);
y += 80;
g.drawString("\"ENTER\"", x, y);
y += 25;
g.drawString("开始游戏", x, y);
y += 35;
g.drawString("\"X\"", x, y);
y += 25;
g.drawString("普通攻击/复活", x, y);
y += 35;
g.drawString("\"D\":技能", x, y);
y += 35;
g.drawString("\"P\":暂停", x, y);
y += 35;
g.drawString("\"C\":继续", x, y);
y += 35;
g.drawString("\"N\":下一关", x, y);
y += 35;
g.drawString("\"ESC/Q\"", x, y);
y += 25;
g.drawString("离开游戏", x, y);
}
/**画人物*/
public void paintFight(Graphics g) {
g.drawImage(fight.image, fight.x, fight.y, fight.w, fight.h, null);
}
/**画植物*/
public void paintPlants(Graphics g) {
for (int i = 0; i < plants.length; i++) {
g.drawImage(plants[i].rzw.getImage(), plants[i].rx, plants[i].ry-plants[i].h, plants[i].w, plants[i].h, null);
}
}
/**画僵尸*/
public void paintZmb(Graphics g) {
for (int i = 0; i < zombles.length; i++) {
g.drawImage(zombles[i].rjs.getImage(), zombles[i].x, zombles[i].ry-zombles[i].h, zombles[i].w, zombles[i].h, null);
}
}
/**画子弹*/
public void paintBullets(Graphics g) {
for (int i = 0; i < bullets.length; i++) {
g.drawImage(bullets[i].image.getImage(), bullets[i].x, bullets[i].y, bullets[i].w, bullets[i].h, null);
}
}
/**启动方法*/
public void action(){
//添加鼠标监听器
this.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
switch (state) {
case START:
state = RUNNING;
break;
case RUNNING:
state = PAUSE;
break;
case PAUSE:
timeDz = System.currentTimeMillis() - (10-dzcd)*1000;
state = RUNNING;
break;
case GAME_OVER:
life = level;
bullets = new Bullet[] {};
plants = new Plants[level*3];
indexs = new int[plants.length];
Plants.t = new boolean[5][10];
for (int i = 0; i < plants.length; i++) {
plants[i] = new Plants();
}
zombles = new Zombles[level*5];
for (int i = 0; i < zombles.length; i++) {
zombles[i] = new Zombles();
}
indexZ = 0;
zomblexs = 0;
state = RUNNING;
break;
case NEXT_LEVEL:
level += 1;
life += 1;
bullets = new Bullet[0];
if (level*3 > 50) { //最多只能放50个植物
plants = new Plants[50];
}else{
plants = new Plants[level*3];
}
indexs = new int[plants.length];
Plants.t = new boolean[5][10];
for (int i = 0; i < plants.length; i++) {
plants[i] = new Plants();
}
zombles = new Zombles[level*5];
for (int i = 0; i < zombles.length; i++) {
zombles[i] = new Zombles();
}
indexZ = 0;
zomblexs = 0;
state = RUNNING;
break;
case GAME_WIN:
score = 0;
level = 1;
life = 1;
bullets = new Bullet[0];
plants = new Plants[level*3];
indexs = new int[plants.length];
Plants.t = new boolean[5][10];
for (int i = 0; i < plants.length; i++) {
plants[i] = new Plants();
}
zombles = new Zombles[level*5];
for (int i = 0; i < zombles.length; i++) {
zombles[i] = new Zombles();
}
indexZ = 0;
zomblexs = 0;
state = START;
break;
}
}
});
//添加键盘监听器
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch (state) {
case START:
processGameStartKey(key);
break;
case RUNNING:
processRunningKey(key);
break;
case PAUSE:
processPauseKey(key);
break;
case NEXT_LEVEL:
processNextLevelKey(key);
break;
case GAME_OVER:
processGameoverKey(key);
break;
case GAME_WIN:
processGameWinKey(key);
break;
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
if (e.getKeyCode() != KeyEvent.VK_X) {
ir();
}
}
});
this.requestFocus();//设置焦点
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
// TODO Auto-generated method stub
switch (state) {
case RUNNING:
//动起来
stepAction();
//发射子弹
shootAction();
//检测碰撞
pengAction();
//检查血量
checkBlood();
//检查越界
outOfBoundAction();
//检测是否进入下一关
isNextLevel();
break;
}
fight.step();
}
} , 0, 50);
while(true){
repaint();//调用repaint()方法重绘画面
}
}
/**游戏结束时键盘事件*/
void processGameoverKey(int key){
switch (key) {
case KeyEvent.VK_ESCAPE:
System.exit(0);
break;
case KeyEvent.VK_X:
score -= 10;
life = level;
bullets = new Bullet[0];
plants = new Plants[level*3];
indexs = new int[plants.length];
Plants.t = new boolean[5][10];
for (int i = 0; i < plants.length; i++) {
plants[i] = new Plants();
}
zombles = new Zombles[level*5];
for (int i = 0; i < zombles.length; i++) {
zombles[i] = new Zombles();
}
indexZ = 0;
zomblexs = 0;
state = RUNNING;
break;
}
}
/**游戏胜利时键盘事件*/
void processGameWinKey(int key){
switch (key) {
case KeyEvent.VK_ESCAPE:
System.exit(0);
break;
case KeyEvent.VK_Q:
System.exit(0);
break;
case KeyEvent.VK_ENTER:
score = 0;
level = 1;
life = 1;
bullets = new Bullet[0];
plants = new Plants[level*3];
indexs = new int[plants.length];
Plants.t = new boolean[5][10];
for (int i = 0; i < plants.length; i++) {
plants[i] = new Plants();
}
zombles = new Zombles[level*5];
for (int i = 0; i < zombles.length; i++) {
zombles[i] = new Zombles();
}
indexZ = 0;
zomblexs = 0;
state = START;
break;
}
}
/**游戏进入下一关时键盘事件*/
void processNextLevelKey(int key){
switch (key) {
case KeyEvent.VK_ESCAPE:
System.exit(0);
break;
case KeyEvent.VK_Q:
System.exit(0);
break;
case KeyEvent.VK_N:
level += 1;
life += 1;
bullets = new Bullet[0];
plants = new Plants[level*3];
if (level*3 > 50) {
plants = new Plants[50];
}
indexs = new int[plants.length];
Plants.t = new boolean[5][10];
for (int i = 0; i < plants.length; i++) {
plants[i] = new Plants();
}
zombles = new Zombles[level*5];
for (int i = 0; i < zombles.length; i++) {
zombles[i] = new Zombles();
}
indexZ = 0;
zomblexs = 0;
state = RUNNING;
break;
}
System.gc();
}
/**游戏暂停时键盘事件*/
void processPauseKey(int key){
switch (key) {
case KeyEvent.VK_ESCAPE:
System.exit(0);
break;
case KeyEvent.VK_Q:
System.exit(0);
break;
case KeyEvent.VK_C:
timeDz = System.currentTimeMillis() - (10-dzcd)*1000;
state = RUNNING;
break;
}
}
/**游戏初始时键盘事件*/
void processGameStartKey(int key){
switch (key) {
case KeyEvent.VK_ESCAPE:
System.exit(0);
break;
case KeyEvent.VK_Q:
System.exit(0);
break;
case KeyEvent.VK_ENTER:
state = RUNNING;
break;
}
}
/**游戏运行时键盘事件*/
void processRunningKey(int key){
switch (key) {
case KeyEvent.VK_ESCAPE:
System.exit(0);
break;
case KeyEvent.VK_RIGHT:
if(direction!=RIGHT) {//判断人物方向调用图片左右翻转方法
fis();
direction = RIGHT;
fight.x += 50;
fi();
}
long t = System.currentTimeMillis();//记录上一次击键时间
if (fight.state != Fight.RUSH) {
if(t-time<200&&t-time>110) {//根据两次击键时间间隔判断是否进入奔跑状态
fight.state = Fight.RUSH;
rightMove();
}else {
fight.state = Fight.HOOF;
time = t;
rightMove();
}
}else {
rightMove();
}
break;
case KeyEvent.VK_LEFT:
if(direction!=LEFT) {
fis();
direction = LEFT;
fight.x -= 50;
fi();
}
long t1 = System.currentTimeMillis();
if (fight.state != Fight.RUSH) {
if(t1-time1<200&&t1-time1>110) {
fight.state = Fight.RUSH;
leftMove();
}else {
fight.state = Fight.HOOF;
time1 = t1;
leftMove();
}
}else {
leftMove();
}
break;
case KeyEvent.VK_DOWN:
fight.state = Fight.HOOF;
downMove();
break;
case KeyEvent.VK_UP:
fight.state = Fight.HOOF;
upMove();
break;
case KeyEvent.VK_P:
state = PAUSE;
break;
case KeyEvent.VK_X:
long t2 = System.currentTimeMillis();
if(t2-time3<500&&t2-time3>250){
attack++;
if(attack==4){
attack = 1;
}
attack(attack);//调用攻击方法
}else if(t2-time3>500){
attack = 1;
attack(attack);
}
time3 = t2;
break;
case KeyEvent.VK_D:
if (dzcd == 0) {
state = DZ;
}
break;
}
}
int indexZ;
int zomblexs;
/**走一步*/
public void stepAction(){
if (zomblexs < zombles.length&&indexZ++ % 50 == 0) {
zomblexs += zombles.length/level;
} //僵尸分批出动
if (zomblexs > zombles.length) {
zomblexs = zombles.length;
}
for (int i = 0; i < zomblexs; i++) {
zombles[i].step();
}
for (int i = 0; i < bullets.length; i++) {
Bullet bullet = bullets[i];
bullet.step();
}
}
/**发射子弹*/
int shootIndex = 0;
public void shootAction(){
if (shootIndex++%27==0) {
for (int i = 0; i < plants.length; i++) {
if (plants[i].iz==0||plants[i].iz==1) {//只有两种植物能发射子弹
for (int j = 0; j < zombles.length; j++) {
if (plants[i].ry == zombles[j].ry&&zombles[j].x<1000) {//如果出现僵尸
Bullet bs = plants[i].shoot();
bullets = Arrays.copyOf(bullets, bullets.length+1);
bullets[bullets.length-1] = bs;
}
}
}
}
}
}
/**向右移动*/
void rightMove() {
fight.rightMove();
}
/**向左移动*/
void leftMove() {
fight.leftMove();
}
/**向上移动*/
void upMove() {
fight.upMove();
}
/**向下移动*/
void downMove() {
fight.downMove();
}
/**攻击*/
void attack(int a){
Timer t = new Timer();
t.schedule(new TimerTask() {
int index=0;
@Override
public void run() {
// TODO Auto-generated method stub
switch (a) {//根据参数更换攻击图片
case 1:
fight.state = Fight.ATTACK;
fight.image = fight.attack1[index++];
if (index == 5) {//优化打击画面
pengFinghtAndZomble();
}
if(index==fight.attack1.length){
t.cancel();//关闭计时器
fight.state = Fight.STOP;
}
break;
case 2:
fight.state = Fight.ATTACK;
fight.image = fight.attack2[index++];
if (index == 5) {
pengFinghtAndZomble();
}
if(index==fight.attack2.length){
t.cancel();
fight.state = Fight.STOP;
}
break;
case 3:
fight.state = Fight.ATTACK;
fight.image = fight.attack3[index++];
if (index == 5) {
pengFinghtAndZomble();
}
if(index==fight.attack3.length){
t.cancel();
fight.state = Fight.STOP;
}
break;
}
}
}, 0,40);
System.gc();
}
/**检测碰撞方法*/
public void pengAction(){
pengBulletsAndZomble();
pengPlantsAndZomble();
}
/**检测人物攻击僵尸*/
public void pengFinghtAndZomble(){
for (int i = 0; i < zombles.length; i++) {
if (isRectangle(fight, zombles[i])) {
zombles[i].x += zombles[i].speed*5;
zombles[i].blood -= 4;
}
}
}
/**释放技能*/
public void daZhao(){
timeDz = System.currentTimeMillis();
int dzx = this.dzx+jiNeng.getWidth();
int dzy = this.dzy+jiNeng.getHeight();
int dzw = jiNeng.getWidth();
int dzh = jiNeng.getHeight();
Rectangle r1 = new Rectangle( dzx, dzy, dzw, dzh);
for (int i = 0; i < zombles.length; i++) {
if (zombles[i].x <= 1100) {
Rectangle r2 = new Rectangle( zombles[i].x, zombles[i].ry,
zombles[i].w, zombles[i].h);
if (r1.intersects(r2)) {
zombles[i].x += zombles[i].speed*5;
zombles[i].blood = -1;
}
}
}
}
/**检测子弹与僵尸碰撞*/
public void pengBulletsAndZomble(){
for (int i = 0; i < bullets.length; i++) {
for (int j = 0; j < zombles.length; j++) {
if (i<bullets.length&&isRectangle(bullets[i], zombles[j])) {
bulletDie(i);
zombles[j].x += zombles[j].speed*2;
zombles[j].blood -= 2;
}
}
}
}
/**检测植物与僵尸碰撞*/
public void pengPlantsAndZomble(){
for (int i = 0; i < plants.length; i++) {
for (int j = 0; j < zombles.length; j++) {
if (isRectangle(plants[i], zombles[j])) {
plantKx(i,j);
zombles[j].x += zombles[j].speed;
}
}
}
}
/**植物扣血*/
public void plantKx(int i, int j){
if (indexs[i]++%30 == 0) {
plants[i].blood -= zombles[j].ij+2;
}
}
/**检查血量*/
public void checkBlood(){
for (int i = 0; i < zombles.length; i++) {
if (zombles[i].blood <= 0) {
zombleDie(i);
}
}
for (int i = 0; i < plants.length; i++) {
if (plants[i].blood <= 0) {
plantDie(i);
}
}
if (life <= 0) {
state = GAME_OVER;
}
}
/**检测过关条件*/
public void isNextLevel() {
if (zombles.length == 0) {
state = NEXT_LEVEL;
}
}
/**检查僵尸和子弹出界*/
public void outOfBoundAction() {
//检查子弹越界
for (int i = 0; i < bullets.length; i++) {
if (bullets[i].x>1100) {
bulletDie(i);
}
}
//检查僵尸越界
for (int i = 0; i < zombles.length; i++) {
if (zombles[i].x+zombles[i].w <= 0) {
zombleDie(i);
life -= 1;
}
}
}
/**僵尸消失*/
public void zombleDie(int i) {
score += 1;
Zombles zs = zombles[i];
zombles[i] = zombles[zombles.length-1];
zombles[zombles.length-1] = zs;
zombles = Arrays.copyOf(zombles, zombles.length-1);
}
/**子弹消失*/
public void bulletDie(int i) {
Bullet b = bullets[i];
bullets[i] = bullets[bullets.length-1];
bullets[bullets.length-1] = b;
bullets = Arrays.copyOf(bullets, bullets.length-1);
}
/**植物消失*/
public void plantDie(int i){
Plants p = plants[i];
plants[i] = plants[plants.length-1];
plants[plants.length-1] = p;
plants = Arrays.copyOf(plants, plants.length-1);
int index = indexs[i];
indexs[i] = indexs[indexs.length-1];
indexs[indexs.length-1] = index;
indexs = Arrays.copyOf(indexs, indexs.length-1);
}
/**立即恢复站立姿态*/
void ir() {
fight.state = Fight.STOP;
repaint();
}
/**人物行进图片翻转*/
void fis(){
for (int i = 0; i < fight.hoof.length; i++) {
fight.hoof[i] = flipImage(fight.hoof[i]);
}
for (int i = 0; i < fight.rush.length; i++) {
fight.rush[i] = flipImage(fight.rush[i]);
}
for (int i = 0; i < fight.stop.length; i++) {
fight.stop[i] = flipImage(fight.stop[i]);
}
}
/**攻击动作图片翻转*/
void fi(){
for (int i = 0; i < fight.attack1.length; i++) {
fight.attack1[i] = flipImage(fight.attack1[i]);
}
for (int i = 0; i < fight.attack2.length; i++) {
fight.attack2[i] = flipImage(fight.attack2[i]);
}
for (int i = 0; i < fight.attack3.length; i++) {
fight.attack3[i] = flipImage(fight.attack3[i]);
}
for (int i = 0; i < jiNengs_2.length; i++) {
jiNengs_2[i] = flipImage(jiNengs_2[i]);
}
}
/**
* 检测碰撞
* @param b 僵尸对象
*/
boolean isRectangle(Fight a,Zombles b){//Java基本矩形碰撞检测类
if (a.y+a.h-19>b.ry+35||a.y+a.h-19<b.ry-35) {
return false;
}else{
Rectangle a1;
if(direction){
a1 = new Rectangle(a.x+a.w/2,a.y,a.w/2,a.h);
}else{
a1 = new Rectangle(a.x,a.y,a.w/2,a.h);
}
Rectangle b1 = new Rectangle(b.x,b.ry-b.h, b.w, b.h);
return a1.intersects(b1);//检测是否碰撞,是返回true
}
}
boolean isRectangle(Bullet a,Zombles b){
if (a.y+68 == b.ry||a.y+60 == b.ry) {
Rectangle a1 = new Rectangle(a.x,a.y,a.w,a.h);
Rectangle b1 = new Rectangle(b.x,b.ry-b.h, b.w, b.h);
return a1.intersects(b1);
}else{
return false;
}
}
boolean isRectangle(Plants a,Zombles b){
if (a.ry!=b.ry||b == null) {
return false;
}else{
Rectangle a1 = new Rectangle(a.rx,a.ry-a.h,a.w,a.h);
Rectangle b1 = new Rectangle(b.x,b.ry-b.h, b.w, b.h);
return a1.intersects(b1);
}
}
/**
* 图片水平翻转
* @param bufferedImage 目标图像
* @return
*/
public static BufferedImage flipImage(final BufferedImage bufferedImage){
int w = bufferedImage.getWidth();
int h = bufferedImage.getHeight();
BufferedImage img;
Graphics2D graphics2;
(graphics2 = (img = new BufferedImage(w,h,bufferedImage
.getColorModel().getTransparency())).createGraphics())
.drawImage(bufferedImage,0,0,w,h,w,0,0,h,null);
graphics2.dispose();
return img;
}
}

53
src/pnf/Zombles.java Normal file
View File

@ -0,0 +1,53 @@
package pnf;
import java.util.Random;
import javax.swing.ImageIcon;
public class Zombles {
/**僵尸数组*/
static ImageIcon[] js = new ImageIcon[6];
static ImageIcon[] js_1 = new ImageIcon[6];
ImageIcon rjs;
int ij;
/**属性*/
int w,h;
/**血量*/
int blood;
static int bx;
/**坐标*/
int x;
static int[] y = new int[5];
int iy,ry;
/**僵尸速度*/
int speed,s;
static {
for (int i = 0; i < y.length; i++) {
y[i] = 191+i*100;
}
for (int i = 0; i < js.length; i++) {
js[i] = new ImageIcon("lib/js"+(i+1)+".gif");
}
// for (int i = 0; i < js.length; i++) {
// js_1[i] = new ImageIcon("lib/js"+(i+1)+"_1.gif");
// }
}
public Zombles() {//随机僵尸种类,位置
Random r = new Random();
ij = r.nextInt(js.length);
rjs = js[ij];
blood = (ij+1)*10;
w = rjs.getIconWidth();
h = rjs.getIconHeight();
iy = r.nextInt(y.length);
ry = y[iy];
speed = r.nextInt(4)+1;
s = speed;
x = 1200;
}
/**僵尸行走*/
public void step(){
x -= speed;
}
}

BIN
素材/pg111.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
素材/pg1110.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
素材/pg112.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
素材/pg113.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
素材/pg114.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
素材/pg115.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
素材/pg116.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
素材/pg117.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
素材/pg118.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Some files were not shown because too many files have changed in this diff Show More