Java实现的经典坦克大战小游戏
先看一下游戏结构:
有点多,没有耐心的可以不用看,这里先给出链接吧!
云链接:经典坦克大战
提取码:s9ai
这里就不介绍功能了,贴了一张游戏运行的截图,具体的功能自己去看吧:
废话不多说,给出代码:
BombTank.java
类
import java.util.ArrayList;
import java.awt.*;
import java.awt.event.*;
import java.util.List;
import javax.swing.JOptionPane;
public class TankClient extends Frame implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 1L;
public static final int Fram_width = 800; // 静态全局窗口大小
public static final int Fram_length = 600;
public static boolean printable = true;
MenuBar jmb = null;
Menu jm1 = null, jm2 = null, jm3 = null, jm4 = null;
MenuItem jmi1 = null, jmi2 = null, jmi3 = null, jmi4 = null, jmi5 = null,
jmi6 = null, jmi7 = null, jmi8 = null, jmi9 = null;
Image screenImage = null;
Tank homeTank = new Tank(300, 560, true, Direction.STOP, this);// 实例化坦克
GetBlood blood = new GetBlood(); // 实例化生命
Home home = new Home(373, 545, this);// 实例化home
List<River> theRiver = new ArrayList<River>();
List<Tank> tanks = new ArrayList<Tank>();
List<BombTank> bombTanks = new ArrayList<BombTank>();
List<Bullets> bullets = new ArrayList<Bullets>();
List<Tree> trees = new ArrayList<Tree>();
List<CommonWall> homeWall = new ArrayList<CommonWall>(); // 实例化对象容器
List<CommonWall> otherWall = new ArrayList<CommonWall>();
List<MetalWall> metalWall = new ArrayList<MetalWall>();
public void update(Graphics g) {
screenImage = this.createImage(Fram_width, Fram_length);
Graphics gps = screenImage.getGraphics();
Color c = gps.getColor();
gps.setColor(Color.GRAY);
gps.fillRect(0, 0, Fram_width, Fram_length);
gps.setColor(c);
framPaint(gps);
g.drawImage(screenImage, 0, 0, null);
}
public void framPaint(Graphics g) {
Color c = g.getColor();
g.setColor(Color.green); // 设置字体显示属性
Font f1 = g.getFont();
g.setFont(new Font("TimesRoman", Font.BOLD, 20));
g.drawString("区域内还有敌方坦克: ", 200, 70);
g.setFont(new Font("TimesRoman", Font.ITALIC, 30));
g.drawString("" + tanks.size(), 400, 70);
g.setFont(new Font("TimesRoman", Font.BOLD, 20));
g.drawString("剩余生命值: ", 500, 70);
g.setFont(new Font("TimesRoman", Font.ITALIC, 30));
g.drawString("" + homeTank.getLife(), 650, 70);
g.setFont(f1);
if (tanks.size() == 0 && home.isLive() && homeTank.isLive()) {
Font f = g.getFont();
g.setFont(new Font("TimesRoman", Font.BOLD, 60)); // 判断是否赢得比赛
this.otherWall.clear();
g.drawString("你赢了! ", 310, 300);
g.setFont(f);
}
if (homeTank.isLive() == false) {
Font f = g.getFont();
g.setFont(new Font("TimesRoman", Font.BOLD, 40));
tanks.clear();
bullets.clear();
g.setFont(f);
}
g.setColor(c);
for (int i = 0; i < theRiver.size(); i++) { // 画出河流
River r = theRiver.get(i);
r.draw(g);
}
for (int i = 0; i < theRiver.size(); i++) {
River r = theRiver.get(i);
homeTank.collideRiver(r);
r.draw(g);
}
home.draw(g); // 画出home
homeTank.draw(g);// 画出自己家的坦克
homeTank.eat(blood);// 充满血--生命值
for (int i = 0; i < bullets.size(); i++) { // 对每一个子弹
Bullets m = bullets.get(i);
m.hitTanks(tanks); // 每一个子弹打到坦克上
m.hitTank(homeTank); // 每一个子弹打到自己家的坦克上时
m.hitHome(); // 每一个子弹打到家里是
for (int j = 0; j < metalWall.size(); j++) { // 每一个子弹打到金属墙上
MetalWall mw = metalWall.get(j);
m.hitWall(mw);
}
for (int j = 0; j < otherWall.size(); j++) {// 每一个子弹打到其他墙上
CommonWall w = otherWall.get(j);
m.hitWall(w);
}
for (int j = 0; j < homeWall.size(); j++) {// 每一个子弹打到家的墙上
CommonWall cw = homeWall.get(j);
m.hitWall(cw);
}
m.draw(g); // 画出效果图
}
for (int i = 0; i < tanks.size(); i++) {
Tank t = tanks.get(i); // 获得键值对的键
for (int j = 0; j < homeWall.size(); j++) {
CommonWall cw = homeWall.get(j);
t.collideWithWall(cw); // 每一个坦克撞到家里的墙时
cw.draw(g);
}
for (int j = 0; j < otherWall.size(); j++) { // 每一个坦克撞到家以外的墙
CommonWall cw = otherWall.get(j);
t.collideWithWall(cw);
cw.draw(g);
}
for (int j = 0; j < metalWall.size(); j++) { // 每一个坦克撞到金属墙
MetalWall mw = metalWall.get(j);
t.collideWithWall(mw);
mw.draw(g);
}
for (int j = 0; j < theRiver.size(); j++) {
River r = theRiver.get(j); // 每一个坦克撞到河流时
t.collideRiver(r);
r.draw(g);
// t.draw(g);
}
t.collideWithTanks(tanks); // 撞到自己的人
t.collideHome(home);
t.draw(g);
}
blood.draw(g);
for (int i = 0; i < trees.size(); i++) { // 画出trees
Tree tr = trees.get(i);
tr.draw(g);
}
for (int i = 0; i < bombTanks.size(); i++) { // 画出爆炸效果
BombTank bt = bombTanks.get(i);
bt.draw(g);
}
for (int i = 0; i < otherWall.size(); i++) { // 画出otherWall
CommonWall cw = otherWall.get(i);
cw.draw(g);
}
for (int i = 0; i < metalWall.size(); i++) { // 画出metalWall
MetalWall mw = metalWall.get(i);
mw.draw(g);
}
homeTank.collideWithTanks(tanks);
homeTank.collideHome(home);
for (int i = 0; i < metalWall.size(); i++) {// 撞到金属墙
MetalWall w = metalWall.get(i);
homeTank.collideWithWall(w);
w.draw(g);
}
for (int i = 0; i < otherWall.size(); i++) {
CommonWall cw = otherWall.get(i);
homeTank.collideWithWall(cw);
cw.draw(g);
}
for (int i = 0; i < homeWall.size(); i++) { // 家里的坦克撞到自己家
CommonWall w = homeWall.get(i);
homeTank.collideWithWall(w);
w.draw(g);
}
}
public TankClient() {
// printable = false;
// 创建菜单及菜单选项
jmb = new MenuBar();
jm1 = new Menu("游戏");
jm2 = new Menu("暂停继续");
jm3 = new Menu("帮助");
jm4 = new Menu("游戏级别");
jm1.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体
jm2.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体
jm3.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体
jm4.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体
jmi1 = new MenuItem("重新开始");
jmi2 = new MenuItem("退出");
jmi3 = new MenuItem("暂停");
jmi4 = new MenuItem("继续");
jmi5 = new MenuItem("游戏说明");
jmi6 = new MenuItem("级别 Ⅰ");
jmi7 = new MenuItem("级别 Ⅱ");
jmi8 = new MenuItem("级别 Ⅲ");
jmi9 = new MenuItem("级别 Ⅳ");
jmi1.setFont(new Font("TimesRoman", Font.BOLD, 15));
jmi2.setFont(new Font("TimesRoman", Font.BOLD, 15));
jmi3.setFont(new Font("TimesRoman", Font.BOLD, 15));
jmi4.setFont(new Font("TimesRoman", Font.BOLD, 15));
jmi5.setFont(new Font("TimesRoman", Font.BOLD, 15));
jm1.add(jmi1);
jm1.add(jmi2);
jm2.add(jmi3);
jm2.add(jmi4);
jm3.add(jmi5);
jm4.add(jmi6);
jm4.add(jmi7);
jm4.add(jmi8);
jm4.add(jmi9);
jmb.add(jm1);
jmb.add(jm2);
jmb.add(jm4);
jmb.add(jm3);
jmi1.addActionListener(this);
jmi1.setActionCommand("NewGame");
jmi2.addActionListener(this);
jmi2.setActionCommand("Exit");
jmi3.addActionListener(this);
jmi3.setActionCommand("Stop");
jmi4.addActionListener(this);
jmi4.setActionCommand("Continue");
jmi5.addActionListener(this);
jmi5.setActionCommand("help");
jmi6.addActionListener(this);
jmi6.setActionCommand("leve Ⅰ");
jmi7.addActionListener(this);
jmi7.setActionCommand("level Ⅱ");
jmi8.addActionListener(this);
jmi8.setActionCommand("level Ⅲ");
jmi9.addActionListener(this);
jmi9.setActionCommand("level Ⅳ");
this.setMenuBar(jmb);// 菜单Bar放到JFrame上
this.setVisible(true);
for (int i = 0; i < 10; i++) { // 家的格局
if (i < 4)
homeWall.add(new CommonWall(350, 580 - 21 * i, this));
else if (i < 7)
homeWall.add(new CommonWall(372 + 22 * (i - 4), 517, this));
else
homeWall.add(new CommonWall(416, 538 + (i - 7) * 21, this));
}
for (int i = 0; i < 32; i++) {
if (i < 16) {
otherWall.add(new CommonWall(220 + 20 * i, 300, this)); // 普通墙布局
otherWall.add(new CommonWall(500 + 20 * i, 180, this));
otherWall.add(new CommonWall(200, 400 + 20 * i, this));
otherWall.add(new CommonWall(500, 400 + 20 * i, this));
} else if (i < 32) {
otherWall.add(new CommonWall(220 + 20 * (i - 16), 320, this));
otherWall.add(new CommonWall(500 + 20 * (i - 16), 220, this));
otherWall.add(new CommonWall(220, 400 + 20 * (i - 16), this));
otherWall.add(new CommonWall(520, 400 + 20 * (i - 16), this));
}
}
for (int i = 0; i < 20; i++) { // 金属墙布局
if (i < 10) {
metalWall.add(new MetalWall(140 + 30 * i, 150, this));
metalWall.add(new MetalWall(600, 400 + 20 * (i), this));
} else if (i < 20)
metalWall.add(new MetalWall(140 + 30 * (i - 10), 180, this));
else
metalWall.add(new MetalWall(500 + 30 * (i - 10), 160, this));
}
for (int i = 0; i < 4; i++) { // 树的布局
if (i < 4) {
trees.add(new Tree(0 + 30 * i, 360, this));
trees.add(new Tree(220 + 30 * i, 360, this));
trees.add(new Tree(440 + 30 * i, 360, this));
trees.add(new Tree(660 + 30 * i, 360, this));
}
}
theRiver.add(new River(85, 100, this));
for (int i = 0; i < 20; i++) { // 初始化20辆坦克
if (i < 9) // 设置坦克出现的位置
tanks.add(new Tank(150 + 70 * i, 40, false, Direction.D, this));
else if (i < 15)
tanks.add(new Tank(700, 140 + 50 * (i - 6), false, Direction.D,
this));
else
tanks
.add(new Tank(10, 50 * (i - 12), false, Direction.D,
this));
}
this.setSize(Fram_width, Fram_length); // 设置界面大小
this.setLocation(280, 50); // 设置界面出现的位置
this
.setTitle("※TanKeWar※ 《∷∷∷∷∷》 ReStart--R Fire--F");
this.addWindowListener(new WindowAdapter() { // 窗口监听关闭
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
this.setResizable(false);
this.setBackground(Color.GREEN);
this.setVisible(true);
this.addKeyListener(new KeyMonitor());// 键盘监听
new Thread(new PaintThread()).start(); // 线程启动
}
public static void main(String[] args) {
new TankClient(); // 实例化
}
private class PaintThread implements Runnable {
public void run() {
// TODO Auto-generated method stub
while (printable) {
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private class KeyMonitor extends KeyAdapter {
public void keyReleased(KeyEvent e) { // 监听键盘释放
homeTank.keyReleased(e);
}
public void keyPressed(KeyEvent e) { // 监听键盘按下
homeTank.keyPressed(e);
}
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("NewGame")) {
printable = false;
Object[] options = { "确定", "取消" };
int response = JOptionPane.showOptionDialog(this, "您确定开始新游戏!", "",
JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,
options, options[0]);
if (response == 0) {
printable = true;
this.dispose();
new TankClient();
} else {
printable = true;
new Thread(new PaintThread()).start(); // 线程启动
}
} else if (e.getActionCommand().endsWith("Stop")) {
printable = false;
} else if (e.getActionCommand().equals("Continue")) {
if (!printable) {
printable = true;
new Thread(new PaintThread()).start(); // 线程启动
}
// System.out.println("继续");
} else if (e.getActionCommand().equals("Exit")) {
printable = false;
Object[] options = { "确定", "取消" };
int response = JOptionPane.showOptionDialog(this, "您确认要退出吗", "",
JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,
options, options[0]);
if (response == 0) {
System.out.println("退出");
System.exit(0);
} else {
printable = true;
new Thread(new PaintThread()).start(); // 线程启动
}
} else if (e.getActionCommand().equals("help")) {
printable = false;
JOptionPane.showMessageDialog(null, "用 ↑ ↓ ← → 控制方向,F键--开火,R键--重新开始!",
"提示!", JOptionPane.INFORMATION_MESSAGE);
this.setVisible(true);
printable = true;
new Thread(new PaintThread()).start(); // 线程启动
} else if (e.getActionCommand().equals("level Ⅰ")) {
Tank.count = 12;
Tank.speedX = 6;
Tank.speedY = 6;
Bullets.speedX = 10;
Bullets.speedY = 10;
this.dispose();
new TankClient();
} else if (e.getActionCommand().equals("level Ⅱ")) {
Tank.count = 12;
Tank.speedX = 10;
Tank.speedY = 10;
Bullets.speedX = 12;
Bullets.speedY = 12;
this.dispose();
new TankClient();
} else if (e.getActionCommand().equals("level Ⅲ")) {
Tank.count = 20;
Tank.speedX = 14;
Tank.speedY = 14;
Bullets.speedX = 16;
Bullets.speedY = 16;
this.dispose();
new TankClient();
} else if (e.getActionCommand().equals("level Ⅳ")) {
Tank.count = 20;
Tank.speedX = 16;
Tank.speedY = 16;
Bullets.speedX = 18;
Bullets.speedY = 18;
this.dispose();
new TankClient();
}
}
}
Bullets.java
类
import java.awt.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Bullets {
public static int speedX = 10;
public static int speedY = 10; // 子弹的全局静态速度
public static final int width = 10;
public static final int length = 10;
private int x, y;
Direction diretion;
private boolean good;
private boolean live = true;
private TankClient tc;
private static Toolkit tk = Toolkit.getDefaultToolkit();
private static Image[] bulletImages = null;
private static Map<String, Image> imgs = new HashMap<String, Image>(); // 定义Map键值对,是不同方向对应不同的弹头
static {
bulletImages = new Image[] { // 不同方向的子弹
tk.getImage(Bullets.class.getClassLoader().getResource(
"images/bulletL.gif")),
tk.getImage(Bullets.class.getClassLoader().getResource(
"images/bulletU.gif")),
tk.getImage(Bullets.class.getClassLoader().getResource(
"images/bulletR.gif")),
tk.getImage(Bullets.class.getClassLoader().getResource(
"images/bulletD.gif")),
};
imgs.put("L", bulletImages[0]); // 加入Map容器
imgs.put("U", bulletImages[1]);
imgs.put("R", bulletImages[2]);
imgs.put("D", bulletImages[3]);
}
public Bullets(int x, int y, Direction dir) { // 构造函数1,传递位置和方向
this.x = x;
this.y = y;
this.diretion = dir;
}
// 构造函数2,接受另外两个参数
public Bullets(int x, int y, boolean good, Direction dir, TankClient tc) {
this(x, y, dir);
this.good = good;
this.tc = tc;
}
private void move() {
switch (diretion) {
case L:
x -= speedX; // 子弹不断向左进攻
break;
case U:
y -= speedY;
break;
case R:
x += speedX; // 字段不断向右
break;
case D:
y += speedY;
break;
case STOP:
break;
}
if (x < 0 || y < 0 || x > TankClient.Fram_width
|| y > TankClient.Fram_length) {
live = false;
}
}
public void draw(Graphics g) {
if (!live) {
tc.bullets.remove(this);
return;
}
switch (diretion) { // 选择不同方向的子弹
case L:
g.drawImage(imgs.get("L"), x, y, null);
break;
case U:
g.drawImage(imgs.get("U"), x, y, null);
break;
case R:
g.drawImage(imgs.get("R"), x, y, null);
break;
case D:
g.drawImage(imgs.get("D"), x, y, null);
break;
}
move(); // 调用子弹move()函数
}
public boolean isLive() { // 判读是否还活着
return live;
}
public Rectangle getRect() {
return new Rectangle(x, y, width, length);
}
public boolean hitTanks(List<Tank> tanks) {// 当子弹打到坦克时
for (int i = 0; i < tanks.size(); i++) {
if (hitTank(tanks.get(i))) { // 对每一个坦克,调用hitTank
return true;
}
}
return false;
}
public boolean hitTank(Tank t) { // 当子弹打到坦克上
if (this.live && this.getRect().intersects(t.getRect()) && t.isLive()
&& this.good != t.isGood()) {
BombTank e = new BombTank(t.getX(), t.getY(), tc);
tc.bombTanks.add(e);
if (t.isGood()) {
t.setLife(t.getLife() - 50); // 受一粒子弹寿命减少50,接受4枪就死,总生命值200
if (t.getLife() <= 0)
t.setLive(false); // 当寿命为0时,设置寿命为死亡状态
} else {
t.setLive(false);
}
this.live = false;
return true; // 射击成功,返回true
}
return false; // 否则返回false
}
public boolean hitWall(CommonWall w) { // 子弹打到CommonWall上
if (this.live && this.getRect().intersects(w.getRect())) {
this.live = false;
this.tc.otherWall.remove(w); // 子弹打到CommonWall墙上时则移除此击中墙
this.tc.homeWall.remove(w);
return true;
}
return false;
}
public boolean hitWall(MetalWall w) { // 子弹打到金属墙上
if (this.live && this.getRect().intersects(w.getRect())) {
this.live = false;
//this.tc.metalWall.remove(w); //子弹不能穿越金属墙
return true;
}
return false;
}
public boolean hitHome() { // 当子弹打到家时
if (this.live && this.getRect().intersects(tc.home.getRect())) {
this.live = false;
this.tc.home.setLive(false); // 当家接受一枪时就死亡
return true;
}
return false;
}
}
CommonWall.java
类
import java.awt.*;
public class CommonWall {
public static final int width = 20; //设置墙的固定参数
public static final int length = 20;
int x, y;
TankClient tc;
private static Toolkit tk = Toolkit.getDefaultToolkit();
private static Image[] wallImags = null;
static {
wallImags = new Image[] { // 储存commonWall的图片
tk.getImage(CommonWall.class.getResource("Images/commonWall.gif")), };
}
public CommonWall(int x, int y, TankClient tc) { // 构造函数
this.x = x;
this.y = y;
this.tc = tc; // 获得界面控制
}
public void draw(Graphics g) {// 画commonWall
g.drawImage(wallImags[0], x, y, null);
}
public Rectangle getRect() { //构造指定参数的长方形实例
return new Rectangle(x, y, width, length);
}
}
Direction.java
类
public enum Direction { //方向为枚举类
L, U, R, D, STOP
}
GetBlood.java
类
import java.awt.*;
import java.util.Random;
public class GetBlood {
public static final int width = 36;
public static final int length = 36;
private int x, y;
TankClient tc;
private static Random r = new Random();
int step = 0;
private boolean live = false;
private static Toolkit tk = Toolkit.getDefaultToolkit();
private static Image[] bloodImags = null;
static {
bloodImags = new Image[] { tk.getImage(CommonWall.class
.getResource("Images/hp.png")), };
}
private int[][] poition = { { 155, 196 }, { 500, 58 }, { 80, 340 },
{ 99, 199 }, { 345, 456 }, { 123, 321 }, { 258, 413 } };
public void draw(Graphics g) {
if (r.nextInt(100) > 98) {
this.live = true;
move();
}
if (!live)
return;
g.drawImage(bloodImags[0], x, y, null);
}
private void move() {
step++;
if (step == poition.length) {
step = 0;
}
x = poition[step][0];
y = poition[step][1];
}
public Rectangle getRect() { //返回长方形实例
return new Rectangle(x, y, width, length);
}
public boolean isLive() {//判断是否还活着
return live;
}
public void setLive(boolean live) { //设置生命
this.live = live;
}
}
MetalWall.java
类
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
public class MetalWall {
public static final int width = 30; // 设置金属墙的长宽静态全局参数
public static final int length = 30;
private int x, y;
TankClient tc;
private static Toolkit tk = Toolkit.getDefaultToolkit();
private static Image[] wallImags = null;
static {
wallImags = new Image[] { tk.getImage(CommonWall.class
.getResource("Images/metalWall.gif")), };
}
public MetalWall(int x, int y, TankClient tc) {// 构造函数,传递要构造的长宽并赋值
this.x = x;
this.y = y;
this.tc = tc;
}
public void draw(Graphics g) { // 画金属墙
g.drawImage(wallImags[0], x, y, null);
}
public Rectangle getRect() { // 构造指定参数的长方形实例
return new Rectangle(x, y, width, length);
}
}
River.java
类
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
public class River {
public static final int riverWidth = 40;
public static final int riverLength = 100;//静态全局变量
private int x, y;
TankClient tc ;
private static Toolkit tk = Toolkit.getDefaultToolkit();
private static Image[] riverImags = null;
static { //存储图片
riverImags = new Image[]{
tk.getImage(CommonWall.class.getResource("Images/river.jpg")),
};
}
public River(int x, int y, TankClient tc) { //River的构造方法
this.x = x;
this.y = y;
this.tc = tc; //获得控制
}
public void draw(Graphics g) {
g.drawImage(riverImags[0],x, y, null); //在对应X,Y出画河
}
public static int getRiverWidth() {
return riverWidth;
}
public static int getRiverLength() {
return riverLength;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public Rectangle getRect() {
return new Rectangle(x, y, riverWidth, riverLength);
}
}
Tank.java
类
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Tank {
public static int speedX = 6, speedY =6; // 静态全局变量速度---------可以作为扩张来设置级别,速度快的话比较难
public static int count = 0;
public static final int width = 35, length = 35; // 坦克的全局大小,具有不可改变性
private Direction direction = Direction.STOP; // 初始化状态为静止
private Direction Kdirection = Direction.U; // 初始化方向为向上
TankClient tc;
private boolean good;
private int x, y;
private int oldX, oldY;
private boolean live = true; // 初始化为活着
private int life = 200; // 初始生命值
private static Random r = new Random();
private int step = r.nextInt(10)+5 ; // 产生一个随机数,随机模拟坦克的移动路径
private boolean bL = false, bU = false, bR = false, bD = false;
private static Toolkit tk = Toolkit.getDefaultToolkit();// 控制面板
private static Image[] tankImags = null; // 存储全局静态
static {
tankImags = new Image[] {
tk.getImage(BombTank.class.getResource("Images/tankD.gif")),
tk.getImage(BombTank.class.getResource("Images/tankU.gif")),
tk.getImage(BombTank.class.getResource("Images/tankL.gif")),
tk.getImage(BombTank.class.getResource("Images/tankR.gif")), };
}
public Tank(int x, int y, boolean good) {// Tank的构造函数1
this.x = x;
this.y = y;
this.oldX = x;
this.oldY = y;
this.good = good;
}
public Tank(int x, int y, boolean good, Direction dir, TankClient tc) {// Tank的构造函数2
this(x, y, good);
this.direction = dir;
this.tc = tc;
}
public void draw(Graphics g) {
if (!live) {
if (!good) {
tc.tanks.remove(this); // 删除无效的
}
return;
}
if (good)
new DrawBloodbBar().draw(g); // 创造一个血包
switch (Kdirection) {
//根据方向选择坦克的图片
case D:
g.drawImage(tankImags[0], x, y, null);
break;
case U:
g.drawImage(tankImags[1], x, y, null);
break;
case L:
g.drawImage(tankImags[2], x, y, null);
break;
case R:
g.drawImage(tankImags[3], x, y, null);
break;
}
move(); //调用move函数
}
void move() {
this.oldX = x;
this.oldY = y;
switch (direction) { //选择移动方向
case L:
x -= speedX;
break;
case U:
y -= speedY;
break;
case R:
x += speedX;
break;
case D:
y += speedY;
break;
case STOP:
break;
}
if (this.direction != Direction.STOP) {
this.Kdirection = this.direction;
}
if (x < 0)
x = 0;
if (y < 40) //防止走出规定区域
y = 40;
if (x + Tank.width > TankClient.Fram_width) //超过区域则恢复到边界
x = TankClient.Fram_width - Tank.width;
if (y + Tank.length > TankClient.Fram_length)
y = TankClient.Fram_length - Tank.length;
if (!good) {
Direction[] directons = Direction.values();
if (step == 0) {
step = r.nextInt(12) + 3; //产生随机路径
int rn = r.nextInt(directons.length);
direction = directons[rn]; //产生随机方向
}
step--;
if (r.nextInt(40) > 38)//产生随机数,控制敌人开火
this.fire();
}
}
private void changToOldDir() {
x = oldX;
y = oldY;
}
public void keyPressed(KeyEvent e) { //接受键盘事件
int key = e.getKeyCode();
switch (key) {
case KeyEvent.VK_R: //当按下R时,重新开始游戏
tc.tanks.clear(); //清理
tc.bullets.clear();
tc.trees.clear();
tc.otherWall.clear();
tc.homeWall.clear();
tc.metalWall.clear();
tc.homeTank.setLive(false);
if (tc.tanks.size() == 0) { //当在区域中没有坦克时,就出来坦克
for (int i = 0; i < 20; i++) {
if (i < 9) //设置坦克出现的位置
tc.tanks.add(new Tank(150 + 70 * i, 40, false,
Direction.R, tc));
else if (i < 15)
tc.tanks.add(new Tank(700, 140 + 50 * (i -6), false,
Direction.D, tc));
else
tc.tanks.add(new Tank(10, 50 * (i - 12), false,
Direction.L, tc));
}
}
tc.homeTank = new Tank(300, 560, true, Direction.STOP, tc);//设置自己出现的位置
if (!tc.home.isLive()) //将home重置生命
tc.home.setLive(true);
new TankClient(); //重新创建面板
break;
case KeyEvent.VK_RIGHT: //监听向右键
bR = true;
break;
case KeyEvent.VK_LEFT://监听向左键
bL = true;
break;
case KeyEvent.VK_UP: //监听向上键
bU = true;
break;
case KeyEvent.VK_DOWN://监听向下键
bD = true;
break;
}
decideDirection();//调用函数确定移动方向
}
void decideDirection() {
if (!bL && !bU && bR && !bD) //向右移动
direction = Direction.R;
else if (bL && !bU && !bR && !bD) //向左移
direction = Direction.L;
else if (!bL && bU && !bR && !bD) //向上移动
direction = Direction.U;
else if (!bL && !bU && !bR && bD) //向下移动
direction = Direction.D;
else if (!bL && !bU && !bR && !bD)
direction = Direction.STOP; //没有按键,就保持不动
}
public void keyReleased(KeyEvent e) { //键盘释放监听
int key = e.getKeyCode();
switch (key) {
case KeyEvent.VK_F:
fire();
break;
case KeyEvent.VK_RIGHT:
bR = false;
break;
case KeyEvent.VK_LEFT:
bL = false;
break;
case KeyEvent.VK_UP:
bU = false;
break;
case KeyEvent.VK_DOWN:
bD = false;
break;
}
decideDirection(); //释放键盘后确定移动方向
}
public Bullets fire() { //开火方法
if (!live)
return null;
int x = this.x + Tank.width / 2 - Bullets.width / 2; //开火位置
int y = this.y + Tank.length / 2 - Bullets.length / 2;
Bullets m = new Bullets(x, y + 2, good, Kdirection, this.tc); //没有给定方向时,向原来的方向发火
tc.bullets.add(m);
return m;
}
public Rectangle getRect() {
return new Rectangle(x, y, width, length);
}
public boolean isLive() {
return live;
}
public void setLive(boolean live) {
this.live = live;
}
public boolean isGood() {
return good;
}
public boolean collideWithWall(CommonWall w) { //碰撞到普通墙时
if (this.live && this.getRect().intersects(w.getRect())) {
this.changToOldDir(); //转换到原来的方向上去
return true;
}
return false;
}
public boolean collideWithWall(MetalWall w) { //撞到金属墙
if (this.live && this.getRect().intersects(w.getRect())) {
this.changToOldDir();
return true;
}
return false;
}
public boolean collideRiver(River r) { //撞到河流的时候
if (this.live && this.getRect().intersects(r.getRect())) {
this.changToOldDir();
return true;
}
return false;
}
public boolean collideHome(Home h) { //撞到家的时候
if (this.live && this.getRect().intersects(h.getRect())) {
this.changToOldDir();
return true;
}
return false;
}
public boolean collideWithTanks(java.util.List<Tank> tanks) {//撞到坦克时
for (int i = 0; i < tanks.size(); i++) {
Tank t = tanks.get(i);
if (this != t) {
if (this.live && t.isLive()
&& this.getRect().intersects(t.getRect())) {
this.changToOldDir();
t.changToOldDir();
return true;
}
}
}
return false;
}
public int getLife() {
return life;
}
public void setLife(int life) {
this.life = life;
}
private class DrawBloodbBar {
public void draw(Graphics g) {
Color c = g.getColor();
g.setColor(Color.RED);
g.drawRect(375, 585, width, 10);
int w = width * life / 200;
g.fillRect(375, 585, w, 10);
g.setColor(c);
}
}
public boolean eat(GetBlood b) {
if (this.live && b.isLive() && this.getRect().intersects(b.getRect())) {
if(this.life<=100)
this.life = this.life+100; //每吃一个,增加100生命点
else
this.life = 200;
b.setLive(false);
return true;
}
return false;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
Tree.java
类
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
//设置界面树和丛林
public class Tree {
public static final int width = 30;
public static final int length = 30;
int x, y;
TankClient tc ;
private static Toolkit tk = Toolkit.getDefaultToolkit();
private static Image[] treeImags = null;
static {
treeImags = new Image[]{
tk.getImage(CommonWall.class.getResource("Images/tree.gif")),
};
}
public Tree(int x, int y, TankClient tc) { //Tree的构造方法,传递x,y和tc对象
this.x = x;
this.y = y;
this.tc = tc;
}
public void draw(Graphics g) { //画出树
g.drawImage(treeImags[0],x, y, null);
}
}
TankClient.java 类
import java.util.ArrayList;
import java.awt.*;
import java.awt.event.*;
import java.util.List;
import javax.swing.JOptionPane;
public class TankClient extends Frame implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 1L;
public static final int Fram_width = 800; // 静态全局窗口大小
public static final int Fram_length = 600;
public static boolean printable = true;
MenuBar jmb = null;
Menu jm1 = null, jm2 = null, jm3 = null, jm4 = null;
MenuItem jmi1 = null, jmi2 = null, jmi3 = null, jmi4 = null, jmi5 = null,
jmi6 = null, jmi7 = null, jmi8 = null, jmi9 = null;
Image screenImage = null;
Tank homeTank = new Tank(300, 560, true, Direction.STOP, this);// 实例化坦克
GetBlood blood = new GetBlood(); // 实例化生命
Home home = new Home(373, 545, this);// 实例化home
List<River> theRiver = new ArrayList<River>();
List<Tank> tanks = new ArrayList<Tank>();
List<BombTank> bombTanks = new ArrayList<BombTank>();
List<Bullets> bullets = new ArrayList<Bullets>();
List<Tree> trees = new ArrayList<Tree>();
List<CommonWall> homeWall = new ArrayList<CommonWall>(); // 实例化对象容器
List<CommonWall> otherWall = new ArrayList<CommonWall>();
List<MetalWall> metalWall = new ArrayList<MetalWall>();
public void update(Graphics g) {
screenImage = this.createImage(Fram_width, Fram_length);
Graphics gps = screenImage.getGraphics();
Color c = gps.getColor();
gps.setColor(Color.GRAY);
gps.fillRect(0, 0, Fram_width, Fram_length);
gps.setColor(c);
framPaint(gps);
g.drawImage(screenImage, 0, 0, null);
}
public void framPaint(Graphics g) {
Color c = g.getColor();
g.setColor(Color.green); // 设置字体显示属性
Font f1 = g.getFont();
g.setFont(new Font("TimesRoman", Font.BOLD, 20));
g.drawString("区域内还有敌方坦克: ", 200, 70);
g.setFont(new Font("TimesRoman", Font.ITALIC, 30));
g.drawString("" + tanks.size(), 400, 70);
g.setFont(new Font("TimesRoman", Font.BOLD, 20));
g.drawString("剩余生命值: ", 500, 70);
g.setFont(new Font("TimesRoman", Font.ITALIC, 30));
g.drawString("" + homeTank.getLife(), 650, 70);
g.setFont(f1);
if (tanks.size() == 0 && home.isLive() && homeTank.isLive()) {
Font f = g.getFont();
g.setFont(new Font("TimesRoman", Font.BOLD, 60)); // 判断是否赢得比赛
this.otherWall.clear();
g.drawString("你赢了! ", 310, 300);
g.setFont(f);
}
if (homeTank.isLive() == false) {
Font f = g.getFont();
g.setFont(new Font("TimesRoman", Font.BOLD, 40));
tanks.clear();
bullets.clear();
g.setFont(f);
}
g.setColor(c);
for (int i = 0; i < theRiver.size(); i++) { // 画出河流
River r = theRiver.get(i);
r.draw(g);
}
for (int i = 0; i < theRiver.size(); i++) {
River r = theRiver.get(i);
homeTank.collideRiver(r);
r.draw(g);
}
home.draw(g); // 画出home
homeTank.draw(g);// 画出自己家的坦克
homeTank.eat(blood);// 充满血--生命值
for (int i = 0; i < bullets.size(); i++) { // 对每一个子弹
Bullets m = bullets.get(i);
m.hitTanks(tanks); // 每一个子弹打到坦克上
m.hitTank(homeTank); // 每一个子弹打到自己家的坦克上时
m.hitHome(); // 每一个子弹打到家里是
for (int j = 0; j < metalWall.size(); j++) { // 每一个子弹打到金属墙上
MetalWall mw = metalWall.get(j);
m.hitWall(mw);
}
for (int j = 0; j < otherWall.size(); j++) {// 每一个子弹打到其他墙上
CommonWall w = otherWall.get(j);
m.hitWall(w);
}
for (int j = 0; j < homeWall.size(); j++) {// 每一个子弹打到家的墙上
CommonWall cw = homeWall.get(j);
m.hitWall(cw);
}
m.draw(g); // 画出效果图
}
for (int i = 0; i < tanks.size(); i++) {
Tank t = tanks.get(i); // 获得键值对的键
for (int j = 0; j < homeWall.size(); j++) {
CommonWall cw = homeWall.get(j);
t.collideWithWall(cw); // 每一个坦克撞到家里的墙时
cw.draw(g);
}
for (int j = 0; j < otherWall.size(); j++) { // 每一个坦克撞到家以外的墙
CommonWall cw = otherWall.get(j);
t.collideWithWall(cw);
cw.draw(g);
}
for (int j = 0; j < metalWall.size(); j++) { // 每一个坦克撞到金属墙
MetalWall mw = metalWall.get(j);
t.collideWithWall(mw);
mw.draw(g);
}
for (int j = 0; j < theRiver.size(); j++) {
River r = theRiver.get(j); // 每一个坦克撞到河流时
t.collideRiver(r);
r.draw(g);
// t.draw(g);
}
t.collideWithTanks(tanks); // 撞到自己的人
t.collideHome(home);
t.draw(g);
}
blood.draw(g);
for (int i = 0; i < trees.size(); i++) { // 画出trees
Tree tr = trees.get(i);
tr.draw(g);
}
for (int i = 0; i < bombTanks.size(); i++) { // 画出爆炸效果
BombTank bt = bombTanks.get(i);
bt.draw(g);
}
for (int i = 0; i < otherWall.size(); i++) { // 画出otherWall
CommonWall cw = otherWall.get(i);
cw.draw(g);
}
for (int i = 0; i < metalWall.size(); i++) { // 画出metalWall
MetalWall mw = metalWall.get(i);
mw.draw(g);
}
homeTank.collideWithTanks(tanks);
homeTank.collideHome(home);
for (int i = 0; i < metalWall.size(); i++) {// 撞到金属墙
MetalWall w = metalWall.get(i);
homeTank.collideWithWall(w);
w.draw(g);
}
for (int i = 0; i < otherWall.size(); i++) {
CommonWall cw = otherWall.get(i);
homeTank.collideWithWall(cw);
cw.draw(g);
}
for (int i = 0; i < homeWall.size(); i++) { // 家里的坦克撞到自己家
CommonWall w = homeWall.get(i);
homeTank.collideWithWall(w);
w.draw(g);
}
}
public TankClient() {
// printable = false;
// 创建菜单及菜单选项
jmb = new MenuBar();
jm1 = new Menu("游戏");
jm2 = new Menu("暂停继续");
jm3 = new Menu("帮助");
jm4 = new Menu("游戏级别");
jm1.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体
jm2.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体
jm3.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体
jm4.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体
jmi1 = new MenuItem("重新开始");
jmi2 = new MenuItem("退出");
jmi3 = new MenuItem("暂停");
jmi4 = new MenuItem("继续");
jmi5 = new MenuItem("游戏说明");
jmi6 = new MenuItem("级别 Ⅰ");
jmi7 = new MenuItem("级别 Ⅱ");
jmi8 = new MenuItem("级别 Ⅲ");
jmi9 = new MenuItem("级别 Ⅳ");
jmi1.setFont(new Font("TimesRoman", Font.BOLD, 15));
jmi2.setFont(new Font("TimesRoman", Font.BOLD, 15));
jmi3.setFont(new Font("TimesRoman", Font.BOLD, 15));
jmi4.setFont(new Font("TimesRoman", Font.BOLD, 15));
jmi5.setFont(new Font("TimesRoman", Font.BOLD, 15));
jm1.add(jmi1);
jm1.add(jmi2);
jm2.add(jmi3);
jm2.add(jmi4);
jm3.add(jmi5);
jm4.add(jmi6);
jm4.add(jmi7);
jm4.add(jmi8);
jm4.add(jmi9);
jmb.add(jm1);
jmb.add(jm2);
jmb.add(jm4);
jmb.add(jm3);
jmi1.addActionListener(this);
jmi1.setActionCommand("NewGame");
jmi2.addActionListener(this);
jmi2.setActionCommand("Exit");
jmi3.addActionListener(this);
jmi3.setActionCommand("Stop");
jmi4.addActionListener(this);
jmi4.setActionCommand("Continue");
jmi5.addActionListener(this);
jmi5.setActionCommand("help");
jmi6.addActionListener(this);
jmi6.setActionCommand("leve Ⅰ");
jmi7.addActionListener(this);
jmi7.setActionCommand("level Ⅱ");
jmi8.addActionListener(this);
jmi8.setActionCommand("level Ⅲ");
jmi9.addActionListener(this);
jmi9.setActionCommand("level Ⅳ");
this.setMenuBar(jmb);// 菜单Bar放到JFrame上
this.setVisible(true);
for (int i = 0; i < 10; i++) { // 家的格局
if (i < 4)
homeWall.add(new CommonWall(350, 580 - 21 * i, this));
else if (i < 7)
homeWall.add(new CommonWall(372 + 22 * (i - 4), 517, this));
else
homeWall.add(new CommonWall(416, 538 + (i - 7) * 21, this));
}
for (int i = 0; i < 32; i++) {
if (i < 16) {
otherWall.add(new CommonWall(220 + 20 * i, 300, this)); // 普通墙布局
otherWall.add(new CommonWall(500 + 20 * i, 180, this));
otherWall.add(new CommonWall(200, 400 + 20 * i, this));
otherWall.add(new CommonWall(500, 400 + 20 * i, this));
} else if (i < 32) {
otherWall.add(new CommonWall(220 + 20 * (i - 16), 320, this));
otherWall.add(new CommonWall(500 + 20 * (i - 16), 220, this));
otherWall.add(new CommonWall(220, 400 + 20 * (i - 16), this));
otherWall.add(new CommonWall(520, 400 + 20 * (i - 16), this));
}
}
for (int i = 0; i < 20; i++) { // 金属墙布局
if (i < 10) {
metalWall.add(new MetalWall(140 + 30 * i, 150, this));
metalWall.add(new MetalWall(600, 400 + 20 * (i), this));
} else if (i < 20)
metalWall.add(new MetalWall(140 + 30 * (i - 10), 180, this));
else
metalWall.add(new MetalWall(500 + 30 * (i - 10), 160, this));
}
for (int i = 0; i < 4; i++) { // 树的布局
if (i < 4) {
trees.add(new Tree(0 + 30 * i, 360, this));
trees.add(new Tree(220 + 30 * i, 360, this));
trees.add(new Tree(440 + 30 * i, 360, this));
trees.add(new Tree(660 + 30 * i, 360, this));
}
}
theRiver.add(new River(85, 100, this));
for (int i = 0; i < 20; i++) { // 初始化20辆坦克
if (i < 9) // 设置坦克出现的位置
tanks.add(new Tank(150 + 70 * i, 40, false, Direction.D, this));
else if (i < 15)
tanks.add(new Tank(700, 140 + 50 * (i - 6), false, Direction.D,
this));
else
tanks
.add(new Tank(10, 50 * (i - 12), false, Direction.D,
this));
}
this.setSize(Fram_width, Fram_length); // 设置界面大小
this.setLocation(280, 50); // 设置界面出现的位置
this
.setTitle("※TanKeWar※ 《∷∷∷∷∷》 ReStart--R Fire--F");
this.addWindowListener(new WindowAdapter() { // 窗口监听关闭
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
this.setResizable(false);
this.setBackground(Color.GREEN);
this.setVisible(true);
this.addKeyListener(new KeyMonitor());// 键盘监听
new Thread(new PaintThread()).start(); // 线程启动
}
public static void main(String[] args) {
new TankClient(); // 实例化
}
private class PaintThread implements Runnable {
public void run() {
// TODO Auto-generated method stub
while (printable) {
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private class KeyMonitor extends KeyAdapter {
public void keyReleased(KeyEvent e) { // 监听键盘释放
homeTank.keyReleased(e);
}
public void keyPressed(KeyEvent e) { // 监听键盘按下
homeTank.keyPressed(e);
}
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("NewGame")) {
printable = false;
Object[] options = { "确定", "取消" };
int response = JOptionPane.showOptionDialog(this, "您确定开始新游戏!", "",
JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,
options, options[0]);
if (response == 0) {
printable = true;
this.dispose();
new TankClient();
} else {
printable = true;
new Thread(new PaintThread()).start(); // 线程启动
}
} else if (e.getActionCommand().endsWith("Stop")) {
printable = false;
} else if (e.getActionCommand().equals("Continue")) {
if (!printable) {
printable = true;
new Thread(new PaintThread()).start(); // 线程启动
}
// System.out.println("继续");
} else if (e.getActionCommand().equals("Exit")) {
printable = false;
Object[] options = { "确定", "取消" };
int response = JOptionPane.showOptionDialog(this, "您确认要退出吗", "",
JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,
options, options[0]);
if (response == 0) {
System.out.println("退出");
System.exit(0);
} else {
printable = true;
new Thread(new PaintThread()).start(); // 线程启动
}
} else if (e.getActionCommand().equals("help")) {
printable = false;
JOptionPane.showMessageDialog(null, "用 ↑ ↓ ← → 控制方向,F键--开火,R键--重新开始!",
"提示!", JOptionPane.INFORMATION_MESSAGE);
this.setVisible(true);
printable = true;
new Thread(new PaintThread()).start(); // 线程启动
} else if (e.getActionCommand().equals("level Ⅰ")) {
Tank.count = 12;
Tank.speedX = 6;
Tank.speedY = 6;
Bullets.speedX = 10;
Bullets.speedY = 10;
this.dispose();
new TankClient();
} else if (e.getActionCommand().equals("level Ⅱ")) {
Tank.count = 12;
Tank.speedX = 10;
Tank.speedY = 10;
Bullets.speedX = 12;
Bullets.speedY = 12;
this.dispose();
new TankClient();
} else if (e.getActionCommand().equals("level Ⅲ")) {
Tank.count = 20;
Tank.speedX = 14;
Tank.speedY = 14;
Bullets.speedX = 16;
Bullets.speedY = 16;
this.dispose();
new TankClient();
} else if (e.getActionCommand().equals("level Ⅳ")) {
Tank.count = 20;
Tank.speedX = 16;
Tank.speedY = 16;
Bullets.speedX = 18;
Bullets.speedY = 18;
this.dispose();
new TankClient();
}
}
}
home.java
类
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
public class Home {
private int x, y;
private TankClient tc;
public static final int width = 30, length = 30; // 全局静态变量长宽
private boolean live = true;
private static Toolkit tk = Toolkit.getDefaultToolkit(); // 全局静态变量
private static Image[] homeImags = null;
static {
homeImags = new Image[] { tk.getImage(CommonWall.class
.getResource("Images/home.jpg")), };
}
public Home(int x, int y, TankClient tc) {// 构造函数,传递Home的参数并赋值
this.x = x;
this.y = y;
this.tc = tc; // 获得控制
}
public void gameOver(Graphics g) {
tc.tanks.clear();// 作清理页面工作
tc.metalWall.clear();
tc.otherWall.clear();
tc.bombTanks.clear();
tc.theRiver.clear();
tc.trees.clear();
tc.bullets.clear();
tc.homeTank.setLive(false);
Color c = g.getColor(); // 设置参数
g.setColor(Color.green);
Font f = g.getFont();
g.setFont(new Font(" ", Font.PLAIN, 40));
g.drawString("你输了!", 220, 250);
g.drawString(" 游戏结束! ", 220, 300);
g.setFont(f);
g.setColor(c);
}
public void draw(Graphics g) {
if (live) { // 如果活着,则画出home
g.drawImage(homeImags[0], x, y, null);
for (int i = 0; i < tc.homeWall.size(); i++) {
CommonWall w = tc.homeWall.get(i);
w.draw(g);
}
} else {
gameOver(g); // 调用游戏结束
}
}
public boolean isLive() { // 判读是否还活着
return live;
}
public void setLive(boolean live) { // 设置生命
this.live = live;
}
public Rectangle getRect() { // 返回长方形实例
return new Rectangle(x, y, width, length);
}
}
有点多,主要也不是让你在页面上看的,闲得无聊,贴了一下。