Omnimaga
Calculator Community => TI Calculators => Axe => Topic started by: Builderboy on February 20, 2011, 01:20:16 am
-
Do you want your title screens to look like this?
(http://www.omnimaga.org/index.php?action=dlattach;topic=6579.0;attach=6102;image)
If so, go no further because in this tutorial, I will be discussing how to get epic fire effects into your games and title screens using Axe. This is applicable to either white fire or black fire, with, or without objects in the fire.
The rules of the fire are simple. Take each pixel, move that pixel up, then also randomly erase pixels. Since each pixel on the screen has an equal probability of being erased, pixels near the top have a lower probability of being set, because the pixels would have had to travel all the way from the bottom to the top without getting erased. But thats a lot of mumbo jumbo, lets get straight to the code:
.Axe
ClrDraw
[FEFDFBF7EFDFBD7F]->Str1 //Each Byte here has 7 bits set and 1 bit not set (like FE is 11111110 in binary)
//This is so that we can erase a random pixel, since Axe has no built in way to do that
Line(0,63,95,63 //the pixels to catch fire, explained a little later
Repeat getKey(15) //until we press clear
For(F,L6+12,L6+767 //loop through all of the screen pixels except the last 12
{F} and {rand^8+Str1}->{F-12} //take the byte, use AND to erase a single bit from it, and then store it into the byte directly *above* it
End //this makes it so that as the byte rises, each frame a pixel is erased from it
DispGraph
End
So why do we need the line command? Well because this routine needs fuel. What that means is that if you draw a sprite onto the screen while this routine is running, that sprite will catch fire automatically. If you stop drawing the sprite, it will rise and vanish like smoke. Anything you draw onto the part of the screen that is being 'flamed' will automatically catch fire, and will continue to be on fire until you stop drawing it, at which point it will vanish like smoke. Go ahead try it out!
Also, some of you may want to try a black background with white smoke. the principles are exactly the same, but everything is inverted. Instead of FE (11111110), you would use 01 (00000001), and instead of using AND, you would use OR. Its that simple :)
-
Wow, this is awesome :o
Now I can make that "light people on fire" game I was going to make a while back ;)
How well would this work for animated sprites? And is there a way to make only part of the screen (say, a sprite) on fire?
-
Wow, this is awesome :o
Now I can make that "light people on fire" game I was going to make a while back ;)
How well would this work for animated sprites? And is there a way to make only part of the screen (say, a sprite) on fire?
Yep. Draw the sprite in two parts (assuming you'll be erasing the sprite every cycle to allow movement). Draw the first part on the buffer before the For( loop and draw the second part after the For( loop. Only the first part will be on fire. I wouldn't recommend this method for processor intensive games though, because it's slow.
-
So, I would xor the second sprites back to nothing, I guess?
I could use RecallPic, but that erases the buffer like pt-off...
-
@Qwerty that wouldn't work because there is no ClrDraw, so there is no difference between doing it before or after.
It could work very well for animated sprites, and with masking you could make it so that only the top of them is on fire and nothing inside.
However, making only a section of the screen create fire is difficult. This is a screen effect, not an object effect, so anything that passes into the 'fire field' will catch on fire. Also, since this is byte based, you would have to make the fire field out of whole bytes, unless you wanted to get into some complicated byte masking.
-
Builder, it wouldn't work? I wonder why it works on my calculator then.
-
Oh do you XOR it on, and then XOR it off?
-
Not for the front buffer where the flames are.
-
Ooooh, nice Builderboy, thanks much ;D
-
Wait do you use the backbuffer then? I was responding to your original idea, where you just said to do it after the for loop
-
I'm using both buffers for graphics. The front buffer holds part of the sprite and the back buffer holds another part. I tried moving the part from after the For( loop (where there was no fire on the sprite) to before it and fire appeared.
-
Gotcha, although how are you using both the buffers? Are you copying from one buffer to another? Using greyscale?
-
I'm swapping between the normal two buffers and a third buffer, which holds specific data from the first two buffers. Basically, it's just greyscale though.
-
o.O Gotcha. Well, to summarize, I was merely responding to your original post, since you didn't say anything about 2 or 3 buffers or anything, I didn't understand ^^
-
I only changed the stuff concerning the front buffer, so I didn't think it was necessary to describe the others.
-
Hmmm well using only one buffer, it shouldn't matter whether or not you have it before or after the for loop, unless you were XORing it right after you displayed it.
-
Random question about the routine. Would using Rect( work?
-
Yes it would, you would get a nice flaming rectangle :) Also note that with this routing there is no need to erase your sprites unless you don't want them to be on fire
-
Wow, this is really cool. Would you mind if I used your code in my game?
-
Absolutely not, go ahead! :D thats what tutorials are there for, so you can learn and use it :)
-
Yes it would, you would get a nice flaming rectangle :) Also note that with this routing there is no need to erase your sprites unless you don't want them to be on fire
No, I meant wouldn't it be better to do rect(0,63,1,96 ?
-
It sure would be faster, but since you were only doing it once, i went for readability, since this is a tutorial :)
-
Ah ok, that makes sense.
Thanks!
[offtopic]I just had a flashback to Acelgoyobis watching this[/offtopic]
-
No problem :) lol acyglobis? haha whyy
-
The main menu has those effects.
(http://tiwizard.com/downloads/images/pinball.gif)
-
Oh so they do! :D Thats awesome! ^^
-
Builderboy, that's hot (pun very intended). This might go into the title screen of A:P if I can optimize enough space to fit it.
Edit: Success!
(http://www.omnimaga.org/index.php?action=dlattach;topic=5014.0;attach=6259;image)
-
Go for it :D I actually was able to do some neat modifications a while back while i was making a title screen to make a title burn greyscale fire >:D
-
Question: how did you keep the text TAO from smoking away? From the Tao source, it seemed that you just copied the pic to the screen, then ran the code in a more conservative loop that didn't affect the lower portion of the screen. But when I tried it, the image on screen just burned up...
-
Nope, there is 1 extra command in the for loop :) there is an AND {TAO hex data} in there which continually erases the title into the screen, and also provides fuel for the fire to burn
-
This is wonderful! I had no idea it was so simple. Great routine! ;D
-
This is very, very cool :)
-
It is. And it's so simple :D I like it.
-
I like that you did the TAO pic for it. The way I'm currently doing it is, I'm taking the white line below the TAO, and just ORing pixels on up, while anding the title screen back on it. It's nice because there are flames all around it, but especially more from the white areas in the lettering.
-
Woah this is great and small! If I was still coding, this could be useful for a title screen for a Mana Force remake or something, since the original had fire surrounding the text, but in ASCII art animation form.
-
I'm not an axe programmer, but this is still a very cool concept that can also apply to the nspire.
-
NOOOOOOO~
I was tinkering with something like this in Axe a few days ago...
Now, I can't use it... :(
-
Weeeeeeee!
-
I was tinkering with something like this in Axe a few days ago...
Now, I can't use it... :(
Why not?
-
Because now everyone can use it and it just looks like I recycled code. :c
-
Just gotta use it in an original way, or modify it in a way that makes it stand out :)
-
Weeeeeeee!
Reminds me of JetPack...now I know what to do for V6.
And the GUI on fire...w00t
Btw it looks great in full speed mode, with drawinv just before and after dispgraph ;)
-
Darl you know you can get the same effect without the DrawInv by inverting the bit data and changing the AND to an OR right? :D Then it can be even faster ^^
-
Raylin could you post it anyway? Especially if it's slightly different it would be cool anyway. More effects == even greater.
Also awesome Squidgetx :D
This could be useful for some games where some maps occur in an inferno-style area, like Demon Crest's forest stage part 2
-
Weeeeeeee!
Setting things on fire is fun :D
You could make a game out of that!
-
May someone of you please write and upload the code for a program:
I can write [Pic1]->GDB1 or something like that at the beginning! (but always with "->GDB1")
The program should load the pic, show it on the screen and then, please everything there should burn
I mean, the black parts should please burn!
not a special point/line/object, which is always the same!!
It should react on the pic I store as GDB1 and make that burning!
Will that be possible?
-
try redrawing the black parts every frame...
this should make the black parts stay there and flame.
also, remove the one Line command in the program
-
Could you please upload the complete code?
(I don't really understand how everything is working in the code) :-\
-
.Axe
ClrDraw
[FFFFFFFFFFFFFFFF]->Pic1 //This is the black object(sample)
[FEFDFBF7EFDFBF7F]->Str1 //Each Byte here has 7 bits set and 1 bit not set (like FE is 11111110 in binary)
//This is so that we can erase a random pixel, since Axe has no built in way to do that
Repeat getKey(15) //until we press clear
Pt-On(35,35,Pic1) //this is the black object that you want to draw... redraw every frame
For(F,L6,L6+767 //loop through all of the screen pixels except the last 12
{F} and {rand^8+Str1}->{F-12} //take the byte, use AND to erase a single bit from it, and then store it into the byte directly *above* it
End //this makes it so that as the byte rises, each frame a pixel is erased from it
DispGraph
End
modified code on first page to fit your needs ;)
-
Awesome o.o This was short and simple and very easy to port to assembly o.o
-
Thanks :D It's one of my simplest tutorials, but still by far one of the most popular, probably because of the high results/effort ratio XD
-
Okay, here is a Grammer version, so this shows your tutorial here is easily ported to other languages :D
-
Nice! It seems to be using slightly different rules, as the fire isn't as prolific, how are you going about it?
-
I used an RNG that thepenguin77 offered. It appears to be much more evenly distributed...
-
Do you do the flame masking in the same way? In my code each pixel only has a 1/8 chance of death alive each frame
-
Oh, oops, I accidentally forgot to mask the upper 5 bits of the random number I produced XD Now the fire isn't working nicely :( (I have about 3/8 of the columns all white)
-
Hmm could you post the source? I'm no Grammer expert but I will take a look ^^
-
Oh, jee, I finally figured it out. I accidentally some of my code when I went to fix the random number generator last time XD. Sorry about that, here is a better screenie :)
Also, the code to actually do the flames is written in assembly and I just use the AsmPrgm command, but the other parts were in Grammer.
EDIT: Source:
(beware, it is mostly hex)
.0:Return
ClrDraw
ㅠ8800[(0102040810204080
ㅠ86ED[(4C931140930103F4CD0888B612231310F70D20F4060CAF121310FCC9
ㅠ8808[(E5D52AFE87ED5F86230F86230FAE230F0F22FE87E60716885F1AD1E1C9
Repeat getKey(15
AsmPrgm21 ;normally don't ever do this >.>
DispGraph
End
Stop
-
The very beginning is very interesting, as there are some patterns that emerge in the smoke. Perhaps due to patterns in the RNG?
-
yes, most of the RNGs that I have used or seen do have a pattern that you can see when you bring it to the graph screen. I like it on one level, but I don't like it when I need to use it for a game XD
-
That's surely a great tutorial, but I haven't really understood how to burn only one sprite, in a big screen with several others ???
-
That is tough and it depends... Pretty much, as builder said, the basics are this:
-you shift the pixels up one
-you give it a chance to disappear (For example, 1/8 chance)
Depending on the sprite situation, you will probably have to use 2 For( loops to check each pixel of the sprite as well as giving it an upper limit (like the flames can only go as high as another 8 pixels)
-
Right now, I have a sprite moved by the player, and an inanimated block which I want him to burn. How must I do it ?
-
okay, I am not sure if this will work as I am not much of an Axe coder, but maybe try this?
For(B,X,X+7
For(C,Y+1,Y+15
pxl-Test(C,B→A
pxl-Off(C-1,B
If rand^8
pxl-On(C-1,B
End
End
-
pxl-Test returns 0 if the pixel tested is off or 1 if it's on o_O what do you do with this command ?
-
Oops, let me modify that XD:
For(B,X,X+7
For(C,Y+1,Y+15
pxl-Off(C-1,B
If rand^8*pxl-Test(C,B
pxl-On(C-1,B
End
End
-
It doesn't work :/
Here it is the full code I use :44->X-16->Y
Repeat getkey(15)
Pt-On(X,Y,[FFFFFFFFFFFFFFFF
For(B,X,X+7)
For(C,Y+1,Y+15)
Pxl-Off(C-1,B
If rand^8*pxl-Test(C,B)
Pxl-On(C-1,B
End
End
End
DispGraph
End
-
It burns the pixels below the block. You'd have to do this:
44->X-16->Y
Repeat getkey(15)
Pt-On(X,Y,[FFFFFFFFFFFFFFFF
For(B,X,X+7)
For(C,Y-7,Y+7) //I changed this line
Pxl-Off(C-1,B
If rand^8*pxl-Test(C,B)
Pxl-On(C-1,B
End
End
End
DispGraph
End
No guarantee, but I hope it works.
-
it doesn't work anymore >_< but I don't know why, it seems that it would be ok o_O
EDIT : I just found what's wrong :44->X-16->Y
Repeat getkey(15)
Pt-On(X,Y,[FFFFFFFFFFFFFFFF
For(B,X,X+7)
For(C,Y-7,Y+7) //I changed this line
Pxl-Off(B,C-1 <----------------------- Here
If rand^8*pxl-Test(B,C) <---------------- Here
Pxl-On(B,C-1 <------------------------ and Here
End
End
End
DispGraph
End
That's why instead of Grammer, the Axe commands Pxl-xxx give the X as first argument and Y as second xD
-
Yeah, ninja'd again.
-
But, I've had the time to put a +1 at your message XD
-
So did my code work, otherwise?
-
Yes, that's a great code, thanks :thumbsup: and you can make the flame longer by changing the second For loop (and I found that rand^6 is better than rand^8)
-
Yes, that's a great code, thanks ;D(http://www.omnimaga.org/Themes/default/images/gpbp_arrow_up.gif) and you can make the flame longer by changing the second For loop (and I found that rand^6 is better than rand^8)
The number you subtract in the for loop is the height of the flames -1.
This would make the flames 16 pixels high
For(C,Y-15,Y+7)
Changing the modulus at the rand will change the density of the flames. A high number like 8 or 10 will let the flames have more particles than having a small number like 4 or 6.
If rand^10*pxl-Test(B,C) //High density = more particles
...
If rand^4*pxl-Test(B,C) //Low density = less particles
-
Yeah, that's it
-
(sorry for bad english, I'm french :/)
Nice tutorial !
But I didn't really understand this part:
For(F,L6+12,L6+767 //loop through all of the screen pixels except the last 12
{F} and {rand^8+Str1}->{F-12} //take the byte, use AND to erase a single bit from it, and then store it into the byte directly *above* it
End //this makes it so that as the byte rises, each frame a pixel is erased from it
Why "except the last 12" ?
And how works the line 2?
{F} and {rand^8+Str1}->{F-12} //take the byte, use AND to erase a single bit from it, and then store it into the byte directly *above* it
Thanks :)
-
For(F,L6+12,L6+767 //loop through all of the screen pixels except the last 12
{F} and {rand^8+Str1}->{F-12} //take the byte, use AND to erase a single bit from it, and then store it into the byte directly *above* it
End //this makes it so that as the byte rises, each frame a pixel is erased from it
Thie first line loops through all the bytes in L6 (except for the last row, which is the last 12 bytes. We save those so that there's something to "feed" the flames). Since L6 has 768 bytes, we loop from 12 to 767.
If you look at the Str1 sprite, it's essentially diagonal pixels filling up the sprite, and each row/column has exactly one pixel. By using rand^8, we select one row at random, and erase that pixel from the screen. We then shift the entire screen up a row. By adding more pixels or taking them away from the sprite, you can do all sorts of things with the flames - bias them to one direction, make them last much shorter times, etc.
-
Oh ok, I undersand erverything now, thanks :) !
Bye and have a nice day ;)
-
It does not work when I do it... :banghead:
-
What part isn't working, could you be more specific? Remember, this is Axe code. Also, you should introduce yourself codebender :) I'm assuming your the same 'codebender' from TI-BASICDeveloper?
-
When I compile, an error occurs:
EDIT: It stopped. Thank you, though... ???
-
I am confused (sorry for being such a noob). I understand everything before the for loop, but I don't understand how L6 can draw to the screen and how that works. Also, why do you only need 768 bytes for 6144 pixels?
-
Also, why do you only need 768 bytes for 6144 pixels?
Each byte is made up of 8 bits. Since the display is purely monochrome and doesn't support grayscale, you can store one pixel in each bit, and 768*8=6144.