少废话,当然借助了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; }
}