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; }
}
相关推荐
申城异乡人6 分钟前
HttpClient使用方法总结及工具类封装
java
爱的叹息16 分钟前
Spring 约定编程案例与示例
java·后端·spring
lili-felicity17 分钟前
走进Java:学生管理系统进阶
java·开发语言
Seven9724 分钟前
【Guava】BiMap&Multimap&Multiset
java
a1800793108030 分钟前
软件工程面试题(六)
java·面试·软件工程
JIU_WW35 分钟前
JVM面试专题
java·jvm·面试·java虚拟机·垃圾回收
计算机程序设计开发37 分钟前
房地产数据可视化管理详细设计基于Spring Boot SSM原创
java·spring boot·信息可视化·毕设·计算机毕设
27669582921 小时前
拼多多 anti-token unidbg 分析
java·python·go·拼多多·pdd·pxx·anti-token
xyliiiiiL1 小时前
二分算法到红蓝染色
java·数据结构·算法