在电影《黑客帝国》中,屏幕上垂直流动的绿色字符雨幕效果给人留下了深刻的印象。这种效果不仅充满了神秘感,而且视觉冲击力强。在java中如何用实现类似的雨幕效果。
我们使用Java Swing来实现
创建一个Java Swing应用程序,模拟字符雨滴从屏幕顶部缓缓下落的动画效果。通过定时器控制字符的下落速度,并利用透明度渐变实现视觉上的残影效果。
我们将主要使用以下类和方法:
- RainEffect:主面板类,负责绘制和控制雨滴。
- RainDrop:内部类,表示单个雨滴。
- main 方法:创建并显示应用程序窗口。
代码:
package com.su.temp;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class RainEffect extends JPanel {
private static final char[] CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
private static final int FONT_SIZE = 20;
private static final int TIMER_DELAY = 20;
private static final int INITIAL_DELAY = 0;
private List<RainDrop> rainDrops = new ArrayList<>();
private Random random = new Random();
private Color backgroundColor = new Color(20, 20, 20);
public RainEffect() {
Timer timer = new Timer(TIMER_DELAY, e -> {
for (RainDrop drop : rainDrops) {
drop.y += drop.speed;
if (drop.y > getHeight()) {
drop.y = -FONT_SIZE;
drop.x = random.nextInt(Math.max(1, getWidth() / FONT_SIZE)) * FONT_SIZE;
drop.text = generateRandomText();
}
}
repaint();
});
timer.setInitialDelay(INITIAL_DELAY);
timer.start();
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
initializeRainDrops();
}
});
}
private void initializeRainDrops() {
rainDrops.clear();
int panelWidth = getWidth();
int panelHeight = getHeight();
if (panelWidth == 0 || panelHeight == 0) {
return;
}
int columns = Math.max(1, panelWidth / FONT_SIZE);
for (int i = 0; i < 100; i++) {
int x = random.nextInt(columns) * FONT_SIZE;
int y = random.nextInt(panelHeight);
int speed = random.nextInt(5) + 2;
String text = generateRandomText();
rainDrops.add(new RainDrop(x, y, speed, text));
}
}
private String generateRandomText() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
sb.append(CHARACTERS[random.nextInt(CHARACTERS.length)]);
}
return sb.toString();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
// 渐变背景
Paint oldPaint = g2d.getPaint();
g2d.setPaint(new GradientPaint(0, 0, Color.DARK_GRAY, 0, getHeight(), Color.BLACK));
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setPaint(oldPaint);
// 添加残影效果
g2d.setColor(new Color(0, 0, 0, 50));
g2d.fillRect(0, 0, getWidth(), getHeight());
// 绘制文字
g2d.setFont(new Font("Monospaced", Font.PLAIN, FONT_SIZE));
for (RainDrop drop : rainDrops) {
for (int i = 0; i < drop.text.length(); i++) {
g2d.setColor(new Color(0, 255, 0, 255 - i * 20));
g2d.drawString(String.valueOf(drop.text.charAt(i)), drop.x, drop.y + i * FONT_SIZE);
}
}
}
private static class RainDrop {
int x, y, speed;
String text;
public RainDrop(int x, int y, int speed, String text) {
this.x = x;
this.y = y;
this.speed = speed;
this.text = text;
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Rain Effect");
RainEffect rainEffect = new RainEffect();
frame.add(rainEffect);
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
SwingUtilities.invokeLater(rainEffect::initializeRainDrops);
}
}
效果: