A plasma effect in Tcl
Download the plasma images and put them in a folder with this source code (named something appropriate, like plasma.tcl), and then run br plasma.tcl.
# a few defintions
#
set screen_w 256
set screen_h 180
set img_w 500
set img_h 400
set wave_w [expr {$img_w + 40}]
set wave_h [expr {$img_h + 40}]
set diff_w [expr {$img_w - $screen_w}]
set diff_h [expr {$img_h - $screen_h}]
#
# make a layer and set some layer options
#
set l [br::layer add]
set sl [lindex [br::layer info $l] 0]
br::layer sorted $l on
br::layer camera $l [expr {$diff_w/2}] [expr {$diff_h/2}]
#
# load the plasma sprites
#
foreach { img z } { p1 10 p2 10 p3 20 p4 20 } {
set sprites($img.id) [br::sprite create]
# read file from disk into the sprite and set its z-hint
br::sprite add-frame $sprites($img.id) [br::frame convert [br::frame from-disk $img.png] lt]
br::sprite z-hint $sprites($img.id) $z
# add it to the sprite list for our layer
br::list add $sl $sprites($img.id)
}
#
# generate some wave data for the wavy displacement sprites
#
for { set i 0 } { $i < $wave_h } { incr i } {
for { set j 0 } { $j < $wave_w } { incr j } {
lappend w1 [expr { int(-20.0 * sin($i*6.28/$img_h)) } ] [expr { int(-20.0 * sin($j*6.28/$img_w)) } ]
lappend w2 [expr { int(20.0 * sin($i*6.28/$img_h)) } ] [expr { int(20.0 * sin($j*6.28/$img_w)) } ]
}
}
# and load the wave data
foreach { w z } { w1 15 w2 30 } {
set sprites($w.id) [br::sprite create]
br::sprite add-frame-data $sprites($w.id) displ $wave_w $wave_h [binary format s* [set $w]]
br::sprite z-hint $sprites($w.id) $z
br::list add $sl $sprites($w.id)
}
#
# open graphics
#
br::graphics open accel $screen_w $screen_h off 3
br::render bg-color 0 0 0
br::render set-overdraw 40 40
#
# run the plasma loop
#
lassign { 0 0 0 0 0 0 } p1 p2 p3 p4 w1 w2
while 1 {
# update the plasmas
foreach { p adder } { p1 .01 p2 .03 p3 .02 p4 .02 } {
set $p [expr {[set $p] + $adder}]
br::sprite position $sprites($p.id) [expr { int( ($diff_w/2 - 40) * cos([set $p]))}] [expr { int( ($diff_h/2 - 40) * sin([set $p]))}]
}
# update the waves
foreach { w adder offset } { w1 .04 -40 w2 .04 -20 } {
set $w [expr {[set $w] + $adder}]
br::sprite position $sprites($w.id) [expr { $offset + int( ($diff_w/2 + $offset) * cos([set $w]))}] [expr { $offset + int( ($diff_h/2 + $offset) * sin([set $w]))}]
}
# display the frame
br::render display
br::delay 50
# quit on escape-keypress
set io [br::io fetch 0]
if { [lindex $io 7] || [br::io has-quit] } { exit }
}