本文通過繼承 JPanel 重寫 paint、實現 KeyListener、使用 Graphics 繪製四方向坦克,實現簡易鍵盤控制移動演示。
MytankGame2 extends JFrame:主窗口,添加面板、註冊鍵盤監聽。MyPanel extends JPanel implements KeyListener:繪製邏輯、鍵盤事件處理、持有 Mytank 實例。Mytank:封裝坦克座標 x,y、方向 direct(0上 1下 2右 3左)及移動方法。public class MytankGame2 extends JFrame {
MyPanel mp;
public static void main(String[] args) { new MytankGame2(); }
public MytankGame2() {
mp = new MyPanel();
this.add(mp);
this.addKeyListener(mp);
this.setSize(270, 500);
this.setLocation(200, 200);
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
class MyPanel extends JPanel implements KeyListener {
Mytank mt = new Mytank(10, 10);
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 300, 400); // 清屏背景
drawTank(mt.getX(), mt.getY(), 0, mt.getDirect(), g);
}
void drawTank(int x, int y, int type, int direct, Graphics g) {
g.setColor(type == 0 ? Color.ORANGE : Color.BLUE);
switch (direct) {
case 0: // 上
g.fillRect(x, y, 5, 30); // 左履帶
g.fillRect(x+5, y+5, 20, 20); // 車身
g.fillRect(x+25, y, 5, 30); // 右履帶
g.setColor(Color.RED); g.drawLine(x+15, y-5, x+15, y+5); // 炮管
g.setColor(Color.GREEN); g.fillOval(x+7, y+7, 16, 16); // 炮塔
break;
case 1: // 下
g.fillRect(x, y, 5, 30);
g.fillRect(x+5, y+5, 20, 20);
g.fillRect(x+25, y, 5, 30);
g.setColor(Color.RED); g.drawLine(x+15, y+15, x+15, y+35);
g.setColor(Color.GREEN); g.fillOval(x+7, y+7, 16, 16);
break;
case 2: // 右
g.fillRect(x, y, 30, 5);
g.fillRect(x+5, y+5, 20, 20);
g.fillRect(x, y+25, 30, 5);
g.setColor(Color.RED); g.drawLine(x-5, y+15, x+15, y+15);
g.setColor(Color.GREEN); g.fillOval(x+7, y+7, 16, 16);
break;
case 3: // 左
g.fillRect(x, y, 30, 5);
g.fillRect(x+5, y+5, 20, 20);
g.fillRect(x, y+25, 30, 5);
g.setColor(Color.RED); g.drawLine(x+15, y+15, x+35, y+15);
g.setColor(Color.GREEN); g.fillOval(x+7, y+7, 16, 16);
break;
}
}
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_W: mt.setDirect(0); mt.moveUp(); break;
case KeyEvent.VK_S: mt.setDirect(1); mt.moveDown(); break;
case KeyEvent.VK_D: mt.setDirect(2); mt.moveRight(); break;
case KeyEvent.VK_A: mt.setDirect(3); mt.moveLeft(); break;
}
repaint(); // 觸發 paint 重繪
}
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
}
class Mytank {
private int x, y, direct;
public Mytank(int x, int y) { this.x = x; this.y = y; }
public void moveUp() { y -= 5; }
public void moveDown() { y += 5; }
public void moveLeft() { x -= 5; }
public void moveRight() { x += 5; }
// getter/setter 省略
}
Bullet 線程,碰撞檢測。update 使用 BufferStrategy 消除閃爍。