//为什么会出现上方向和左方向的子弹不能发射的情况?检查了好久,有大佬帮帮忙吗,小白睡不着
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); }}