|
- 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、本站资源来自互联网用户收集发布,仅供用于学习和交流。
2、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。
3、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决。
4、联系邮箱:admin@panjdzy.com
5、官方网址:www.panjdzy.com
6、备用网址:www.panjd.top
上一篇:一根万能角钢重 5kg,长 2 米,求其单位长度的质量。下一篇:JavaFX SDK相关配置
|