Java课程设计(双人对战游戏)持续更新......

少废话,当然借助了ai,就这么个实力,后续会逐渐完善......

考虑添加以下功能:

选将,选图,技能,天赋,道具,防反,反重力,物理反弹,击落,计分,粒子效果,打击感加强,陷阱,逃杀......

java 复制代码
package game;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;

public class GameFrame extends JFrame {
    public GameFrame() {
        setTitle("平台射击对战");
        setSize(800, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        add(new GamePanel());
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new GameFrame());
    }
}

class GamePanel extends JPanel implements KeyListener, ActionListener {
    private Player p1, p2;
    private Timer timer;
    private boolean[] keys = new boolean[256];
    private boolean gameOver = false;
    private boolean gameStarted = false;
    private JButton startButton, restartButton, exitButton;
    private List<Platform> platforms = new ArrayList<>();
    private List<Bullet> bullets = new ArrayList<>();

    public GamePanel() {
        setLayout(null);
        setFocusable(true);
        addKeyListener(this);

        // 对称平台布局
        platforms.add(new Platform(150, 350, 200, 20));  // 左平台
        platforms.add(new Platform(300, 250, 200, 20));  // 中央平台
        platforms.add(new Platform(450, 350, 200, 20));  // 右平台

        startButton = createButton("开始游戏", 300, 250);
        restartButton = createButton("重新开始", 300, 300);
        exitButton = createButton("退出游戏", 300, 350);

        restartButton.setVisible(false);
        exitButton.setVisible(false);

        add(startButton);
        add(restartButton);
        add(exitButton);

        startButton.addActionListener(e -> startGame());
        restartButton.addActionListener(e -> restartGame());
        exitButton.addActionListener(e -> System.exit(0));
    }

    private JButton createButton(String text, int x, int y) {
        JButton button = new JButton(text);
        button.setBounds(x, y, 200, 40);
        button.setFocusable(false);
        button.setFont(new Font("微软雅黑", Font.BOLD, 18));
        button.setBackground(new Color(200, 200, 200));
        return button;
    }

    private void startGame() {
        gameStarted = true;
        gameOver = false;
        bullets.clear();
        startButton.setVisible(false);
        restartButton.setVisible(false);
        exitButton.setVisible(false);

        p1 = new Player(100, 400, Color.BLUE, KeyEvent.VK_A, KeyEvent.VK_D, KeyEvent.VK_W, KeyEvent.VK_F);
        p2 = new Player(600, 400, Color.RED, KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT, KeyEvent.VK_UP, KeyEvent.VK_M);

        if (timer != null && timer.isRunning()) {
            timer.stop();
        }
        timer = new Timer(16, this);
        timer.start();
        requestFocusInWindow();
    }

    private void restartGame() {
        gameOver = false;
        gameStarted = false;
        startGame();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (!gameStarted) {
            g.setColor(new Color(30, 30, 30));
            g.fillRect(0, 0, getWidth(), getHeight());
            g.setColor(Color.WHITE);
            g.setFont(new Font("微软雅黑", Font.BOLD, 48));
            g.drawString("平台射击对战", 250, 150);
            return;
        }

        Graphics2D g2d = (Graphics2D) g;
        g2d.setPaint(new GradientPaint(0, 0, new Color(30, 30, 50), 0, 600, new Color(10, 10, 20)));
        g2d.fillRect(0, 0, getWidth(), getHeight());

        g.setColor(new Color(80, 50, 30));
        g.fillRect(0, 450, getWidth(), 150);
        g.setColor(new Color(110, 70, 40));
        for(int i=0; i<getWidth(); i+=30){
            g.fillRect(i, 450, 15, 10);
            g.fillRect(i+15, 460, 15, 10);
        }

        for (Platform platform : platforms) {
            platform.draw(g);
        }

        p1.draw(g);
        p2.draw(g);

        for (Bullet bullet : bullets) {
            bullet.draw(g);
        }

        drawHealthBar(g, p1, 20, 20);
        drawHealthBar(g, p2, getWidth() - 220, 20);

        if (gameOver) {
            g.setColor(new Color(255, 255, 255, 200));
            g.fillRect(0, 0, getWidth(), getHeight());
            g.setColor(Color.BLACK);
            g.setFont(new Font("微软雅黑", Font.BOLD, 48));
            String winner = p1.getHealth() <= 0 ? "红方胜利!" : "蓝方胜利!";
            g.drawString(winner, getWidth()/2 - 120, getHeight()/2);

            restartButton.setVisible(true);
            exitButton.setVisible(true);
        }
    }

    private void drawHealthBar(Graphics g, Player p, int x, int y) {
        g.setColor(Color.BLACK);
        g.fillRect(x, y, 200, 25);
        g.setColor(p.getColor());
        g.fillRect(x + 2, y + 2, (int)(196 * (p.getHealth() / 100.0)), 21);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (!gameOver && gameStarted) {
            handleInput();
            updatePlayers();
            updateBullets();
            checkCollisions();
            checkGameOver();
        }
        repaint();
    }

    private void handleInput() {
        p1.setMovingLeft(keys[p1.getLeftKey()]);
        p1.setMovingRight(keys[p1.getRightKey()]);
        if (keys[p1.getJumpKey()] && p1.isOnGround()) {
            p1.jump();
        }
        if (keys[p1.getAttackKey()] && p1.canAttack()) {
            bullets.add(p1.shoot());
        }

        p2.setMovingLeft(keys[p2.getLeftKey()]);
        p2.setMovingRight(keys[p2.getRightKey()]);
        if (keys[p2.getJumpKey()] && p2.isOnGround()) {
            p2.jump();
        }
        if (keys[p2.getAttackKey()] && p2.canAttack()) {
            bullets.add(p2.shoot());
        }
    }

    private void updatePlayers() {
        p1.update(getWidth(), platforms);
        p2.update(getWidth(), platforms);
    }

    private void updateBullets() {
        List<Bullet> toRemove = new ArrayList<>();
        for (Bullet bullet : bullets) {
            bullet.update();
            if (bullet.x < -10 || bullet.x > getWidth() + 10) {
                toRemove.add(bullet);
            }
        }
        bullets.removeAll(toRemove);
    }

    private void checkCollisions() {
        List<Bullet> toRemove = new ArrayList<>();
        for (Bullet bullet : bullets) {
            for (Platform platform : platforms) {
                if (bullet.hitsPlatform(platform)) {
                    toRemove.add(bullet);
                    break;
                }
            }

            Player target = bullet.shooter == p1 ? p2 : p1;
            if (bullet.hitsPlayer(target)) {
                target.takeDamage(10);
                toRemove.add(bullet);
            }
        }
        bullets.removeAll(toRemove);
    }

    private void checkGameOver() {
        if (p1.getHealth() <= 0 || p2.getHealth() <= 0) {
            gameOver = true;
            timer.stop();
        }
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() < keys.length) {
            keys[e.getKeyCode()] = true;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() < keys.length) {
            keys[e.getKeyCode()] = false;
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {}
}

class Player {
    private static final int GRAVITY = 1;
    private static final int JUMP_FORCE = -15;
    private static final int ATTACK_COOLDOWN = 30;
    private static final int SPEED = 5;
    private static final int BULLET_SPEED = 10;

    private int x, y;
    private int width = 40, height = 80;
    private int dx, dy;
    private int health = 100;
    private Color color;
    private boolean onGround = false;
    private int attackTimer = 0;
    private boolean movingLeft = false;
    private boolean movingRight = false;
    private boolean facingRight = true;
    private int leftKey, rightKey, jumpKey, attackKey;

    public Player(int x, int y, Color color, int leftKey, int rightKey, int jumpKey, int attackKey) {
        this.x = x;
        this.y = y;
        this.color = color;
        this.leftKey = leftKey;
        this.rightKey = rightKey;
        this.jumpKey = jumpKey;
        this.attackKey = attackKey;
    }

    public void update(int screenWidth, List<Platform> platforms) {
        // 处理水平移动
        dx = 0;
        if (movingLeft) {
            dx -= SPEED;
            facingRight = false;
        }
        if (movingRight) {
            dx += SPEED;
            facingRight = true;
        }

        // 保存移动前的坐标
        int xPrev = x;
        x += dx;
        x = Math.max(0, Math.min(screenWidth - width, x));

        // 水平碰撞检测
        Rectangle playerRect = getCollisionBounds();
        for (Platform platform : platforms) {
            Rectangle platformRect = platform.getBounds();
            if (playerRect.intersects(platformRect)) {
                if (dx > 0) { // 向右移动碰撞
                    x = platformRect.x - width;
                } else if (dx < 0) { // 向左移动碰撞
                    x = platformRect.x + platformRect.width;
                }
                break;
            }
        }

        // 处理垂直移动
        dy += GRAVITY;
        int yPrev = y;
        y += dy;

        // 垂直碰撞检测
        boolean isFalling = dy > 0;
        onGround = false;

        if (isFalling) {
            // 下落碰撞检测
            int playerBottomAfter = y + height;
            int playerBottomBefore = yPrev + height;

            Platform landingPlatform = null;
            int highestPlatformY = Integer.MIN_VALUE;

            for (Platform platform : platforms) {
                Rectangle platformRect = platform.getBounds();
                int platformTop = platformRect.y;
                int platformBottom = platformTop + platformRect.height;

                boolean xOverlap = (x < platformRect.x + platformRect.width) &&
                        (x + width > platformRect.x);

                if (xOverlap &&
                        playerBottomBefore <= platformTop &&
                        playerBottomAfter >= platformTop) {

                    if (platformTop > highestPlatformY) {
                        highestPlatformY = platformTop;
                        landingPlatform = platform;
                    }
                }
            }

            if (landingPlatform != null) {
                y = landingPlatform.getY() - height;
                dy = 0;
                onGround = true;
            } else {
                // 检查地面碰撞
                if (playerBottomAfter >= 450) {
                    y = 450 - height;
                    dy = 0;
                    onGround = true;
                }
            }
        } else if (dy < 0) {
            // 上升碰撞检测(头部碰撞)
            int playerTopAfter = y;
            int playerTopBefore = yPrev;

            Platform headPlatform = null;
            int lowestPlatformBottom = Integer.MAX_VALUE;

            for (Platform platform : platforms) {
                Rectangle platformRect = platform.getBounds();
                int platformBottom = platformRect.y + platformRect.height;

                boolean xOverlap = (x < platformRect.x + platformRect.width) &&
                        (x + width > platformRect.x);

                if (xOverlap &&
                        playerTopBefore >= platformBottom &&
                        playerTopAfter <= platformBottom) {

                    if (platformBottom < lowestPlatformBottom) {
                        lowestPlatformBottom = platformBottom;
                        headPlatform = platform;
                    }
                }
            }

            if (headPlatform != null) {
                y = headPlatform.getY() + headPlatform.getHeight();
                dy = 0;
            }
        }

        // 更新攻击计时器
        if (attackTimer > 0) {
            attackTimer--;
        }
    }

    public Bullet shoot() {
        attackTimer = ATTACK_COOLDOWN;
        int bulletX = facingRight ? x + width : x - 10;
        int bulletY = y + height/2 - Bullet.SIZE/2;
        return new Bullet(bulletX, bulletY, facingRight ? BULLET_SPEED : -BULLET_SPEED, this);
    }

    public void jump() {
        if (onGround) {
            dy = JUMP_FORCE;
            onGround = false;
        }
    }

    public void takeDamage(int damage) {
        health = Math.max(0, health - damage);
    }

    public void draw(Graphics g) {
        g.setColor(color);
        g.fillRect(x, y, width, height);
    }

    public Rectangle getCollisionBounds() {
        return new Rectangle(x + 5, y + 10, width - 10, height - 20);
    }

    public int getX() { return x; }
    public int getY() { return y; }
    public int getHealth() { return health; }
    public Color getColor() { return color; }
    public boolean isOnGround() { return onGround; }
    public void setMovingLeft(boolean moving) { movingLeft = moving; }
    public void setMovingRight(boolean moving) { movingRight = moving; }
    public boolean canAttack() { return attackTimer <= 0; }
    public int getLeftKey() { return leftKey; }
    public int getRightKey() { return rightKey; }
    public int getJumpKey() { return jumpKey; }
    public int getAttackKey() { return attackKey; }
}

class Bullet {
    int x, y;
    int speed;
    Player shooter;
    static final int SIZE = 10;

    public Bullet(int x, int y, int speed, Player shooter) {
        this.x = x;
        this.y = y;
        this.speed = speed;
        this.shooter = shooter;
    }

    public void update() {
        x += speed;
    }

    public void draw(Graphics g) {
        g.setColor(Color.YELLOW);
        g.fillOval(x, y, SIZE, SIZE);
    }

    public boolean hitsPlayer(Player player) {
        Rectangle bulletRect = new Rectangle(x, y, SIZE, SIZE);
        return bulletRect.intersects(player.getCollisionBounds());
    }

    public boolean hitsPlatform(Platform platform) {
        Rectangle bulletRect = new Rectangle(x, y, SIZE, SIZE);
        return bulletRect.intersects(platform.getBounds());
    }
}

class Platform {
    private int x, y, width, height;

    public Platform(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

    public void draw(Graphics g) {
        g.setColor(new Color(100, 100, 100));
        g.fillRect(x, y, width, height);
        g.setColor(new Color(120, 120, 120));
        g.fillRect(x, y, width, 3);
        g.fillRect(x, y + height - 3, width, 3);
    }

    public Rectangle getBounds() {
        return new Rectangle(x, y, width, height);
    }

    public int getY() { return y; }
    public int getHeight() { return height; }
}
相关推荐
枫叶落雨2222 分钟前
ShardingSphere 介绍
java
花花鱼8 分钟前
Spring Security 与 Spring MVC
java·spring·mvc
551只玄猫22 分钟前
【数学建模 matlab 实验报告13】主成分分析
开发语言·数学建模·matlab·课程设计·主成分分析
言慢行善1 小时前
sqlserver模糊查询问题
java·数据库·sqlserver
专吃海绵宝宝菠萝屋的派大星1 小时前
使用Dify对接自己开发的mcp
java·服务器·前端
大数据新鸟1 小时前
操作系统之虚拟内存
java·服务器·网络
Tong Z1 小时前
常见的限流算法和实现原理
java·开发语言
凭君语未可1 小时前
Java 中的实现类是什么
java·开发语言
He少年1 小时前
【基础知识、Skill、Rules和MCP案例介绍】
java·前端·python
克里斯蒂亚诺更新2 小时前
myeclipse的pojie
java·ide·myeclipse