//为什么会出现上方向和左方向的子弹不能发射的情况?检查了好久,有大佬帮帮忙吗,小白睡不着
package TanKe.lbl;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.util.concurrent.atomic.DoubleAdder;
//JFrame为事件源
public class MytankGame extends JFrame{
Mypanel mp = null;
public static void main(String[] args) {
MytankGame mg = new MytankGame();
}
//构造方法设置画布属性,定义自己的画框,并将划款添加进JFrame
public MytankGame() {
this.setTitle("坦克大战");
mp = new Mypanel();
this.add(mp);
//启动线程
Thread t = new Thread(mp);
t.start();
//创建监听
this.addKeyListener(mp);
this.setSize(400,300);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
//定义自己的画框,并且作为监听者类
class Mypanel extends JPanel implements KeyListener,Runnable{
Ltank LL = null;
Vector<Dtank> vv = new Vector<Dtank>();
int enSize = 6;
//构造函数实例化我的坦克
public Mypanel() {
LL = new Ltank(170,130);//坦克的初始坐标
//创建敌人坦克引用
for(int i = 0; i < enSize; i ++) {
Dtank dd = new Dtank((i+1) * 60, 0);
//设置颜色
dd.setColor(1);
//设置方向
dd.setDirect(1);
//将引用添加到集合里
vv.add(dd);
}
}
//重写父类的画笔方法
public void paint(Graphics g) {
super.paint(g);
//设置地图为黑色
g.fillRect(0, 0, 400, 300);
//画出自己的坦克
this.drawTank(LL.getX(), LL.getY(), g, LL.direct, 0);
//判断子弹不为空
if(LL.ss != null&&LL.ss.isLive == true) {
g.draw3DRect(LL.ss.x, LL.ss.y, 1, 1, false);
}
//画出敌方坦克
for(int i = 0; i < vv.size(); i ++) {
//取出坦克并且赋予坐标等属性画出来
this.drawTank(vv.get(i).getX(), vv.get(i).getY(), g, vv.get(i).direct, 1);
}
}
//画的动作,这么画,如何画
public void drawTank(int x, int y, Graphics g, int direct, int type) {
switch (type) {
case 0:
g.setColor(Color.cyan);
break;
case 1:
g.setColor(Color.blue);
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, 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 2:
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;
//向右
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 + 30, y + 10);
break;
}
}
//重写监听者的方法
public void keyPressed(KeyEvent arg0) {
//识别按键
if(arg0.getKeyCode() == KeyEvent.VK_W) {
this.LL.setDirect(0);
this.LL.moveup();
}
else if(arg0.getKeyCode() == KeyEvent.VK_S) {
this.LL.setDirect(1);
this.LL.movedown();
}
else if(arg0.getKeyCode() == KeyEvent.VK_A) {
this.LL.setDirect(2);
this.LL.moveleft();
}
else if(arg0.getKeyCode() == KeyEvent.VK_D) {
this.LL.setDirect(3);
this.LL.moveright();
}
//坦克开火
if (arg0.getKeyCode() == KeyEvent.VK_J) {
this.LL.shotDtank();
}
this.repaint();
}
@Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.repaint();
}
}
}
//定义子弹类,实现线程接口
class Shot implements Runnable{
int x;
int y;
int direct;
int speed = 2;
boolean isLive = true;
public Shot(int x, int y, int direct) {
this.x = x;
this.y = y;
this.direct = direct;
}
//线程方法
public void run() {
while(true) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
switch(direct) {
case 0:
y = y - speed;
case 1:
y = y + speed;
case 2:
x = x - speed;
case 3:
x = x + speed;
}
//何时死亡
//子弹碰到边缘
if(x<0||x>400||y<0||y>300) {
this.isLive = false;
break;
}
}
}
}
//定义一个坦克类
class Tank {
int x = 0;
int y = 0;
//0,1,2,3分别是上下左右
int direct = 0;
int speed = 1;
int color;
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public Tank( int x, int y) {
this.x = x;
this.y = y;
}
//获取坦克的x,y坐标
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 int getDirect() {
return direct;
}
public void setDirect(int direct) {
this.direct = direct;
}
//速度
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
}
//我方坦克类
class Ltank extends Tank {
Shot ss = null;
public Ltank(int x, int y) {
super(x,y);
}
//开火方法
public void shotDtank() {
//判断子弹方向
switch(this.direct){
case 0:
ss = new Shot(x + 10, y, 0);
break;
case 1:
ss = new Shot(x + 10, y + 30, 1);
break;
case 2:
ss = new Shot(x, y + 10,2);
break;
case 3:
ss = new Shot(x + 30, y + 10,3);
break;
}
//启动子弹线程
Thread t = new Thread(ss);
t.start();
}
//坦克向上移动
public void moveup() {
y= y - speed;
}
//向下移动
public void movedown() {
y= y + speed;
}
//向左移动
public void moveleft() {
x= x - speed;
}
//向右移动
public void moveright() {
x= x + speed;
}
}
//敌方坦克类
class Dtank extends Tank {
public Dtank(int x, int y) {
super(x,y);
}
}