Matrix digital rain: Difference between revisions

m
J: rebuild to better match the movie
m (J: some minor documentation)
m (J: rebuild to better match the movie)
Line 1,049:
 
=={{header|J}}==
This implementation was written for jqt under j903, after studying https://youtu.be/MvEXkd3O2ow
 
Some key issues are the relatively low resolution of the screen, a somewhat slow update rate and some variation over time in the update rate of the screen. This is, of course, only an approximation...
 
<lang J>require'ide/qt/gl2'
Line 1,055 ⟶ 1,057:
 
junk=: 7 u:;48 65 16b30a1(+i.)&.>10 26 90
sz=:12840 7225
len=: <.1.4*{:sz
heat=: 0,(224 255 255)(len-1)}(<.0.5+255*(% >./)i.len)*/0 1 0
 
canvas=: sz$' '
hp=: sz$0
cols=: i.0
rows=: i.0
scale=: 24
live=: (#heat)#<i.3 0
 
update=: {{
try. glfill 0 0 0 255 catch. wd'timer 0' return. end.
glfont font=.'courier ',":0.8*scale
cols=: cols,?{.sz
upd=. 0>._3++/?2 2 2 2 4
rows=: rows,0
cols=: cols,upd{.(?~{.sz)-.(-<.0.3*{:sz){.cols
canvas=: (junk{~?(#cols)##junk) (cols,.rows)} canvas
hprows=: len (#cols,){.rows)} hp
live=: }.live,<(scale*cols,.rows),.?(#cols)##junk
for_p. }./:~~.0,,hplive do.
gltextcolor glrgb pp_index{heat
for_xy. ($hp)#:I.,p=hp do.
if.p_index=<:#live do.
gltextxy 10*xy
gltextglfont 8font,' u:(<xy) { canvasbold'
end.
for_xyj.;p do.
gltextxy 10*xy2{.xyj
gltext 8 u:junk{~{:xyj
end.
end. glpaint''
hp=: 0 >. hp-1
keep=: rows<{:sz-1
cols=: keep#cols
Line 1,085 ⟶ 1,090:
sys_timer_z_=: update_base_
 
wd rplc&('DIMS';":10scale*sz) {{)n
pc rain closeok;
setp wh DIMS;
cc green isidraw flush;
pshow;
timer 42100
}}</lang>
 
Notes:
 
<tt>timer 42100</tt> to roughly match the frameupdate rate used in the matrix movie (so we update the display roughly once every 42 milliseconds).
 
Some key data structures here are a matrix (pun intended) of displayed characters named 'canvas', a corresponding matrix counting how many screen updates remain for each character named 'hp', a list of candidate unicode characters named 'junk', a matrix representing color for each 'hp' value named 'heat' (initial value is white, when hp reaches zero, the value is black, in between are shades of green).
 
Also, there's a sequence of injection points characterized by 'cols' and 'rows', which (taken together) form an index into 'canvas' and into 'hp'. Every update, we add a random value to 'cols' and a corresponding zero to 'rows'. Also, every update, we add a new random character (picked from junk) to 'canvas' (with a corresponding max value added to 'hp') at every position characterized by the rows,cols pair. Then we update the display based on the canvas and hp{heat values. (Finally, in each update, we decrement every value in heat that was above zero, and remove from cols and rows a possible pair which corresponds to the last row of the screen.)
 
FIXME: document some of the rest of this...
Conceptually, it would be better to only track characters which would be rendered with green or white. This would allow multiple characters to be rendered at the same position (which would better match the characteristic behavior of the display tube mechanism being emulated here).
 
=={{header|Javascript}}==
6,951

edits