小九九 发表于 2024-6-23 17:05:33

Java坦克大战代码

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class TankMovementWithKeysAndBullets extends JPanel {

    private int x = 175;
    private int y = 340;
    private static final int TANK_WIDTH = 30;
    private static final int TANK_HEIGHT = 15;
    private static final int MOVE_DISTANCE = 5;

    private static final int CANNON_HEIGHT = 10;
    private static final int WHEEL_DIAMETER = 10;

    private List<Bullet> bullets = new ArrayList<>();
    private List<EnemyTank> enemyTanks = new ArrayList<>();
    private boolean spacePressed = false;
    private int cannonDirection = 0; // 0: up, 1: right, 2: down, 3: left
    private int enemiesDefeated = 0;

    public TankMovementWithKeysAndBullets() {
      addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                handleKeyPress(e.getKeyCode());
                repaint();
            }

            @Override
            public void keyReleased(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_SPACE) {
                  spacePressed = false;
                }
            }
      });
      setFocusable(true);

      new Thread(() -> {
            Random rand = new Random();
            while (true) {
                if (rand.nextInt(100) < 2 && enemyTanks.size() < 30) { // 2% chance to spawn an enemy tank, max 30
                  int side = rand.nextInt(4);
                  int enemyX = 0, enemyY = 0;
                  switch (side) {
                        case 0: // top
                            enemyX = rand.nextInt(getWidth());
                            enemyY = 0;
                            break;
                        case 1: // right
                            enemyX = getWidth();
                            enemyY = rand.nextInt(getHeight());
                            break;
                        case 2: // bottom
                            enemyX = rand.nextInt(getWidth());
                            enemyY = getHeight();
                            break;
                        case 3: // left
                            enemyX = 0;
                            enemyY = rand.nextInt(getHeight());
                            break;
                  }
                  enemyTanks.add(new EnemyTank(enemyX, enemyY, rand.nextInt(4), new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256))));
                }
                moveAndRemoveBullets();
                moveEnemyTanks();
                checkBulletCollisions();
                repaint();
                try {
                  Thread.sleep(10);
                } catch (InterruptedException e) {
                  e.printStackTrace();
                }
            }
      }).start();
    }

    private void handleKeyPress(int keyCode) {
      switch (keyCode) {
            case KeyEvent.VK_UP:
                if (y - MOVE_DISTANCE >= CANNON_HEIGHT) {
                  y -= MOVE_DISTANCE;
                }
                cannonDirection = 0;
                break;
            case KeyEvent.VK_DOWN:
                if (y + MOVE_DISTANCE <= getHeight() - TANK_HEIGHT - WHEEL_DIAMETER / 2) {
                  y += MOVE_DISTANCE;
                }
                cannonDirection = 2;
                break;
            case KeyEvent.VK_LEFT:
                if (x - MOVE_DISTANCE >= WHEEL_DIAMETER / 2) {
                  x -= MOVE_DISTANCE;
                }
                cannonDirection = 3;
                break;
            case KeyEvent.VK_RIGHT:
                if (x + MOVE_DISTANCE <= getWidth() - TANK_WIDTH - WHEEL_DIAMETER / 2) {
                  x += MOVE_DISTANCE;
                }
                cannonDirection = 1;
                break;
            case KeyEvent.VK_SPACE:
                if (!spacePressed) {
                  int bulletX = x + TANK_WIDTH / 2;
                  int bulletY = y - CANNON_HEIGHT;
                  switch (cannonDirection) {
                        case 0: // up
                            bulletY = y - CANNON_HEIGHT;
                            break;
                        case 1: // right
                            bulletX = x + TANK_WIDTH;
                            bulletY = y + TANK_HEIGHT / 2;
                            break;
                        case 2: // down
                            bulletX = x + TANK_WIDTH / 2;
                            bulletY = y + TANK_HEIGHT;
                            break;
                        case 3: // left
                            bulletX = x - CANNON_HEIGHT;
                            bulletY = y + TANK_HEIGHT / 2;
                            break;
                  }
                  bullets.add(new Bullet(bulletX, bulletY, cannonDirection));
                  spacePressed = true;
                }
                break;
      }
    }

    @Override
    protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      drawTank(g, x, y);
      for (Bullet bullet : bullets) {
            bullet.draw(g);
      }
      for (EnemyTank enemy : enemyTanks) {
            enemy.draw(g);
            for (Bullet enemyBullet : enemy.getBullets()) {
                enemyBullet.draw(g);
            }
      }
      g.setColor(Color.BLACK);
      g.drawString("Enemies Defeated: " + enemiesDefeated, 10, 20);
    }

    private void drawTank(Graphics g, int x, int y) {
      g.setColor(Color.YELLOW);
      g.fillRect(x, y, TANK_WIDTH, TANK_HEIGHT);
      g.setColor(Color.BLACK);
      switch (cannonDirection) {
            case 0: // up
                g.fillRect(x + (TANK_WIDTH / 2) - 2, y - CANNON_HEIGHT, 4, CANNON_HEIGHT);
                break;
            case 1: // right
                g.fillRect(x + TANK_WIDTH, y + (TANK_HEIGHT / 2) - 2, CANNON_HEIGHT, 4);
                break;
            case 2: // down
                g.fillRect(x + (TANK_WIDTH / 2) - 2, y + TANK_HEIGHT, 4, CANNON_HEIGHT);
                break;
            case 3: // left
                g.fillRect(x - CANNON_HEIGHT, y + (TANK_HEIGHT / 2) - 2, CANNON_HEIGHT, 4);
                break;
      }
      g.fillOval(x - WHEEL_DIAMETER / 2, y + TANK_HEIGHT - WHEEL_DIAMETER / 2, WHEEL_DIAMETER, WHEEL_DIAMETER);
      g.fillOval(x + TANK_WIDTH - WHEEL_DIAMETER / 2, y + TANK_HEIGHT - WHEEL_DIAMETER / 2, WHEEL_DIAMETER, WHEEL_DIAMETER);
    }

    private void moveAndRemoveBullets() {
      for (Bullet bullet : bullets) {
            bullet.move();
      }
      bullets.removeIf(bullet -> bullet.getY() < 0 || bullet.getY() > getHeight() || bullet.getX() < 0 || bullet.getX() > getWidth());
      for (EnemyTank enemy : enemyTanks) {
            for (Bullet enemyBullet : enemy.getBullets()) {
                enemyBullet.move();
            }
            enemy.getBullets().removeIf(bullet -> bullet.getY() < 0 || bullet.getY() > getHeight() || bullet.getX() < 0 || bullet.getX() > getWidth());
      }
    }

    private void moveEnemyTanks() {
      for (EnemyTank enemy : enemyTanks) {
            enemy.move(enemyTanks);
            if (new Random().nextInt(100) < 1) { // 1% chance to shoot
                enemy.shoot();
            }
      }
      enemyTanks.removeIf(enemy -> enemy.getX() < 0 || enemy.getX() > getWidth() || enemy.getY() < 0 || enemy.getY() > getHeight());
    }

    private void checkBulletCollisions() {
      Iterator<Bullet> bulletIterator = bullets.iterator();
      while (bulletIterator.hasNext()) {
            Bullet bullet = bulletIterator.next();
            Iterator<EnemyTank> enemyIterator = enemyTanks.iterator();
            while (enemyIterator.hasNext()) {
                EnemyTank enemy = enemyIterator.next();
                if (bullet.getX() >= enemy.getX() && bullet.getX() <= enemy.getX() + EnemyTank.ENEMY_TANK_WIDTH &&
                  bullet.getY() >= enemy.getY() && bullet.getY() <= enemy.getY() + EnemyTank.ENEMY_TANK_HEIGHT) {
                  enemyIterator.remove();
                  bulletIterator.remove();
                  enemiesDefeated++;
                  break; // Exit the inner loop after removing the enemy tank
                }
            }
      }
    }

    private class Bullet {
      private int x;
      private int y;
      private int direction;
      private static final int BULLET_SIZE = 3;
      private static final int BULLET_SPEED = 5;

      public Bullet(int x, int y, int direction) {
            this.x = x;
            this.y = y;
            this.direction = direction;
      }

      public int getX() {
            return x;
      }

      public int getY() {
            return y;
      }

      public void move() {
            switch (direction) {
                case 0: // up
                  y -= BULLET_SPEED;
                  break;
                case 1: // right
                  x += BULLET_SPEED;
                  break;
                case 2: // down
                  y += BULLET_SPEED;
                  break;
                case 3: // left
                  x -= BULLET_SPEED;
                  break;
            }
      }

      public void draw(Graphics g) {
            g.setColor(Color.RED);
            g.fillOval(x - BULLET_SIZE / 2, y - BULLET_SIZE / 2, BULLET_SIZE, BULLET_SIZE);
      }
    }

    private class EnemyTank {
      private int x;
      private int y;
      private int direction;
      private Color color;
      private static final int ENEMY_TANK_WIDTH = 30;
      private static final int ENEMY_TANK_HEIGHT = 15;
      private static final int ENEMY_MOVE_DISTANCE = 2;
      private List<Bullet> bullets = new ArrayList<>();

      public EnemyTank(int x, int y, int direction, Color color) {
            this.x = x;
            this.y = y;
            this.direction = direction;
            this.color = color;
      }

      public int getX() {
            return x;
      }

      public int getY() {
            return y;
      }

      public List<Bullet> getBullets() {
            return bullets;
      }

      public void move(List<EnemyTank> enemyTanks) {
            int newX = x;
            int newY = y;
            switch (direction) {
                case 0: // up
                  newY -= ENEMY_MOVE_DISTANCE;
                  break;
                case 1: // right
                  newX += ENEMY_MOVE_DISTANCE;
                  break;
                case 2: // down
                  newY += ENEMY_MOVE_DISTANCE;
                  break;
                case 3: // left
                  newX -= ENEMY_MOVE_DISTANCE;
                  break;
            }

            boolean collision = false;
            for (EnemyTank other : enemyTanks) {
                if (other != this && newX < other.getX() + ENEMY_TANK_WIDTH && newX + ENEMY_TANK_WIDTH > other.getX() &&
                  newY < other.getY() + ENEMY_TANK_HEIGHT && newY + ENEMY_TANK_HEIGHT > other.getY()) {
                  collision = true;
                  break;
                }
            }

            if (!collision) {
                x = newX;
                y = newY;
            } else {
                direction = new Random().nextInt(4); // 重新选择路线
            }
      }

      public void shoot() {
            int bulletX = x + ENEMY_TANK_WIDTH / 2;
            int bulletY = y - CANNON_HEIGHT;
            switch (direction) {
                case 0: // up
                  bulletY = y - CANNON_HEIGHT;
                  break;
                case 1: // right
                  bulletX = x + ENEMY_TANK_WIDTH;
                  bulletY = y + ENEMY_TANK_HEIGHT / 2;
                  break;
                case 2: // down
                  bulletX = x + ENEMY_TANK_WIDTH / 2;
                  bulletY = y + ENEMY_TANK_HEIGHT;
                  break;
                case 3: // left
                  bulletX = x - CANNON_HEIGHT;
                  bulletY = y + ENEMY_TANK_HEIGHT / 2;
                  break;
            }
            bullets.add(new Bullet(bulletX, bulletY, direction));
      }

      public void draw(Graphics g) {
            g.setColor(color);
            g.fillRect(x, y, ENEMY_TANK_WIDTH, ENEMY_TANK_HEIGHT);
            g.setColor(Color.BLACK);
            switch (direction) {
                case 0: // up
                  g.fillRect(x + (ENEMY_TANK_WIDTH / 2) - 2, y - CANNON_HEIGHT, 4, CANNON_HEIGHT);
                  break;
                case 1: // right
                  g.fillRect(x + ENEMY_TANK_WIDTH, y + (ENEMY_TANK_HEIGHT / 2) - 2, CANNON_HEIGHT, 4);
                  break;
                case 2: // down
                  g.fillRect(x + (ENEMY_TANK_WIDTH / 2) - 2, y + ENEMY_TANK_HEIGHT, 4, CANNON_HEIGHT);
                  break;
                case 3: // left
                  g.fillRect(x - CANNON_HEIGHT, y + (ENEMY_TANK_HEIGHT / 2) - 2, CANNON_HEIGHT, 4);
                  break;
            }
            g.fillOval(x - WHEEL_DIAMETER / 2, y + ENEMY_TANK_HEIGHT - WHEEL_DIAMETER / 2, WHEEL_DIAMETER, WHEEL_DIAMETER);
            g.fillOval(x + ENEMY_TANK_WIDTH - WHEEL_DIAMETER / 2, y + ENEMY_TANK_HEIGHT - WHEEL_DIAMETER / 2, WHEEL_DIAMETER, WHEEL_DIAMETER);
      }
    }

    public static void main(String[] args) {
      JFrame frame = new JFrame("可通过方向键移动且发射子弹的坦克");
      TankMovementWithKeysAndBullets panel = new TankMovementWithKeysAndBullets();

      frame.add(panel);
      frame.setSize(400, 400);
      frame.setVisible(true);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      panel.requestFocusInWindow();
    }
}

页: [1]
查看完整版本: Java坦克大战代码