package tankGame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
/**
* 坦克大战的绘图区域(画布)
*/
public class MyPanel extends JPanel implements KeyListener, Runnable {
//定义我方坦克
Hero hero = null;
//定义敌方坦克,到Vector(多辆)
Vector<Enemy> enemies = new Vector<>();
int etSize = 3;//敌方坦克数量
//定义炸弹,到Vector(为什么用这个?,原因: Vector 可多线程同步)
//被击中后,初始化炸弹 hitTank()
Vector<Bomb> bombs = new Vector<>();
//炸弹资源
Image image1 = null;
Image image2 = null;
Image image3 = null;
public MyPanel() {
//我方坦克初始化
hero = new Hero(100, 100);//坐标
hero.setDirect(0);//方向:向上
//敌方坦克初始化
for (int i = 0; i < etSize; i++) {
//坦克
Enemy enemy = new Enemy(100 * (i + 1), 0);// 坐标
enemy.setDirect(2); //方向:向下
new Thread(enemy).start();//启动线程
//子弹
Shot shot = new Shot(enemy.getX() + 20, enemy.getY() + 40, 2);//初始化一颗子弹
enemy.shots.add(shot);//添加进 Vector 组
new Thread(shot).start();//启动线程
//加入
enemies.add(enemy);
}
//初始化炸弹资源
image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/tankGame/refImg/Bomb_01.png"));
image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/tankGame/refImg/Bomb_02.png"));
image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/tankGame/refImg/Bomb_03.png"));
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 800, 550);//填充矩形,默认黑色(画布)
//我方坦克
if (hero.isLive()&&hero!=null) {
drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 0);
}
//我方坦克子弹
if (hero.getShot() != null && hero.getShot().isLive()) {
g.fillOval(hero.getShot().getX(), hero.getShot().getY(), 2, 2);
g.setColor(Color.yellow);
System.out.println("子弹绘制...");
}
//敌方坦克
for (int i = 0; i < enemies.size(); i++) {
//取出单个
Enemy enemy = enemies.get(i);
//判断是否存活
if (enemy.isLive()) {//isLive == true
//绘制坦克
drawTank(enemy.getX(), enemy.getY(), g, enemy.getDirect(), 1);
//遍历这个坦克的所有子弹
for (int j = 0; j < enemy.shots.size(); j++) {
//取出子弹
Shot shot = enemy.shots.get(j);
//绘制子弹
if (shot.isLive()) {//isLive == true
g.fillOval(shot.getX(), shot.getY(), 2, 2);
} else {
enemy.shots.remove(shot);//超出移除->使不继续绘制
}
}
}
}
//绘制炸弹 hitTank(子弹击中坦克)内创建爆炸,实现效果
for (int i = 0; i < bombs.size(); i++) {
//第一颗子弹撞击敌人坦克后无爆炸效果,加休眠后,才有效果,原理?
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
//取出单个炸弹(一个炸弹由三张图片构成)
Bomb bomb = bombs.get(i);
//判断炸弹生命周期绘制对应三张图片
if (bomb.getLive() > 6) {
g.drawImage(image1, bomb.getX(), bomb.getY(), 40, 40, this);
} else if (bomb.getLive() > 3) {
g.drawImage(image2, bomb.getX(), bomb.getY(), 40, 40, this);
} else {
g.drawImage(image3, bomb.getX(), bomb.getY(), 40, 40, this);
}
//减少生命周期,达到切换效果
bomb.BombLive();
//为0,从bombs集合中移除炸弹
if (bomb.getLive() == 0) {
bombs.remove(bomb);
}
}
}
/**
* 我方的坦克,敌人的坦克都有相同的属性(封装目的)
*
* @param x 坦克的左上角x坐标
* @param y 坦克左上角y坐标
* @param g 画笔
* @param direct 坦克方向(上下左右)
* @param type 坦克类型(0-自己,1-敌方)
*/
public void drawTank(int x, int y, Graphics g, int direct, int type) {
switch (type) {
case 0: //我方坦克
g.setColor(Color.yellow);
break;
case 1: //敌方坦克
g.setColor(Color.cyan);
break;
}
//根据坦克方向,绘制坦克
//direct(上-0,右-1,下-2,左-3)
switch (direct) {
case 0: //绘制向上时坦克形态(参考refImg.坦克向上模样.png)
//矩形(轮子)
g.fill3DRect(x, y, 10, 40, false);//左轮
g.fill3DRect(x + 30, y, 10, 40, false);//右轮
//画身体(盖子)
g.fill3DRect(x + 10, y + 5, 20, 30, false);
//画圆
g.fillOval(x + 10, y + 10, 20, 20);
//炮筒(线)1->外点 2->园盖中心点
g.drawLine(x + 20, y, x + 20, y + 20);
break;
case 1: //绘制向右时坦克形态
//矩形(轮子)
g.fill3DRect(x, y, 40, 10, false);
g.fill3DRect(x, y + 30, 40, 10, false);
//画身体(盖子)
g.fill3DRect(x + 5, y + 10, 30, 20, false);
//画圆
g.fillOval(x + 10, y + 10, 20, 20);
//炮筒(线)
g.drawLine(x + 20, y + 20, x + 40, y + 20);
break;
case 2: //绘制向下时坦克形态
//矩形(轮子)
g.fill3DRect(x, y, 10, 40, false);
g.fill3DRect(x + 30, y, 10, 40, false);
//画身体(盖子)
g.fill3DRect(x + 10, y + 5, 20, 30, false);
//画圆
g.fillOval(x + 10, y + 10, 20, 20);
//炮筒(线)
g.drawLine(x + 20, y + 20, x + 20, y + 40);
break;
case 3: //绘制向左时坦克形态
//矩形(轮子)
g.fill3DRect(x, y, 40, 10, false);
g.fill3DRect(x, y + 30, 40, 10, false);
//画身体(盖子)
g.fill3DRect(x + 5, y + 10, 30, 20, false);
//画圆
g.fillOval(x + 10, y + 10, 20, 20);
//炮筒(线)
g.drawLine(x + 20, y + 20, x, y + 20);
break;
default:
System.out.println("暂时没处理");
}
}
/**
* 我方(敌方)子弹撞击敌方(我方)坦克后果(对方子弹到达对立坦克区域内)
* 在run内进行判断执行,因run内100秒内重新绘制画布
*
* @param s 子弹
* @param tank 坦克
*/
public void hitTank(Shot s, Tank tank) {
switch (tank.getDirect()) {
case 0://上
case 2://下
case 1://右
case 3://左
//坦克整体长度40,宽度40
if (s.getX() > tank.getX() && s.g
评论0