| Fire FX: REALbasic |
|
|
|
| Friday, 03 October 2008 21:25 | |||||||||||||||||||
|
I'll be the first to admit i'm not a RB graphics guru. While in the days of DOS and when Turbo Pascal 7.0 ruled the programming air waves, I was quite the demo coder. In fact this project is routines that I remember doing back when. Be it most of the code was in assembler and ran a million times smoother and faster than this. I can still explain how the effects is made quite effectively with this REALbasic version. I'm sure its a lot more easier than if I was to torture your eyes with TASM versions.
Every fire needs a spark. Our fire is no different.
Starting off I choosed to make Phire class extend a Canvas and added the actionNotificationReceiver interface. Why I did this is to simplify things. If you look at the properties list of Phire you will see a property Cog that is of the Timer class. Normally Timer classes are only accessible at design time. In order to be able to use a timer at design time we would have had to use a Container Control. This would have added a bit of complexity to something not necessary. When you look at the constructor of Phire you will see Phire Constructor:
In the constructor I initiate a new timer object and than bind the action event of the timer to the Phire class using the addActionNotficationReciever. I also set some setting needed for the timer to function. I did not turn on the timer in the oconstructor. Instead I do this on Phire's Open event. Ok enough with the propriatary REALbasic stuff. More into how the fire effect works now. If you look in the constructor you will see a SetPalette method. This is important. In the world of demo's you want to have all your calculations ahead of time and stubbed before rendering. The more calculations you are doing at render time the slower and crappier your animation is going to be. In this case we are making a palette of colors that we are going to be using for our demo that is going to be ordered and sorted in a way that it will cut down a lot of calculations. SetPalette Method:
Simply all this does is makes a color array starting from black and fades into yellow by adjusting the red and green levels and a tiny bit of blue as the array goes from 0 to 255. If you want to change the colors you just need to tinker with this setting to make a green or blue flame. So last of the intialization process is the Open event. Open Event:
In this I define my double buffer area. So that what is getting posted to Phire canvas is a final picture not drawing directly to the main canvas. I redefined a voxel array that is a property of Phire that is design time initiated with -1,-1 dimensions. Which means there is no elements at all. What the voxel is is a staging area where we can compare colors purely by their indexes in the Palette array. Remember how we set the array? 0 is your coldest color and 255 is your hottest color. So that means you can say Palette(125) is a warm color which is hotter than Palette(50). This simplifies rendering in a big way. Last thing as we leave Open is I turned on the Timer object. Ok at this point the ball is in motion. The next thing to get triggered is PerformAction. Remember this method is a psuedo event triggered by our Timer object.
PerformAction Method:
Everytime we trigger this event the first thing we need to do is let all the other failed events triggered fall threw by placing right in the begining App.DoEvents. This will clear all the other queued events that triggered at the designated time but the thread was locked because it was already running. Ok, here is where things gets exciting. This is our spark that starts the fire. This array runs across the bottom of our screen sparking the flame. If your persceptive, right now your going, "WAIT! Your sparking the line just above the bottom. Why do that?" The reason is how I render the flames. If you put the sparks at the very bottom the effect won't get started because I reflect looking down. I'll explain later. More importantly what this for loop is doing is going from left to right randomly 1 to 4 putting a spark on that scan line. RenderVoxel Method:
Pretty straight forward. We are running through the screen left to right, bottom to top. As we run through our matrix we call CalculatePoint to figure out what color from the palette to use. Than paint it to the surface. To optimize things I check the activity of the scanline. if the scanline is black than quit rendering as we moved past the last tip of a flame. Now for the trickiest part of the whole effect. CalculatePoint Method:
What this method is doing is averaging all the pixels to the left, bottom left, bottom, bottom right and right. Basically everything but what is above the flame. The n variable is just a counter to count how many values were included. The screen edges are completely dropped from the equation as to not cause a cooling effect. When you get to the bottom you will notice that I decrement the value by 1. What we are comparing and calculating is where in our tempature scale color palette this point belongs in. As we move from our spark our flame needs to cool. Rather than use a more real world effect of including above cooler air I sumerized as anything moving from the source is a automatic -1. These calculations are so far from being used for physics that it really doesn't mater so long as it visually matches what we want. Remember what I was saying about the spark and how it has to be on the second line from the bottom. Well as you can see here if you put it at the very bottom your only going to get left and right. If its 1 in 4 that there will be a spark. You will quickly extinguish your flame. :-) Like a real fire this one needs breathing room. You can write out the flaw that causes this but it wasn't what I wanted and happy with the results this produced. The Paint event is merely just drawing the Double_Buffer picture to the canvas to be displayed to the user.
There you have it folks. The infamous fire effects commonly found in games and misc demos.Just remember most of this was originally written in assembly. So there is no reason why you can't have fun making it in whatever language of your choice.
Only registered users can write comments!
Powered by !JoomlaComment 3.26
3.26 Copyright (C) 2008 Compojoom.com / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved." |
|||||||||||||||||||
| Last Updated ( Saturday, 11 October 2008 17:47 ) | |||||||||||||||||||




