1.操作方法与说明
操作:W:上 A:左 S:下 D:右 J:发子弹 K:大招
说明:红色坦克为自己的坦克,蓝色为敌方坦克,我防坦克右100血,每次被攻击到就会减少10血,直至死亡,我方坦克阵亡后,按F2可以重新开始。
2.坦克大战程序
将以下Class,放在一个包内,运行TankWarClient即可
效果图
/**
* 坦克游戏主客户端,负责响应机制与主要操作等
*/
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
public class TankWarClient extends Frame {
private static final long serialVersionUID = 1L;
Tank MyTank=new Tank(50,50,true,this);//创建我方坦克
List<Missile> missiles=new ArrayList<Missile>();//子弹容器
List<Explode> explodes =new ArrayList<Explode>();//爆炸容器
List<Tank> tanks =new ArrayList<Tank>();//坦克容器
List<Wall> walls=new ArrayList<Wall>();//墙
List<Blood>bloods=new ArrayList<Blood>();//血块
Random r=new Random();
Image offImage=null;
public static final int GAME_WEITH=800;
public static final int GAME_HEIGHT=600;
public void paint(Graphics g) {
g.drawString("missiles count:"+missiles.size(), 10, 50);//显示出子弹个数
g.drawString("explodes count:"+explodes.size(), 10, 70);//爆炸个数
g.drawString("tanks count:"+tanks.size(), 10, 90);//坦克个数
g.drawString("tank life:"+MyTank.getGlife(), 10, 120);//坦克的剩余生命
//画出血块
for(int i=0;i<bloods.size();i++){
Blood bl=bloods.get(i);
bl.hitTanks(tanks);//血块碰撞坦克检测
bl.draw(g);
}
for(int i=0;i<missiles.size();i++){
Missile Mi=missiles.get(i);
Mi.hitTanks(tanks);
Mi.hitWalls(walls);
Mi.draw(g);
}
for(int i=0;i<explodes.size();i++){
Explode Ex=explodes.get(i);
Ex.draw(g);
}
for(int i=0;i<tanks.size();i++){
Tank tan=tanks.get(i);
tan.hitWalls(walls);
tan.hitTanks(tanks);
tan.draw(g);
}
for(int i=0;i<walls.size();i++){
Wall wa=walls.get(i);
wa.draw(g);
}
int ra=r.nextInt(400);
if(ra==10){
//随机加入血块
bloods.add(new Blood(200,200,this));
}
}
//设置双缓冲,防止图片闪烁
public void update(Graphics g) {
if(offImage==null){
offImage=this.createImage(GAME_WEITH,GAME_HEIGHT);
}
Graphics goff=offImage.getGraphics();
Color c=goff.getColor();
goff.setColor(Color.white);
goff.fillRect(0, 0, GAME_WEITH,GAME_HEIGHT);
goff.setColor(c);
paint(goff);
g.drawImage(offImage, 0, 0, null);
}
void launchFram(){
//增加10个对方坦克
for(int i=0;i<10;i++){
tanks.add(new Tank(200+50*i,200+50*i,false,this));
}
walls.add(new Wall(200,300,100,20,this));
walls.add(new Wall(400,150,20,200,this));
tanks.add(MyTank);
this.setBounds(100, 100, GAME_WEITH,GAME_HEIGHT);
this.setVisible(true);
this.setTitle("TankWar");
this.setResizable(false);
this.setBackground(Color.white);
this.addKeyListener(new KeyMonitor());
//添加Window关闭响应
this.addWindowListener(new WinClosed());
new Thread(new MyRepaint()).start();
}
public static void main(String[] args) {
TankWarClient twc=new TankWarClient();
twc.launchFram();
}
//响应关闭装口
class WinClosed extends WindowAdapter{
public void windowClosing(WindowEvent e){
System.exit(0);
}
}
//启用新线程重画,画面显示的更均匀
class MyRepaint implements Runnable{
public void run() {
while(true){
repaint();
try {
Thread.sleep(45);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class KeyMonitor extends KeyAdapter{
public void keyPressed(KeyEvent ke){
MyTank.keyPressed(ke);
}
public void keyReleased(KeyEvent e){
MyTank.keyReleased(e);
}
}
}
/**
* 坦克,敌方坦克与我方坦克均在此实现,用boolean good区分,其中我方坦克有血条大招
* 敌方坦克被攻击一次就会消亡
*/
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
public class Tank {
int x,y;
int oldX,oldY;
private int glife=100;
static final int dx=5,dy=5,WIDTH=30,HEIGHT=30;
boolean L=false,D=false,R=false,U=false;
boolean shoot=true,kshoot=true;
private boolean good=true;
private boolean live=true;
private static Random r=new Random();
private int mStep=r.nextInt(16);
TankWarClient twc=null;
Direction dir=Direction.STOP;
Direction ptDir=Direction.U;
public int getGlife() {
return glife;
}
public void setGlife(int glife) {
this.glife = glife;
}
public boolean isGood() {
return good;
}
Tank(int x,int y,boolean good){
this.x=x;
this.y=y;
this.oldX=x;
this.oldY=y;
this.good=good;
}
Tank(int x,int y,boolean good,TankWarClient twc){
this(x,y,good);
this.twc=twc;
}
public boolean isLive() {
return live;
}
public void setLive(boolean live) {
this.live = live;
}
//根据方向设置下一步要画的坦克位置
void move(){
oldX=x;
oldY=y;
switch(dir){
case L:
x -=dx;
break;
case LU:
x -=dx;
y -=dy;
break;
case U:
y -=dy;
break;
case RU:
x +=dx;
y -=dy;
break;
case R:
x +=dx;
break;
case RD:
x +=dx;
y +=dy;
break;
case D:
y +=dy;
break;
case LD:
x -=dx;
y +=dy;
break;
case STOP:
break;
}
if(dir!=Direction.STOP){
ptDir=dir;
}
if(x<0) x=0;
if(y<20) y=20;
if(x>TankWarClient.GAME_WEITH-WIDTH) x=TankWarClient.GAME_WEITH-WIDTH;
if(y>TankWarClient.GAME_HEIGHT-HEIGHT) y=TankWarClient.GAME_HEIGHT-HEIGHT;
if(!good){
if(mStep==0){
mStep=r.nextInt(20)+3;
Direction []dirs=Direction.values() ;
int rn=r.nextInt(dirs.length);
dir=dirs[rn];
}
mStep--;
int isShoot=r.nextInt(40);
if(isShoot>=39){
twc.missiles.add(shoot());
}
}
}
public void draw(Graphics g){
if(!live){
if(!good){
twc.tanks.remove(this);
}
//好坦克死了就不画了
if(good){
twc.tanks.remove(this);
}
}
Color c=g.getColor();
if(good){
g.setColor(Color.red);
}else{
g.setColor(Color.blue);
}
g.fillOval(x, y, WIDTH,HEIGHT);
//还原g原来的颜色
g.setColor(c);
new BloodBar().drawBar(g);
switch(ptDir){
case L:
g.drawLine(x+WIDTH/2, y+HEIGHT/2,x-5,y+HEIGHT/2);;
break;
case LU:
g.drawLine(x+WIDTH/2, y+HEIGHT/2,x , y);;
break;
case U:
g.drawLine(x+WIDTH/2, y+HEIGHT/2,x+WIDTH/2 , y-5);;
break;
case RU:
g.drawLine(x+WIDTH/2, y+HEIGHT/2,x+WIDTH , y);;
break;
case R:
g.drawLine(x+WIDTH/2, y+HEIGHT/2,x+WIDTH+5 , y+HEIGHT/2);;
break;
case RD:
g.drawLine(x+WIDTH/2, y+HEIGHT/2,x+WIDTH , y+HEIGHT);;
break;
case D:
g.drawLine(x+WIDTH/2, y+HEIGHT/2,x+WIDTH/2 , y+HEIGHT+5);;
break;
case LD:
g.drawLine(x+WIDTH/2, y+HEIGHT/2,x , y+HEIGHT);;
break;
default:
break;
}
move();
}
public void keyPressed(KeyEvent ke){
int key=ke.getKeyCode();
switch(key){
case KeyEvent.VK_F2:
if(!live&&good)
{
twc.tanks.add(this);
live=true;
glife=100;
}
break;
case KeyEvent.VK_J:
if(shoot&&live){
twc.missiles.add(shoot());
shoot=false;
}
break;
case KeyEvent.VK_K:
if(kshoot&&live){
Direction []pir=Direction.values();
for(int i=0;i<8;i++){
twc.missiles.add(new Missile(x,y,good,pir[i],this.twc));
}
kshoot=false;
}
break;
case KeyEvent.VK_W:
U=true;
break;
case KeyEvent.VK_D:
R=true;
break;
case KeyEvent.VK_S:
D=true;
break;
case KeyEvent.VK_A:
L=true;
break;
}
locateDirection();
}
private Missile shoot() {
//大管家 this.twc
Missile m=new Missile(x,y,good,ptDir,this.twc);
return m;
}
public void keyReleased(KeyEvent ke){
int key=ke.getKeyCode();
switch(key){
case KeyEvent.VK_J:
shoot=true;
break;
case KeyEvent.VK_K:
kshoot=true;
break;
case KeyEvent.VK_W:
U=false;
break;
case KeyEvent.VK_D:
R=false;
break;
case KeyEvent.VK_S:
D=false;
break;
case KeyEvent.VK_A:
L=false;
break;
}
locateDirection();
}
//设置要移动的方向
void locateDirection(){
if(U&&!R&&!D&&!L) dir=Direction.U;
else if(U&&R&&!D&&!L) dir=Direction.RU;
else if(!U&&R&&!D&&!L) dir=Direction.R;
else if(!U&&R&&D&&!L) dir=Direction.RD;
else if(!U&&!R&&D&&!L) dir=Direction.D;
else if(!U&&!R&&D&&L) dir=Direction.LD;
else if(!U&&!R&&!D&&L) dir=Direction.L;
else if(U&&!R&&!D&&L) dir=Direction.LU;
else if(!U&&!R&&!D&&!L) dir=Direction.STOP;
}
public Rectangle getRect(){
return new Rectangle(x,y,WIDTH,HEIGHT);
}
void stay(){
x=oldX;
y=oldY;
}
public boolean hitWall(Wall w){
if(this.getRect().intersects(w.getRect())){
stay();
return true;
}
return false;
}
public boolean hitWalls(List<Wall> walls){
for(int i=0;i<walls.size();i++){
if(hitWall(walls.get(i))){
return true;
}
}
return false;
}
//判断坦克是否撞到坦克
public boolean hitTank(Tank t){
if(this.getRect().intersects(t.getRect())){
stay();
return true;
}
return false;
}
public boolean hitTanks(List<Tank> tanks){
for(int i=0;i<tanks.size();i++){
if(this==tanks.get(i))
continue;
if(hitTank(tanks.get(i))){
return true;
}
}
return false;
}
private class BloodBar{
private void drawBar(Graphics g){
if(!good) return;
Color c=g.getColor();
//goodTank的画血条
if(glife>=60){
g.setColor(Color.green);
}else if(glife>=40){
g.setColor(Color.orange);
}
else{
g.setColor(Color.red);
}
g.fillRect(x, y-15,glife, 10);
g.drawRect(x+glife, y-15,100-glife, 10);
g.setColor(c);
}
}
}
/**
* 实现子弹
*/
import java.awt.*;
import java.util.List;
public class Missile {
int x,y;
Direction dir=null;
private TankWarClient twc=null;
static final int dx=8,dy=8,WIDTH=10,HEIGHT=10;
private boolean live =true;
private boolean good;
public boolean isGood() {
return good;
}
public Missile(int x, int y,Direction dir) {
this.x = x;
this.y = y;
this.dir = dir;
}
public Missile (int x,int y,boolean good,Direction dir,TankWarClient twc){
this(x,y,dir);
this.twc=twc;
this.good=good;
}
public void draw(Graphics g){
if(!live) {
twc.missiles.remove(this);
return;
}
Color c=g.getColor();
if(good){
g.setColor(Color.red);
}else{
g.setColor(Color.BLACK);
}
g.fillOval(x+Tank.WIDTH/2-WIDTH/2, y+Tank.WIDTH/2-HEIGHT/2,
WIDTH, HEIGHT);
g.setColor(c);
move();
}
void move(){
switch(dir){
case L:
x -=dx;
break;
case LU:
x -=dx;
y -=dy;
break;
case U:
y -=dy;
break;
//buf
case RU:
x +=dx;
y -=dy;
break;
case R:
x +=dx;
break;
case RD:
x +=dx;
y +=dy;
break;
case D:
y +=dy;
break;
case LD:
x -=dx;
y +=dy;
break;
default:
break;
}
//当子弹超出显示界面时消亡(从容器里将其删除)
if(x<0||x>TankWarClient.GAME_WEITH||y<0||y>TankWarClient.GAME_HEIGHT||hitTanks(twc.tanks)){
live=false;
}
}
public boolean isLive() {
return live;
}
public void setLive(boolean live) {
this.live = live;
}
public Rectangle getRect(){
return new Rectangle(x,y,WIDTH,HEIGHT);
}
//判断子弹是否打中坦克
public boolean hitTank(Tank t){
if(this.getRect().intersects(t.getRect())&&this.good!=t.isGood()){
//子弹消亡
this.live=false;
if(t.isGood()){
t.setGlife(t.getGlife()-10);
if(t.getGlife()<=0){
t.setLive(false);
}
}else{
//坦克消亡
t.setLive(false);
}
twc.explodes.add(new Explode(x,y,twc));
return true;
}
return false;
}
public boolean hitTanks(List<Tank> tanks){
for(int i=0;i<tanks.size();i++){
if(hitTank(tanks.get(i))){
return true;
}
}
return false;
}
//判断子弹是否打中墙
public boolean hitWall(Wall w){
if(this.getRect().intersects(w.getRect())){
//子弹消亡
live=false;
return true;
}
return false;
}
public boolean hitWalls(List<Wall> walls){
for(int i=0;i<walls.size();i++){
if(hitWall(walls.get(i))){
return true;
}
}
return false;
}
}
/**
* 实现爆炸,坦克死亡时出现,接着消失
*/
import java.awt.*;
public class Explode {
int x,y,step=0;
TankWarClient twc=null;
boolean live=true;
int [] p={0,1,5,10,15,20,30,35,40,50,60,55,47,43,33,27,21,18,13,7,2,0};
public Explode(int x, int y, TankWarClient twc) {
super();
this.x = x;
this.y = y;
this.twc = twc;
}
public void draw(Graphics g){
if(!live) {
twc.explodes.remove(this);
return;
}
if(step==p.length){
live=false;
step=0;
return;
}
Color c=g.getColor();
g.setColor(Color.orange);
g.fillOval(x, y, p[step], p[step]);
step++;
g.setColor(c);
}
}
/**
* 实现血块,随机产生,一定时间消失,运动轨迹随机
*/
import java.awt.*;
import java.util.*;
import java.util.List;
public class Blood {
int x,y;
//血块生存的时间
int time=300;
//大管家
TankWarClient twc=null;
//设置移动的步长
private final int dx=5,dy=5;
private final Random r=new Random();
//血块的长宽
private final int WIDTH=25,HEIGHT=25;
//设置血块是否存在
boolean live =true;
//构造方法,把大管家交给Blood
public Blood(int x, int y,TankWarClient twc) {
this.x = x;
this.y = y;
this.twc=twc;
}
//定义8个移动的方向
enum Direction {L,LU,U,RU,R,RD,D,LD,STOP}
Direction dir=Direction.STOP;
//把血块画出来
void draw(Graphics g){
if(!live){
twc.bloods.remove(this);
}
Color c=g.getColor();
g.setColor(Color.pink);
g.fillRect(x, y, WIDTH,HEIGHT);
g.setColor(c);
time--;
bloodMove();
}
//根据方向设置下一步要画的坦克位置
void bloodMove(){
Direction []dirs=Direction.values();
int rn1=r.nextInt(20);
if(rn1==19){
int rn2=r.nextInt(dirs.length);
dir=dirs[rn2];
}
switch(dir){
case L:
x -=dx;
break;
case LU:
x -=dx;
y -=dy;
break;
case U:
y -=dy;
break;
case RU:
x +=dx;
y -=dy;
break;
case R:
x +=dx;
break;
case RD:
x +=dx;
y +=dy;
break;
case D:
y +=dy;
break;
case LD:
x -=dx;
y +=dy;
break;
case STOP:
break;
}
if(x<0) x=0;
if(y<20) y=20;
if(x>TankWarClient.GAME_WEITH-WIDTH){
x=TankWarClient.GAME_WEITH-WIDTH;
}
if(y>TankWarClient.GAME_HEIGHT-HEIGHT){
y=TankWarClient.GAME_HEIGHT-HEIGHT;
}
if(time<0){
live =false;
}
}
private Rectangle getRect(){
return new Rectangle(x,y,WIDTH,HEIGHT);
}
//坦克是否吃到血块
public boolean hitTank(Tank t){
if(this.getRect().intersects(t.getRect())&&t.isGood()){
if(t.getGlife()<=90){
t.setGlife(t.getGlife()+10);
//血块消亡
live=false;
}
return true;
}
return false;
}
public boolean hitTanks(List<Tank> tanks){
for(int i=0;i<tanks.size();i++){
if(hitTank(tanks.get(i))){
return true;
}
}
return false;
}
}
/**
* 实现一堵墙,子弹碰到墙自己消失,坦克不能穿过墙
*/
import java.awt.*;
public class Wall {
private int x,y,WIDTH,HEIGHT;
TankWarClient twc=null;
public void draw(Graphics g){
Color c=g.getColor();
g.setColor(Color.DARK_GRAY);
g.fillRect(x, y, WIDTH, HEIGHT);
g.setColor(c);
}
public Wall(int x, int y, int wIDTH, int hEIGHT, TankWarClient twc) {
super();
this.x = x;
this.y = y;
WIDTH = wIDTH;
HEIGHT = hEIGHT;
this.twc = twc;
}
public Rectangle getRect() {
return new Rectangle(x,y,WIDTH,HEIGHT);
}
}
package com.RudyGuo;
/**
* 方向
*/
public enum Direction {
L,LU,U,RU,R,RD,D,LD,STOP
}