在上篇文章中我们发现炮杆方向和移动方向不一致 如图:
那么要怎么优化呢?
也就是在画炮杆时根据当前坦克的方向画。所以需要一个枚举变量Direction
来监视当前坦克的方向
新建一个枚举变量:
package tankWar;
public enum Direction {
U,D,L,R,STOP
}
然后在Tank类中 新增一个curDir 默认当前坦克方向向上 ptDir表示炮塔方向
//当前坦克的方向
private Direction curDir=Direction.U;
//当前坦克的炮塔方向
private Direction ptDir=Direction.U;
然后在每次移动后 都修改一下当前坦克方向
</pre><p><pre name="code" class="java">// 我方坦克的键盘按下事件
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
curDir = Direction.U;
y -= speed;
break;
case KeyEvent.VK_DOWN:
curDir = Direction.D;
y += speed;
break;
case KeyEvent.VK_LEFT:
curDir = Direction.L;
x -= speed;
break;
case KeyEvent.VK_RIGHT:
curDir = Direction.R;
x += speed;
break;
default:
curDir = Direction.STOP;
break;
}
// 炮杆方向没有停止 只有坦克会停止
if (curDir != Direction.STOP) {
ptDir = curDir;
}
}
然后就是在Tank类中的draw方法中根据当前坦克的方向画炮杆
Line2D l2 = null;
if (ptDir == Direction.U)
l2 = new Line2D.Double(x + width / 2, y + height / 2,
x + width / 2, y + height / 2 - 40);
if (ptDir == Direction.D)
l2 = new Line2D.Double(x + width / 2, y + height / 2,
x + width / 2, y + height / 2 + 40);
if (ptDir == Direction.L)
l2 = new Line2D.Double(x + width / 2, y + height / 2, x + width / 2
- 40, y + height / 2);
if (ptDir == Direction.R)
l2 = new Line2D.Double(x + width / 2, y + height / 2, x + width / 2
+ 40, y + height / 2);
然后就完成
运行结果:
全部代码:
TankClient类
package tankWar;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TankClient extends JFrame {
// 窗口的高度
public static final int SCREENHEIGHT = 600;
// 窗口的宽度
public static final int SCREENWIDTH = 800;
public static Tank myTank;
// 创建一个窗口
public TankClient() {
setTitle("坦克大战");
// 窗口的大小
setSize(SCREENWIDTH, SCREENHEIGHT);
// 设置窗口的显示位置在屏幕中央
setLocationRelativeTo(null);
// 关闭窗口的事件管理
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 不允许窗口的大小改动
setResizable(false);
setVisible(true);
// 添加自定义的panel
add(new TankClientPanel());
// 实例化我的坦克
myTank = new Tank(50, 50, 50, 50);
// 为窗口添加键盘事件
addKeyListener(new KeyMonitor());
// 启动屏幕刷新线程
new updateThread().start();
}
public static void main(String[] args) {
// 启动窗口
new TankClient();
}
public class KeyMonitor extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
myTank.keyPressed(e);
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
myTank.keyReleased(e);
}
}
// 自定义Jpanel
public class TankClientPanel extends JPanel {
// 重写patit方法
@Override
public void paint(Graphics g) {
// 画我的坦克
myTank.draw(g);
}
}
// 屏幕刷新线程
public class updateThread extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
// 刷新屏幕
repaint();
try {
// 设置线程睡眠时间
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Tank类
package tankWar;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
public class Tank {
// 坦克x坐标
private int x;
// 坦克y坐标
private int y;
// 坦克的宽
private int width;
// 坦克的高
private int height;
// 坦克移动的速度
private int speed = 5;
// 当前坦克的方向
private Direction curDir = Direction.U;
// 当前坦克的炮塔方向
private Direction ptDir = Direction.U;
public Tank() {
super();
// TODO Auto-generated constructor stub
}
public Tank(int x, int y, int width, int height) {
super();
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
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 getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public void draw(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
// 画一个圆
Ellipse2D e2 = new Ellipse2D.Double(x, y, width, height);
// 颜色为红色
g2.setColor(Color.RED);
// 填充
g2.fill(e2);
// 画一条线 通过坦克的坐标计算炮杆的坐标
Line2D l2 = null;
if (ptDir == Direction.U)
l2 = new Line2D.Double(x + width / 2, y + height / 2,
x + width / 2, y + height / 2 - 40);
if (ptDir == Direction.D)
l2 = new Line2D.Double(x + width / 2, y + height / 2,
x + width / 2, y + height / 2 + 40);
if (ptDir == Direction.L)
l2 = new Line2D.Double(x + width / 2, y + height / 2, x + width / 2
- 40, y + height / 2);
if (ptDir == Direction.R)
l2 = new Line2D.Double(x + width / 2, y + height / 2, x + width / 2
+ 40, y + height / 2);
g2.setColor(Color.BLACK);
// 加粗炮杆
g2.setStroke(new BasicStroke(3));
g2.draw(l2);
}
// 我方坦克的键盘按下事件
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
curDir = Direction.U;
y -= speed;
break;
case KeyEvent.VK_DOWN:
curDir = Direction.D;
y += speed;
break;
case KeyEvent.VK_LEFT:
curDir = Direction.L;
x -= speed;
break;
case KeyEvent.VK_RIGHT:
curDir = Direction.R;
x += speed;
break;
default:
curDir = Direction.STOP;
break;
}
// 炮杆方向没有停止 只有坦克会停止
if (curDir != Direction.STOP) {
ptDir = curDir;
}
}
// 我方坦克的键盘松下事件
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
枚举变量
package tankWar;
public enum Direction {
U, D, L, R, STOP
}