java小项目,坦克大战完整


终于完成,修改了很多地方,大家如果需要可以看看,java基础知识练手的! 

********************************************** 
//线程主类 
import java.awt.Color; 
import java.awt.Frame; 
import java.awt.Graphics; 
import java.awt.Image
import java.util.ArrayList; 
import java.util.List; 


public class TankClient extends Frame { 
public static final int GAME_WIDTH = 800; 
public static final int GAME_HIGHT = 600; 
private static TankClient tc; 
public static boolean p=true; 

Wall w1 = new Wall(100, 200, 20, 150, this), w2 = new Wall(300, 100, 300, 20, this); 
Tank myTank = new Tank(50, 50, true, Tank.Direction.STOP, this); 
/** 
* 怎么打多发炮弹,使用容器装炮弹,每当按下Ctr这个键的时候往容器中添加炮弹 
* 画出每一个炮弹; 

伦理片 http://www.dotdy.com/

List<Missile> missiles = new ArrayList<Missile>(); // 遍历比较快 
// //LinkedList<>;//链表删除快,查找慢 
// 画出爆炸 
List<Explode> explodes = new ArrayList<Explode>(); 
private Image offScreenImage = null; 
// 坏坦克创建 
// 关数 
int c = 1; 
List<Tank> tanks = new ArrayList<Tank>(); 
// 重写 
Blood b = new Blood(); 
/** 
* //消除闪烁,使用双缓冲 
   //线程重画更加均匀,更能控制重化的速度。按键重画不能解决子弹自动飞行的问题; 
*/ 
public void update(Graphics g) { 
if (offScreenImage == null) { 
offScreenImage = this.createImage(GAME_WIDTH, GAME_HIGHT); 

// 拿到图片上的画笔 
Graphics gOffScreen = offScreenImage.getGraphics(); 
Color c = gOffScreen.getColor(); 
gOffScreen.setColor(Color.blue); 
gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HIGHT); 
gOffScreen.setColor(c); 
paint(gOffScreen);// 画在背后图片上 
g.drawImage(offScreenImage, 0, 0, null);// 画在屏幕上 


/** 
* // 画出还有多少炮弹,画一个字符串到屏幕 
*/ 
public void paint(Graphics g) { 

g.drawString("missiles count:" + missiles.size(), 30, 50); 
g.drawString("Explode count:" + explodes.size(), 30, 70); 
g.drawString("Tanks count:" + tanks.size(), 30, 90); 
g.drawString("tanks   life:" + myTank.getLife(), 30, 110); 
g.drawString("关卡数:   -" + c + "-", 30, 130); 
g.drawString("p为暂停                ", 30, 150); 
for (int i = 0; i < missiles.size(); i++) { 
Missile m = missiles.get(i); 
m.draw(g); 
m.hitTank(tanks); 
m.hitTank(myTank); 
m.hitWall(w1); 
m.hitWall(w2); 


for (int i = 0; i < tanks.size(); i++) { 
Tank t = tanks.get(i); 
t.collideWithWall(w1); 
t.collideWithWall(w2); 
t.collidesWithTanks(tanks); 
t.draw(g); 
myTank.collideWithWall(w1); 
myTank.collideWithWall(w2); 

for (int i = 0; i < explodes.size(); i++) { 
Explode e = explodes.get(i); 
e.draw(g); 



myTank.draw(g); 
w1.draw(g); 
w2.draw(g); 
myTank.eat(b); 
if(myTank.getLife()<=40){ 
b.draw(g); 

/** 
*  敌人死完后再加入,C为关卡数,不同的关卡,坦克数量,以及出现的地方不同 
*/ 
if (tanks.size() == 0) { 
c++; 
if (c > 10) { 
for (int i = 0; i < 15; i++) { 
tanks.add(new Tank((i) * 50, 50, false, Tank.Direction.D, tc)); 

} else  if(c>5){ 
for (int j = 0; j < 10; j++) { 
tanks.add(new Tank( 300,j*40+50, false, Tank.Direction.D, tc)); 

}else { 
for (int i = 0; i < 10; i++) { 
tanks.add(new Tank((i) * 50, 50, false, Tank.Direction.D, tc)); 




/** 
* 添加坦克,以及设置窗体 
*/ 
public void lauchFrame() { 
for (int i = 0; i < 10; i++) { 
tanks.add(new Tank((i + 1) * 50 + 100, 50, false, Tank.Direction.D, tc)); 

setTitle("TankWar"); 
setBounds(230, 100, 800, 600); 
// 匿名内部类,短,不涉及将来的扩展 
addWindowListener(new WindowAdapter() { 
public void windowClosing(WindowEvent e) { 
System.exit(0); 

}); 

setResizable(false); 
setBackground(Color.GREEN); 
setVisible(true); 
addKeyListener(new KeyMoniter()); 
new Thread(new PaintThread()).start(); 


public static void main(String[] args) { 
tc = new TankClient(); 
tc.lauchFrame(); 



/** 
* // 内部类,只为这个TankWar服务,方便的访问包装类的方法,不方便公开, 
* @author yan 

*/ 
private class PaintThread implements Runnable { 
public void run() { 
while (true) { 
//游戏暂停有关,线程不能关,关了以后的话,后面的方法都不会运行 
if(p==true){ 
repaint();} 
// 内部调用父类的paint方法; 
try { 
Thread.sleep(50); 
} catch (InterruptedException e) { 
e.printStackTrace(); 





/** 
* // 键盘事件,内部类 
* @author yan 

*/ 
private class KeyMoniter extends KeyAdapter { 
public void keyReleased(KeyEvent e) { 
myTank.keyReleased(e); 


public void keyPressed(KeyEvent e) { 
myTank.keyPressed(e); 




********************************************************* 
//血块类 

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Rectangle; 
import java.util.Random; 
//血块 
public class Blood { 
int step=0; 
int x,y,w,h; 
Random ran=new Random(); 
    private boolean live=true; 
public boolean isLive() { 
return live; 

public void setLive(boolean live) { 
this.live = live; 

TankClient tc; 
/** 
* 初始化血块 
*/ 
public Blood(){ 
w=h=20; 
x=300; 
y=300; 


/** 
* 用来设定下一次血块随机出现的地点,避免线程带来的闪烁,(不归线程来控制) 
*/ 
public void setBlood(){ 
x=ran.nextInt(500)+50; 
y=ran.nextInt(500)+50; 
live=true; 

public void draw(Graphics g){ 
if(!live){ 
return ; 


Color c=g.getColor(); 
g.setColor(Color.MAGENTA); 
g.fillRect(x, y, w, h); 
g.setColor(c); 


/** 
* 血块的碰撞检测 
* @return 
*/ 
public Rectangle getRect(){ 
return new Rectangle(x,y,w,h); 



******************************************* 

//爆炸类 

import java.awt.Color; 
import java.awt.Graphics; 

public class Explode { 
int x,y; 
private boolean live=true; 
private TankClient tc; 
public Explode(int x,int y,TankClient tc){ 
this.x=x; 
this.y=y; 
this.tc=tc; 


int[] diameter={4,6,7,10,12,15,18,21,25,26,30,32,35,40,45,49,30,14,6}; 
int step; 
public void draw(Graphics g){ 
if(step==diameter.length){ 
live=false; 
tc.explodes.remove(this);//爆炸完成后移除此对象 
step=0; 
return; 

if(!live)return; 
Color c = g.getColor(); 
g.setColor(Color.green); 
g.fillOval(x, y, diameter[step], diameter[step]); 
step++; 
g.setColor(c); 






********************************************************* 
//炮弹类 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Rectangle; 
import java.util.List; 

import Frame.Tank.Direction; 
/** 
* // 炮弹的生死状态,默认为生,出街,打倒敌人为死 
* @author yan 

*/ 
public class Missile { 
private static final int xspeed = 8; 
private static final int yspeed = 8; 
public static final int WIDTH = 10; 
public static final int HEIGHT = 10; 
private List<Tank> tanks; 
private boolean Live = true; 
private boolean good=true; 

public boolean isLive() { 
return Live; 


int x, y; 
Tank.Direction dir; 
private TankClient tc; 

public Missile(int x, int y, Direction dir) { 

this.x = x; 
this.y = y; 
this.dir = dir; 


public Missile(int x, int y, Direction dir,boolean good,TankClient tc) { 
this(x, y, dir); 
this.good=good; 
this.tc = tc; 


public void draw(Graphics g) { 
if (!Live) { 
tc.missiles.remove(this); 


Color c = g.getColor(); 
g.setColor(Color.black); 
g.fillOval(x, y, WIDTH, HEIGHT); 
g.setColor(c); 
move(); 

影音先锋电影 http://www.iskdy .com/
private void move() { 
switch (dir) { 
case L: 
x -= xspeed; 
break; 
case LU: 
x -= xspeed; 
y -= yspeed; 
break; 
case U: 
y -= yspeed; 
break; 
case RU: 
x += xspeed; 
y -= yspeed; 
break; 

case R: 
x += xspeed; 
break; 
case RD: 
x += xspeed; 
y += yspeed; 
break; 
case LD: 
x -= xspeed; 
y += yspeed; 
break; 
case D: 
y += yspeed; 
break; 


if (x < 0 || y < 0 || x > TankClient.GAME_WIDTH || y > TankClient.GAME_HIGHT) { 
Live = false; 
tc.missiles.remove(this); 




/** 
* // 得到外围小方块,(碰撞检测辅助类Rectangle) 
* @return 
*/ 
public Rectangle getRect() { 
return new Rectangle(x, y, WIDTH, HEIGHT); 

/** 
* // 添加爆炸对象到列表,射击类 
* @param t 
* @return 
*/ 
public boolean hitTank(Tank t) { 
if (this.Live&&this.getRect().intersects(t.getRect()) && t.isLive() == true&&this.good!=t.isGood()) {// 检测是否碰撞,碰撞之后,还得判断坦克是生还是死,否则子弹在那个地方还是会消失 
if(t.isGood()){ 
t.setLife(t.getLife()-20); 
if(t.getLife()<=0) 
t.setLive(false); 
}else{ 
t.setLive(false); 


Explode e = new Explode(x, y, tc); 
tc.explodes.add(e); 
this.Live = false; 
return true; 

return false; 

/** 
* // 对一个数组的坦克进行射击类添加 
* @param tanks 
* @return 
*/ 
public boolean hitTank(List<Tank> tanks) { 
for (int i = 0; i < tanks.size(); i++) { 
if (hitTank(tanks.get(i))) { 
return true; 


return false; 


/** 
* 坦克碰撞到墙 
* @param w 
* @return 
*/ 
public boolean hitWall(Wall w){ 
if(this.Live&&this.getRect().intersects(w.getRect())){ 
this.Live=false; 
return true; 


return false; 





******************************************************** 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值