Created
July 11, 2024 05:04
-
-
Save pentaphobe/47330886270a988af56ef7ec6bf6306c to your computer and use it in GitHub Desktop.
Fire effect in evy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cell_size := 2 | |
cells_width := 100 / cell_size | |
cells_height := 100 / cell_size | |
cells := [[0]*cells_width] * cells_height | |
// Defines the gradient used for our flame cells | |
palette_stops := [ | |
// black | |
{pos:0 col:{hue:12 sat:2 light:0}} | |
// smoke! | |
{pos:20 col:{hue:12 sat:2 light:30}} | |
// black (end of flames) - using two stops here to make a wide black band | |
{pos:30 col:{hue:12 sat:2 light:0}} | |
{pos:60 col:{hue:12 sat:100 light:0}} | |
// dark red | |
{pos:100 col:{hue:12 sat:100 light:20}} | |
// orange | |
{pos:128 col:{hue:28 sat:100 light:44}} | |
// bright orange | |
{pos:164 col:{hue:28 sat:100 light:89}} | |
// very bright yellow | |
{pos:256 col:{hue:51 sat:100 light:100}} | |
] | |
// generate our array of pre-generated colours | |
palette := (build_palette palette_stops) | |
// add some random specs to the screen to start with | |
init_cells | |
on animate | |
draw_cells | |
update_cells | |
end | |
func update_cells | |
// add some random colours at the bottom | |
for col := range 0 cells_width | |
cells[cells_height - 1][col] = (rand 256) | |
end | |
// weights used for blending colours from the current row and the one below | |
weightNextMid := 8 | |
weightNextSide := 4 | |
weightCurMid := 6 | |
weightCurSide := 1 | |
weightRand := 0 | |
divis := weightNextMid + (weightNextSide * 2) + weightCurMid + (weightCurSide * 2) + weightRand | |
for row := range 0 cells_height | |
thisrow := cells[row] | |
nextrow := cells[(constrain (row + 1) 0 cells_height-1)] | |
for col := range 0 cells_width | |
left := constrain (col - 1) 0 cells_width-1 | |
right := constrain (col + 1) 0 cells_width-1 | |
accum := thisrow[col] * weightCurMid | |
accum = accum + (thisrow[left] * weightCurSide) + (thisrow[right] * weightCurSide) | |
accum = accum + nextrow[col] * weightNextMid | |
accum = accum + (nextrow[left] * weightNextSide) + (nextrow[right] * weightNextSide) | |
// removed random just in case it's slowing things down | |
//accum = accum + ((rand 16) * weightRand) | |
accum = accum / divis | |
accum = accum - 2 | |
if accum < 0 | |
accum = 0 | |
end | |
thisrow[col] = (round accum) | |
end | |
end | |
end | |
func init_cells | |
for row := range 0 cells_height | |
for col := range 0 cells_width | |
cells[row][col] = (rand 64) | |
end | |
end | |
end | |
func draw_cells | |
color "rgb(255 0 255)" | |
for row := range 0 cells_height | |
y := 100 - (row * cell_size) - cell_size | |
for col := range 0 cells_width | |
x := (col * cell_size) | |
val := cells[row][col] | |
color palette[val] | |
move x y | |
rect cell_size cell_size | |
end | |
end | |
end | |
// interpolate from one number to another | |
// amount is how far between a and b we get | |
// | |
// a ----------------------------- b | |
// 0 0.5 1 | |
func interp:num a:num b:num amount:num | |
delta := b - a | |
return a + (delta * amount) | |
end | |
// colorMix is like interp but for colours | |
// it blends between the two provided colours based on amount | |
// and returns a string you can use with color() | |
func colorMix:string a:{}num b:{}num amount:num | |
h := interp a.hue b.hue amount | |
s := interp a.sat b.sat amount | |
l := interp a.light b.light amount | |
return sprintf "hsl(%.fdeg %.f%% %.f%%)" h s l | |
end | |
// convert a number from one range to another | |
// eg. | |
// | |
// remap 5 [0 10] [50 100] | |
// | |
// would turn 5 into 75 | |
func remap:num in:num inRange:[]num outRange:[]num | |
result := in - inRange[0] | |
result = result / (inRange[1] - inRange[0]) | |
result = result * (outRange[1] - outRange[0]) | |
result = result + outRange[0] | |
return max outRange[0] (min outRange[1] result) | |
end | |
func constrain:num in:num minimum:num maximum:num | |
if in < minimum | |
return minimum | |
else if in >= maximum | |
return maximum | |
end | |
return in | |
end | |
func build_palette:[]string stops:[]{}any | |
palette := [""] * 256 | |
for i := range (len stops)-1 | |
from := stops[i] | |
to := stops[i + 1] | |
palette = build_palette_range palette from to | |
end | |
return palette | |
end | |
func build_palette_range:[]string palette:[]string stop1:{}any stop2:{}any | |
startPos := stop1.pos.(num) | |
endPos := stop2.pos.(num) | |
for idx := range startPos endPos | |
amount := remap idx [startPos endPos] [0 1] | |
palette[idx] = colorMix stop1.col.({}num) stop2.col.({}num) amount | |
end | |
return palette | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment