Matrix digital rain: Difference between revisions
Content deleted Content added
m →{{header|J}}: bypass a potential qt message pump issue |
New post. |
||
Line 1,334: | Line 1,334: | ||
Conceptually, we are emulating an emulation of a cathode ray tube with a long phosphor persistence time. Thus, there's an initial "burst" of light when the phosphor is being painted followed by a lingering glow which gradually fades out. Here, we use a <span style="background-color: black; color: #e0ffff"> light cyan </span> to represent the initial paint event and <span style="color: #00ff00">f</span><span style="color: #00ec00">a</span><span style="color: #00da00">d</span><span style="color: #00c900">i</span><span style="color: #00b900">n</span><span style="color: #00aa00">g</span><span style="color: #009b00"> </span><span style="color: #008d00">s</span><span style="color: #007f00">h</span><span style="color: #007200">a</span><span style="color: #006600">d</span><span style="color: #005b00">e</span><span style="color: #004f00">s</span><span style="color: #004500"> </span><span style="color: #003b00">o</span><span style="color: #003100">f</span><span style="color: #002800"> </span><span style="color: #001f00">g</span><span style="color: #001700">r</span><span style="color: #000f00">e</span><span style="color: #000700">e</span><span style="color: #000000">n</span> to represent the fading phosphors. To better approximate the phosphor persistence mechanism, we have intensity fall off exponentially (and then we adjust the numeric range of the result so it still fades from our brightest green to black). |
Conceptually, we are emulating an emulation of a cathode ray tube with a long phosphor persistence time. Thus, there's an initial "burst" of light when the phosphor is being painted followed by a lingering glow which gradually fades out. Here, we use a <span style="background-color: black; color: #e0ffff"> light cyan </span> to represent the initial paint event and <span style="color: #00ff00">f</span><span style="color: #00ec00">a</span><span style="color: #00da00">d</span><span style="color: #00c900">i</span><span style="color: #00b900">n</span><span style="color: #00aa00">g</span><span style="color: #009b00"> </span><span style="color: #008d00">s</span><span style="color: #007f00">h</span><span style="color: #007200">a</span><span style="color: #006600">d</span><span style="color: #005b00">e</span><span style="color: #004f00">s</span><span style="color: #004500"> </span><span style="color: #003b00">o</span><span style="color: #003100">f</span><span style="color: #002800"> </span><span style="color: #001f00">g</span><span style="color: #001700">r</span><span style="color: #000f00">e</span><span style="color: #000700">e</span><span style="color: #000000">n</span> to represent the fading phosphors. To better approximate the phosphor persistence mechanism, we have intensity fall off exponentially (and then we adjust the numeric range of the result so it still fades from our brightest green to black). |
||
=={{header|Java}}== |
|||
<syntaxhighlight lang="java"> |
|||
import java.awt.Canvas; |
|||
import java.awt.Color; |
|||
import java.awt.Dimension; |
|||
import java.awt.EventQueue; |
|||
import java.awt.Font; |
|||
import java.awt.Graphics2D; |
|||
import java.awt.Point; |
|||
import java.awt.image.BufferStrategy; |
|||
import java.awt.image.BufferedImage; |
|||
import java.util.List; |
|||
import java.util.concurrent.ExecutorService; |
|||
import java.util.concurrent.Executors; |
|||
import java.util.concurrent.ThreadLocalRandom; |
|||
import java.util.concurrent.TimeUnit; |
|||
import java.util.stream.Collectors; |
|||
import java.util.stream.Stream; |
|||
import javax.swing.JFrame; |
|||
public final class MatrixDigitalRain { |
|||
public static void main(String[] args) { |
|||
EventQueue.invokeLater( () -> { |
|||
JFrame.setDefaultLookAndFeelDecorated(true); |
|||
JFrame frame = new JFrame("Matrix Digital Rain"); |
|||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
|||
frame.setResizable(false); |
|||
DigitalRain digitalRain = new DigitalRain(800, 600); |
|||
frame.add(digitalRain); |
|||
frame.setLocationByPlatform(true); |
|||
frame.pack(); |
|||
frame.setVisible(true); |
|||
digitalRain.start(); |
|||
} ); |
|||
} |
|||
private static final class DigitalRain extends Canvas { |
|||
public DigitalRain(int aWidth, int aHeight) { |
|||
setPreferredSize( new Dimension(aWidth, aHeight) ); |
|||
setBackground(Color.BLACK); |
|||
columnCount = aWidth / spacing; |
|||
rowCount = aHeight / spacing; |
|||
setCursor(getToolkit().createCustomCursor( |
|||
new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB), new Point(0, 0), "transparent")); |
|||
executiveService = Executors.newSingleThreadExecutor(); |
|||
random = ThreadLocalRandom.current(); |
|||
} |
|||
public void start() { |
|||
requestFocus(); |
|||
createBufferStrategy(2); |
|||
executiveService.execute( new DrawingCycle(rowCount) ); |
|||
} |
|||
private final class DrawingCycle implements Runnable { |
|||
public DrawingCycle(int rowCount) { |
|||
columns = Stream.generate( () -> new Column(rowCount) ) |
|||
.limit(columnCount / 2).collect(Collectors.toList()); |
|||
bufferStrategy = getBufferStrategy(); |
|||
} |
|||
@Override |
|||
public void run() { |
|||
while ( true ) { |
|||
draw(); |
|||
update(100); |
|||
} |
|||
} |
|||
private void draw() { |
|||
Graphics2D graphics2D = (Graphics2D) bufferStrategy.getDrawGraphics(); |
|||
graphics2D.setColor(Color.BLACK); |
|||
graphics2D.fillRect(0, 0, getWidth(), getHeight()); |
|||
for ( int col = 0; col < columnCount / 2; col++ ) { |
|||
for ( int row = 0; row < rowCount; row++ ) { |
|||
Symbol symbol = columns.get(col).symbols.get(row); |
|||
graphics2D.setFont(symbol.font); |
|||
graphics2D.setColor(symbol.color()); |
|||
graphics2D.drawString(symbol.element, ( 2 * col + 1 ) * spacing, row * spacing); |
|||
} |
|||
} |
|||
graphics2D.dispose(); |
|||
bufferStrategy.show(); |
|||
} |
|||
private void update(long delay) { |
|||
for ( Column column : columns ) { |
|||
if ( column.index >= 0 ) { |
|||
String element = elements.get(random.nextInt(elements.size())); |
|||
column.symbols.set(column.index, new Symbol(element, column.font, 255) ); |
|||
} |
|||
column.index = Math.min(column.index + 1, rowCount); |
|||
column.darken(); |
|||
if ( column.index == rowCount ) { |
|||
column.reset(); |
|||
} |
|||
} |
|||
try { |
|||
TimeUnit.MILLISECONDS.sleep(delay); |
|||
} catch (InterruptedException ie) { |
|||
Thread.currentThread().interrupt(); |
|||
} |
|||
} |
|||
private final BufferStrategy bufferStrategy; |
|||
private final List<Column> columns; |
|||
} // End DrawingCycle class |
|||
private static final class Column { |
|||
public Column(int aRowCount) { |
|||
rowCount = aRowCount; |
|||
index = random.nextInt(-rowCount, rowCount); |
|||
setFont(); |
|||
symbols = Stream.generate( () -> new Symbol(font) ).limit(rowCount).collect(Collectors.toList()); |
|||
} |
|||
public void darken() { |
|||
symbols.stream().forEach(Symbol::darken); |
|||
} |
|||
public void reset() { |
|||
index = random.nextInt(-rowCount, rowCount / 2); |
|||
setFont(); |
|||
} |
|||
private void setFont() { |
|||
final int fontSize = ( random.nextInt(2) == 0 ) ? 12 : ( random.nextInt(2) == 0 ) ? 9 : 18; |
|||
final int fontStyle = ( random.nextInt(3) == 0 ) ? Font.BOLD : Font.PLAIN; |
|||
font = new Font("Dialog", fontStyle, fontSize); |
|||
} |
|||
private int index; |
|||
private Font font; |
|||
private List<Symbol> symbols; |
|||
private final int rowCount; |
|||
} // End Column class |
|||
private static final class Symbol { |
|||
public Symbol(String aElement, Font aFont, int aBrightness) { |
|||
element = aElement; |
|||
font = aFont; |
|||
brightness = aBrightness; |
|||
} |
|||
public Symbol(Font font) { |
|||
this(" ", font, 0); |
|||
} |
|||
public Color color() { |
|||
return new Color(0, 255, 0, brightness); |
|||
} |
|||
public void darken() { |
|||
brightness = Math.max(0, brightness - 5); |
|||
} |
|||
public String toString() { |
|||
return element; |
|||
} |
|||
private int brightness; |
|||
private final Font font; |
|||
private final String element; |
|||
} // End Symbol class |
|||
private final int columnCount; |
|||
private final int rowCount; |
|||
private final ExecutorService executiveService; |
|||
private final int spacing = 10; |
|||
private final List<String> elements = List.of( |
|||
"M", "Ї", "Љ", "Њ", "Ћ", "Ќ", "Ѝ", "Ў", "Џ", "Б", "Г", "Д", "Ж", "И", "Й", "Л", "П", "Ф", "Ц", "Ч", "Ш", |
|||
"Щ", "Ъ", "Ы", "Э", "Ю", "Я", "в", "д", "ж", "з", "и", "й", "к", "л", "м", "н", "п", "т", "ф", "ц", "ч", |
|||
"ш", "щ", "ъ", "ы", "ь", "э", "ю", "я", "ѐ", "ё", "ђ", "ѓ", "є", "ї", "љ", "њ", "ћ", "ќ", "ѝ", "ў", "џ", |
|||
"Ѣ", "ѣ", "ѧ", "Ѯ", "ѱ", "Ѳ", "ѳ", "ҋ", "Ҍ", "ҍ", "Ҏ", "ҏ", "Ґ", "ґ", "Ғ", "ғ", "Ҕ", "ҕ", "Җ", "җ", "Ҙ", |
|||
"ҙ", "Қ", "қ", "ҝ", "ҟ", "ҡ", "Ң", "ң", "Ҥ", "ҥ", "ҩ", "Ҫ", "ҫ", "Ҭ", "ҭ", "Ұ", "ұ", "Ҳ", "ҳ", "ҵ", "ҷ", |
|||
"ҹ", "Һ", "ҿ", "Ӂ", "ӂ", "Ӄ", "ӄ", "ӆ", "Ӈ", "ӈ", "ӊ", "Ӌ", "ӌ", "ӎ", "Ӑ", "ӑ", "Ӓ", "ӓ", "Ӕ", "ӕ", "Ӗ", |
|||
"ӗ", "Ә", "ә", "Ӛ", "ӛ", "Ӝ", "ӝ", "Ӟ", "ӟ", "ӡ", "Ӣ", "ӣ", "Ӥ", "ӥ", "Ӧ", "ӧ", "Ө", "ө", "Ӫ", "ӫ", "Ӭ", |
|||
"ӭ", "Ӯ", "ӯ", "Ӱ", "ӱ", "Ӳ", "ӳ", "Ӵ", "ӵ", "Ӷ", "ӷ", "Ӹ", "ӹ", "Ӻ", "ӽ", "ӿ", "Ԁ", "ԍ", "ԏ", "Ԑ", "ԑ", |
|||
"ԓ", "Ԛ", "ԟ", "Ԧ", "ԧ", "Ϥ", "ϥ", "ϫ", "ϭ", "ゥ", "ェ", "ォ", "ャ", "ュ", "ョ", "ッ", "ー", "ア", "イ", "ウ", "エ", |
|||
"オ", "カ", "キ", "ク", "ケ", "コ", "サ", "シ", "ス", "セ", "ソ", "タ", "チ", "ツ", "テ", "ト", "ナ", "ニ", "ヌ", "ネ", "ノ", |
|||
"ハ", "ヒ", "フ", "ヘ", "ホ", "マ", "ミ", "ム", "メ", "モ", "ヤ", "ユ", "ヨ", "ラ", "リ", "ル", "レ", "ロ", "ワ", "ン", "ⲁ", |
|||
"Ⲃ", "ⲃ", "Ⲅ", "Γ", "Δ", "Θ", "Λ", "Ξ", "Π", "Ѐ", "Ё", "Ђ", "Ѓ", "Є", "ⲉ", "Ⲋ", "ⲋ", "Ⲍ", "ⲍ", "ⲏ", "ⲑ", |
|||
"ⲓ", "ⲕ", "ⲗ", "ⲙ", "ⲛ", "Ⲝ", "ⲝ", "ⲡ", "ⲧ", "ⲩ", "ⲫ", "ⲭ", "ⲯ", "ⳁ", "Ⳉ", "ⳉ", "ⳋ", "ⳤ", "⳥", "⳦", "⳨", |
|||
"⳩", "∀", "∁", "∂", "∃", "∄", "∅", "∆", "∇", "∈", "∉", "∊", "∋", "∌", "∍", "∎", "∏", "∐", "∑", "∓", "ℇ", |
|||
"ℏ", "℥", "Ⅎ", "ℷ", "⩫", "⨀", "⨅", "⨆", "⨉", "⨍", "⨎", "⨏", "⨐", "⨑", "⨒", "⨓", "⨔", "⨕", "⨖", "⨗", "⨘", |
|||
"⨙", "⨚", "⨛", "⨜", "⨝", "⨿", "⩪" ); |
|||
private static ThreadLocalRandom random; |
|||
} // End DigitalRain class |
|||
} // End MatrixDigitalRain class |
|||
</syntaxhighlight> |
|||
=={{header|Javascript}}== |
=={{header|Javascript}}== |