|
| 1 | +# After original by Alex Young https://github.com/alexyoung/fire-p5r |
| 2 | + |
| 3 | +# Algorithm: |
| 4 | +# 1. Create an indexed palette of red, orange and yellows |
| 5 | +# 2. Loop: |
| 6 | +# 3. Draw a random set of colours from the palette at the bottom of the screen |
| 7 | +# 4. Loop through each pixel and average the colour index value around it |
| 8 | +# 5. Reduce the average by a fire intensity factor |
| 9 | + |
| 10 | +# k9 --run fire.rb |
| 11 | +load_library :palette |
| 12 | + |
| 13 | +def settings |
| 14 | + size 320, 240 |
| 15 | +end |
| 16 | + |
| 17 | +def setup |
| 18 | + sketch_title 'Fire' |
| 19 | + frame_rate 30 |
| 20 | + @palette = Palette.create_palette |
| 21 | + @fire = [] |
| 22 | + @scale = 8 |
| 23 | + @width = width / @scale |
| 24 | + @height = height / @scale |
| 25 | + @intensity = 2 |
| 26 | +end |
| 27 | + |
| 28 | +def draw |
| 29 | + background 0 |
| 30 | + update_fire |
| 31 | +end |
| 32 | + |
| 33 | +def update_fire |
| 34 | + random_line @height - 1 |
| 35 | + (0..@height - 2).each do |y| |
| 36 | + (0..@width).each do |x| |
| 37 | + # Wrap |
| 38 | + left = x.zero? ? fire_data(@width - 1, y) : fire_data(x - 1, y) |
| 39 | + right = (x == @width - 1) ? fire_data(0, y) : fire_data(x + 1, y) |
| 40 | + below = fire_data(x, y + 1) |
| 41 | + # Get the average pixel value |
| 42 | + average = (left.to_i + right.to_i + (below.to_i * 2)) / 4 |
| 43 | + # Fade the flames |
| 44 | + average -= @intensity if average > @intensity |
| 45 | + set_fire_data x, y, average |
| 46 | + fill @palette[average] |
| 47 | + stroke @palette[average] |
| 48 | + rect x * @scale, (y + 1) * @scale, @scale, @scale |
| 49 | + end |
| 50 | + end |
| 51 | +end |
| 52 | + |
| 53 | +def fire_data(x, y) |
| 54 | + @fire[offset(x, y)] |
| 55 | +end |
| 56 | + |
| 57 | +def set_fire_data(x, y, value) |
| 58 | + @fire[offset(x, y)] = value.to_i |
| 59 | +end |
| 60 | + |
| 61 | +def random_offset |
| 62 | + rand(0..@palette.size) |
| 63 | +end |
| 64 | + |
| 65 | +def random_line(y) |
| 66 | + (0...@width).each do |x| |
| 67 | + @fire[offset(x, y)] = random_offset |
| 68 | + end |
| 69 | +end |
| 70 | + |
| 71 | +def offset(x, y) |
| 72 | + (y * @width) + x |
| 73 | +end |
0 commit comments