Java版字符雨效果,hold不住的感觉

  思路总体分为几点:

  一、如何实现一列字符向下滑动的效果?其实就是把字符序列逐个字符地输出在屏幕上,保持x轴不变,随时间改变y轴坐标= =

  二、如何展现多列字符向下滑动?其实就是上例的推广,作一个循环来处理不同的列。

  为了保证效果,可以先为每列定义一个随机化初始位置,还可以加一个不同的速度和加速度= =

  实现中,我先把屏幕进行了划分,计算出所需要的字符序列行列数,随机生成。

  之后就只是从里面取字符,加速度啥的没有去做= =

  当然也可以作一个改变,由自己输入多行不同的字符串之类,可能效果看着更有新鲜感= =

  三、如何实现颜色效果?仔细看下Matrix中的字符雨,大概上就是一个从黑到绿的颜色过渡。

  实现这种过渡也就是改变RGB值中的G分量大小,很容易= =

  import java.awt.*;

  import java.util.Random;

  import javax.swing.JFrame;

  class RainCanvas extends Canvas implements Runnable {

  private int width, height;

  private Image offScreen; //缓冲图片

  private char[][] charset; //随机字符集合

  private int[] pos; //列的起始位置

  private Color[] colors = new Color[30]; //列的渐变颜色

  public RainCanvas(int width, int height) {

  this.width = width;

  this.height = height;

  //生成ASCII可见字符集合

  Random rand = new Random();

  charset = new char[width / 10][height / 10];

  for (int i = 0; i < charset.length; i++) {

  for (int j = 0; j < charset.length; j++) {

  charset[j] = (char) (rand.nextInt(96) + 33);

  }

  }

  //随机化列起始位置

  pos = new int[charset.length];

  for (int i = 0; i < pos.length; i++) {

  pos = rand.nextInt(pos.length);

  }

  //生成从黑色到绿色的渐变颜色,最后一个保持为白色

  for (int i = 0; i < colors.length - 1; i++) {

  colors = new Color(0, 255 / colors.length * (i + 1), 0);

  }

  colors[colors.length - 1] = new Color(255, 255, 255);

  setBackground(Color.BLACK);

  setSize(width, height);

  setVisible(true);

  }

  public void startRain() {

  new Thread(this).start();

  }

  public void drawRain() {

  if (offScreen == null) {

  return;

  }

  Random rand = new Random();

  Graphics g = offScreen.getGraphics();

  g.clearRect(0, 0, width, height);

  g.setFont(new Font("Arial", Font.BOLD, 12));

  //

  for (int i = 0; i < charset.length; i++) {

  int speed = rand.nextInt(2);

  for (int j = 0; j < colors.length; j++) {

  int index = (pos + j) % charset.length;

  g.setColor(colors[j]);

  g.drawChars(charset, index, 1, i * 10, index * 10);

  }

  pos = (pos + 1) % charset.length;

  }

  }

  @Override

  public void update(Graphics g) {

  paint(g);

  }

  public void run() {

  while (true) {

  drawRain();

  repaint();

  try {

  Thread.sleep(50); //可改变睡眠时间以调节速度

  } catch (InterruptedException e) {

  System.out.println(e);

  }

  }

  }

  @Override

  public void paint(Graphics g) {

  //当组件显示时检测是否要创建缓冲图片,在组件还不可见时调用createImage将返回null

  if (offScreen == null) {

  offScreen = createImage(width, height);

  }

  g.drawImage(offScreen, 0, 0, this);

  }

  }

  public class Test extends JFrame {

  private RainCanvas canvas = new RainCanvas(860, 480);

  public Test() {

  super("Test");

  getContentPane().add(canvas);

  setSize(860, 480);

  setVisible(true);

  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  }

  public static void main(String[] args) {

  Test test = new Test();

  test.canvas.startRain();

  }

  }

  补充:如果需要全屏显示,可以在Test类的构造函数中再加上

  setUndecorated(true);

  setExtendedState(JFrame.MAXIMIZED_BOTH);

  这两句来设置无边框和最大化,修改后如下

  public class Test extends JFrame {

  private RainCanvas canvas;

  public Test() {

  super("Test");

  setUndecorated(true);

  setExtendedState(JFrame.MAXIMIZED_BOTH);

  setVisible(true);

  canvas = new RainCanvas(this.getWidth(), this.getHeight());

  getContentPane().add(canvas);

  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  }

  public static void main(String[] args) {

  Test test = new Test();

  test.canvas.startRain();

  }

  }

  如果需要修改屏幕上的字符序列个数,可以修改new charset[widht/10][height/10]这里的widht/10的值,

  对应的g.drawChars(charset, index, 1, i * 10, index * 10);这里的坐标值也要进行修改。

  要重新设定Font的大小,直接修改new Font("Arial", Font.BOLD, 15)这处

  这些最好是定义成一个字面常量或抽取出方法来进行设置= =

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值