/** 功能:
* 1.实现爆炸效果
* 2.敌人坦克可移动,可以连发子弹
* 3.敌人击中我的坦克,我爆炸
* 4.击中第一个坦克爆炸的效果不明显*/
packagecom.fanghua5;import java.awt.*;importjava.awt.event.KeyEvent;importjava.util.Vector;import javax.swing.*;public class MyTankGame1_6 extendsJFrame {
Mypanel1_2 mp= null;public static voidmain(String[] args) {newMyTankGame1_6();
}//构造函数
publicMyTankGame1_6() {
mp= newMypanel1_2();//启动mp线程
Thread t = newThread(mp);
t.start();this.add(mp);//注册监听
this.addKeyListener(mp);this.setSize(400, 300);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);
}
}//我的面板,拓宽思路:Panel本身就是一个刷新体
class Mypanel1_2 extends JPanel implementsjava.awt.event.KeyListener, Runnable {//定义我的坦克
Hero1_2 hero = null;//定义敌人的坦克(不止一辆,线程安全,集合)
Vector ets = new Vector();//定义炸弹集合
Vector bombs = new Vector();int enSize = 4;//敌人坦克保持四个//定义三张图片(三张图片才能组成一颗炸弹)
Image image1 = null;
Image image2= null;
Image image3= null;//构造函数
publicMypanel1_2() {
hero= new Hero1_2(10, 10);for (int i = 0; i < enSize; i++) {//创建一辆敌人的坦克
EnemyTank et = new EnemyTank((i + 1) * 50, 0);
et.setColor(0);//坦克默认反向是0(向上),这里改一下
et.setDirect(2);//加入
ets.add(et);//启动敌人的坦克
Thread t = newThread(et);
t.start();//给敌人坦克添加一颗子弹
Shot s = new Shot(et.x + 10, et.y + 30, 2);//加入给敌人的坦克
et.ss.add(s);
Thread t2= newThread(s);
t2.start();
ets.add(et);
}//初始话图片,这样做击中第一个坦克,爆炸的效果不明显。下面优化
image1 =Toolkit.getDefaultToolkit().getImage(
Panel.class.getResource("/bomb_1.gif"));
image2=Toolkit.getDefaultToolkit().getImage(
Panel.class.getResource("/bomb_2.gif"));
image3=Toolkit.getDefaultToolkit().getImage(
Panel.class.getResource("/bomb_3.gif"));//引包:import javax.imageio.ImagesssIO;//try {//image1=ImageIO.read(new File("/bomsb_1.gif"));//image2=ImageIO.read(new File("/bomb_2.gif"));//image3=ImageIO.read(new File("/bomb_3.gif"));//} catch (IOException e) {// //TODO Auto-generated catch block//e.printStackTrace();//}
}//重写paint函数
public voidpaint(Graphics g) {//一定要调用
super.paint(g);
g.fillRect(0, 0, 400, 350);//画出自己的坦克(将方向填进去)
if (hero.isLive == true) {this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1);
}//从ss中取出每一颗子弹,并画出
for (int i = 0; i < hero.ss.size(); i++) {
Shot myShot=hero.ss.get(i);if (myShot != null && myShot.isLive == true) {
g.draw3DRect(myShot.x, myShot.y,1, 1, false);/** 画出一颗子弹(后添加 hero.s.isLive==true,节省资源) if (hero.s != null
* &&hero.s.isLive == true) { g.draw3DRect(hero.s.x, hero.s.y,
* 1, 1,false); }*/}if (myShot.isLive == false) {//从ss(向量)中删除该子弹//hero.ss.remove(i);会报异常。
hero.ss.remove(myShot);
}
}//画出炸弹
for (int i = 0; i < bombs.size(); i++) {//取出炸弹
Bomb b =bombs.get(i);if (b.life > 6) {
g.drawImage(image1, b.x, b.y,30, 30, this);
}else if (b.life > 4) {
g.drawImage(image2, b.x, b.y,30, 30, this);
}else{
g.drawImage(image3, b.x, b.y,30, 30, this);
}//让b的生命值减小
b.lifeDown();//如果炸弹生命值为零,就把该炸弹从bombs向量中去掉
if (b.life == 0) {
bombs.remove(b);
}
}//画出敌人的坦克
for (int i = 0; i < ets.size(); i++) {
EnemyTank et=ets.get(i);if(et.isLive) {this.drawTank(et.getX(), et.getY(), g, et.getDirect(), 0);//画出敌人的子弹
for (int j = 0; j < et.ss.size(); j++) {//取出子弹
Shot enemyShot =et.ss.get(j);if (enemyShot != null && enemyShot.isLive == true) {
g.draw3DRect(enemyShot.x, enemyShot.y,1, 1, false);
}if (enemyShot.isLive == false) {//如果敌人的坦克死亡了,就从Vector中删除
et.ss.remove(enemyShot);
}
}
}
}
}//判断敌人的子弹是否击中我
public voidhitMe() {//取出每一个敌人的坦克
for (int i = 0; i < this.ets.size(); i++) {//取出坦克
EnemyTank et =ets.get(i);//取出每一颗子弹
for (int j = 0; j < et.ss.size(); j++) {//取出子弹
Shot enemyShot =et.ss.get(j);this.hitTank(enemyShot, hero);
}
}
}//判断我是否击中敌人的坦克
public voidhitEnemyTank() {//判断是否被击中敌人的坦克
for (int i = 0; i < hero.ss.size(); i++) {//取出我的子弹与敌人坦克匹配
Shot myShot =hero.ss.get(i);//判断子弹是否有效
if(myShot.isLive) {//取出每个坦克,与它判断
for (int j = 0; j < ets.size(); j++) {//取出坦克
EnemyTank et =ets.get(j);if(et.isLive) {this.hitTank(myShot, et);
}
}
}
}
}//写一个函数 专门判断是否击中敌人坦克(原来第二参数: EnemyTank et)
public voidhitTank(Shot s, Tank1_2 et) {//判断该坦克的方向
switch(et.direct) {//敌人坦克的方向是0或2,一致
case 0:case 2:if (s.x >= et.x && s.x <= et.x + 20 && s.y >=et.y&& s.y <= et.y + 30) {//击中(子弹死亡,敌人死亡)
s.isLive = false;
et.isLive= false;//创建一颗炸弹,放入Vector中
Bomb b = newBomb(et.x, et.y);//放入
bombs.add(b);
}
break;case 1:case 3:if (s.x >= et.x && s.x <= et.x + 30 && s.y >=et.y&& s.y <= et.y + 20) {//击中(子弹死亡,敌人死亡)
s.isLive = false;
et.isLive= false;//创建一颗炸弹,放入Vector中
Bomb b = newBomb(et.x, et.y);//放入
bombs.add(b);
}
break;
}
}//画出坦克的函数
public void drawTank(int x, int y, Graphics g, int direct, inttype) {//坦克类型
switch(type) {case 0:
g.setColor(Color.green);break;case 1:
g.setColor(Color.yellow);break;
}//方向设置
switch(direct) {//向上
case 0:
g.fill3DRect(x, y,5, 30, false);
g.fill3DRect(x+ 15, y, 5, 30, false);
g.fill3DRect(x+ 5, y + 5, 10, 20, false);
g.fillOval(x+ 5, y + 10, 10, 10);
g.drawLine(x+ 10, y + 15, x + 10, y);break;//向右
case 1:
g.fill3DRect(x, y,30, 5, false);
g.fill3DRect(x, y+ 15, 30, 5, false);
g.fill3DRect(x+ 5, y + 5, 20, 10, false);
g.fillOval(x+ 10, y + 5, 10, 10);
g.drawLine(x+ 15, y + 10, x + 30, y + 10);break;//向下
case 2:
g.fill3DRect(x, y,5, 30, false);
g.fill3DRect(x+ 15, y, 5, 30, false);
g.fill3DRect(x+ 5, y + 5, 10, 20, false);
g.fillOval(x+ 5, y + 10, 10, 10);
g.drawLine(x+ 10, y + 15, x + 10, y + 30);break;//向左
case 3:
g.fill3DRect(x, y,30, 5, false);
g.fill3DRect(x, y+ 15, 30, 5, false);
g.fill3DRect(x+ 5, y + 5, 20, 10, false);
g.fillOval(x+ 10, y + 5, 10, 10);
g.drawLine(x+ 15, y + 10, x, y + 10);break;
}
}
@Overridepublic voidkeyTyped(KeyEvent e) {//TODO Auto-generated method stub
}
@Overridepublic voidkeyPressed(KeyEvent e) {//TODO Auto-generated method stub//已更正为顺时针
if (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() ==KeyEvent.VK_W) {this.hero.moveUp();this.hero.setDirect(0);
}else if (e.getKeyCode() ==KeyEvent.VK_RIGHT|| e.getKeyCode() ==KeyEvent.VK_D) {this.hero.setDirect(1);this.hero.moveRight();
}else if (e.getKeyCode() ==KeyEvent.VK_DOWN|| e.getKeyCode() ==KeyEvent.VK_S) {this.hero.moveDown();this.hero.setDirect(2);
}else if (e.getKeyCode() ==KeyEvent.VK_LEFT|| e.getKeyCode() ==KeyEvent.VK_A) {this.hero.moveLeft();this.hero.setDirect(3);
}else if (e.getKeyCode() ==KeyEvent.VK_J) {//将J键设置为发出子弹//子弹连发,J被按几下,发几颗:this.hero.shotEnemy();//this.repaint();在run函数里,不应该设计在这里
if (this.hero.ss.size() <= 4) {this.hero.shotEnemy();
}
}
}
@Overridepublic voidkeyReleased(KeyEvent e) {//TODO Auto-generated method stub
}
@Overridepublic voidrun() {//TODO Auto-generated method stub//每隔100毫秒去重绘
while (true) {try{
Thread.sleep(100);
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}//判断是否击中(写在这里,虽然在每次重绘的时候都要调用,但是没办法)//每一颗子弹都要和每个坦克进行匹配
for (int i = 0; i < hero.ss.size(); i++) {//取出子弹
Shot myShot =hero.ss.get(i);//判断子弹是否有效
if(myShot.isLive) {//取出每个坦克,与它判断
for (int j = 0; j < ets.size(); j++) {//取出坦克
EnemyTank et =ets.get(j);if(et.isLive) {this.hitTank(myShot, et);
}
}
}
}this.hitEnemyTank();this.hitMe();//重绘
this.repaint();
}
}
}