📜  召唤具有爆炸半径的火球 - Java (1)

📅  最后修改于: 2023-12-03 14:50:37.533000             🧑  作者: Mango

召唤具有爆炸半径的火球 - Java

在游戏开发中,经常需要实现召唤具有爆炸半径的火球的功能。下面给出一种实现方式。

思路

利用Java中的Graphics2D类,在画布上绘制一个圆形,并使用渐变色填充,实现火球的效果。通过计时器不断更新火球的位置和半径,达到动态效果。当火球半径达到指定大小后,触发爆炸效果,使用粒子系统模拟火焰爆炸的效果。

代码实现

以下是实现召唤具有爆炸半径的火球的Java代码片段:

import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RadialGradientPaint;
import java.awt.geom.Point2D;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class FireBall extends JPanel {
    private int x, y; // 火球中心坐标
    private int radius; // 火球半径
    private int maxSize = 100; // 最大半径
    private int speed = 3; // 移动速度
    private Timer timer; // 定时器
    private boolean exploded = false; // 是否已经爆炸

    public FireBall(int x, int y) {
        this.x = x;
        this.y = y;
        this.radius = 0;
        startTimer();
    }

    private void startTimer() {
        timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                // 更新火球位置和半径
                x += speed;
                radius += 2;
                if (radius >= maxSize) {
                    // 火球达到最大半径,触发爆炸
                    exploded = true;
                    stopTimer();
                }
                // 重画面板
                repaint();
            }
        };
        timer.schedule(task, 0, 50);
    }

    private void stopTimer() {
        timer.cancel();
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;

        if (!exploded) {
            // 绘制火球
            Point2D center = new Point2D.Float(x, y);
            float[] dist = { 0.0f, 1.0f };
            Color[] colors = { Color.RED, Color.ORANGE };
            RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors);
            g2d.setPaint(paint);
            g2d.fillOval(x - radius, y - radius, radius * 2, radius * 2);
        } else {
            // 绘制爆炸效果
            int numParticles = 80; // 粒子数量
            for (int i = 0; i < numParticles; i++) {
                double angle = Math.random() * Math.PI * 2;
                double distance = Math.random() * radius;
                int px = (int) (x + distance * Math.cos(angle));
                int py = (int) (y + distance * Math.sin(angle));
                Particle p = new Particle(px, py);
                p.draw(g2d);
            }
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("FireBall");
        FireBall panel = new FireBall(100, 100);
        frame.add(panel);
        frame.setSize(400, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    // 内部类,表示火球爆炸后的粒子效果
    private class Particle {
        private int x, y; // 粒子坐标
        private int size; // 粒子大小
        private int speed; // 粒子移动速度
        private int life; // 粒子寿命
        private Color color; // 粒子颜色

        public Particle(int x, int y) {
            this.x = x;
            this.y = y;
            this.size = (int) (Math.random() * 20);
            this.speed = (int) (Math.random() * 5);
            this.life = (int) (Math.random() * 50);
            this.color = new Color((int) (Math.random() * 255), (int) (Math.random() * 255), (int) (Math.random() * 255));
        }

        public void draw(Graphics2D g2d) {
            g2d.setColor(color);
            g2d.fillOval(x, y, size, size);
            life--;
            if (life <= 0) {
                // 粒子寿命结束,从集合中移除
                FireBall.this.removeParticle(this);
            }
            x += speed;
            y += speed;
        }
    }

    // 内部方法,移除已经死亡的粒子
    private void removeParticle(Particle p) {
        // TODO
    }
}
使用方法

新建一个FireBall对象,传入火球中心的坐标,将其加入需要显示的面板中。执行程序后,会在面板中显示出火球并开始动态效果,当火球半径达到最大值时,会自动触发爆炸效果。