Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Special Effects

This thread is locked; no one can reply to it. rss feed Print
Special Effects
Michael Jensen
Member #2,870
October 2002
avatar

Maybe these are really general questions but I'd really like to know how to make FUN special effects in games.

For a while I took a bitmap that looked like a pointy star with yellow filling on the inside and red filling on the outside and rendered different randomly angled rotations each frame for x number of frames to make an explosion, that looked ok.

I've tried particles that shoot off every which way from a specific point for explosions, but I've also seen cooler ones...

A good example is in the game Overgod (in the depot under action I think -- if you play this game, I recomend you turn off the sound) the graphics arn't anything exciting, but the expolosions and special effects look like they belong in a 3D game (and it's quite captivating)... how do you do that?

Are their articles on making cool particle effects/explosion rendering engines etc?

Fladimir da Gorf
Member #1,565
October 2001
avatar

The explosions aren't usually rendered. But you could use the fire effect I use in the OL demo to create an explosion, too. Using explosion sprites would give better speed but less variation.

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

Elverion
Member #6,239
September 2005
avatar

I've made pretty decent looking fire and smoke effects before with sprites. I'll attach a screenshot of it (although it looks pretty bad when it's not animated...it looks very cool when it is, though).

All I did was have each particle raise up at between 85 and 95 degrees, with slightly random speed, slightly random colorization between yellow/red/orange, and would scale larger and become more transparent as it became "older". Once it's alpha became <= 0, it would be destroyed. As the particles were drawn, they would use the blender mode "addition" so that the flames seemed to combine with each other, rather than be drawn over top of each other.

Smoke was dome in a similar way, only it would spread out a lot more, and not be colorized.

--
SolarStrike Software - MicroMacro home - Automation software.

Ceagon Xylas
Member #5,495
February 2005
avatar

Anyone have stuff on like nice flashy glowy things other than fire?

Elverion
Member #6,239
September 2005
avatar

I've done all sorts of flashy-glowy stuff using pretty similar methods, such as "magic glitter" effects, explosions, object motion blur, lights, so on so on. Just minor tweeks here and there can make many different effects that way I mentioned earlier.

From google, I found what looks like a pretty promising particle tutorial.
http://awiki.tomasu.org/bin/view/Main/AllegroParticles

And from NeHe:
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=19

--
SolarStrike Software - MicroMacro home - Automation software.

Ceagon Xylas
Member #5,495
February 2005
avatar

Here's my flame-thrower and napalm 'engine.'
{"name":"image21ah.gif","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/4\/14d6ad50fd536d14bafc8ef5632e1b86.gif","w":484,"h":272,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/4\/14d6ad50fd536d14bafc8ef5632e1b86"}image21ah.gif image39tk.gif image46sf.gif
Yeah, that's two bears...So lay off. My code looks like this [hopefully you'll be able to understand what's happening.]

1const int MAX_FIRE=1024;
2int fire_counter=0;
3 
4 
5class fire{
6public:
7 float x,y,velX,velY; //obvious what these do
8 short life; //life of the fire 'particle'
9 bool visible; //weather or not it's visible
10 
11 void deploy(short x1,short y1,float velX1,float velY1);
12 void update();
13}fire[MAX_FIRE];
14 
15void fire::deploy(short x1,short y1,float velX1,float velY1) {
16 x=x1; y=y1; velX=velX1; velY=velY1;
17 life=200+roll(55); visible=true;
18 //roll here simply returns a random number from 1-55.
19
20 fire_counter++;
21 if(fire_counter>=MAX_FIRE-1)
22 fire_counter=0;
23};
24 
25void fire::update() {
26 if(visible && life>0) {
27 life--;
28
29 //my roll() function returns int, not float
30 //so I have to make sure it knows to use a float
31 if(velX<-0.01) velX+=(float)roll(50)/1000;
32 else if(velX>0.01) velX-=(float)roll(50)/1000;
33 else velX=0;
34 if(velY<-0.7) velY+=0.03;
35 else velY+=0.008;
36 x+=velX;
37 y+=velY;
38
39 drawing_mode(DRAW_MODE_TRANS,NULL,NULL,NULL);
40 for(short i=1; i<5; i++) {
41 //not sure if this is a very smart algorithm, but it seems to make it pretty ^_^
42 set_trans_blender(0,0,0,life/2+life/2/5%i);
43 circlefill(buffer,x,y,i+life/51,makecol(255,life,0));
44 }
45 solid_mode();
46 }
47};
48 
49/*Where you call your key input*/
50float angle=4.353; //set this to whatever you want in radiants
51if(key[KEY_SPACE]) {
52 fire[fire_counter].deploy(320,240,3*cos(angle),3*sin(angle));
53}

So tell me what all I did wrong there. =] I'm known for amassing errors.

Elverion
Member #6,239
September 2005
avatar

I think if you just use addition as your blending mode, it would look rather nice. Addition blending is just like it sounds...it "adds" the colors instead of just blitting over top of them. You should probably also begin with an alpha of, say 0.75. I'm not sure how to do this in allegro, though, sorry.

--
SolarStrike Software - MicroMacro home - Automation software.

Fladimir da Gorf
Member #1,565
October 2001
avatar

If you want to use software graphics, downloading FBlend would be a good start. Though you won't be able to both rotate (and/or stretch) and blend the sprites.

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

Ceagon Xylas
Member #5,495
February 2005
avatar

Oh wow, the add_blender was ALLLOOTTT better! Thanks much Elverion! I'm leaning towards the top right in this image.
{"name":"image95cs.gif","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/2\/02337cd6bf280fd19cb415572af2d3f6.gif","w":518,"h":255,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/2\/02337cd6bf280fd19cb415572af2d3f6"}image95cs.gif

for(short i=1; i<5; i++) {
  set_add_blender(0,0,0,life/8+life/2/5%i);
  circlefill(buffer,x,y,i+life/51,makecol(255,life,life/4+life/2/5%i));
                                            //this is the red writing on the pictures
}

Okay I'll look into that Fladimir. =]

Marcello
Member #1,860
January 2002
avatar

It'd also help if you used sprites with some texture instead of circles. You'll basically get the benefit of lots of little sprites without actually having them.

Marcello

kentl
Member #2,905
November 2002

Ceagon Xylas: You should make a game in which you play the role of a dragon who are out to burn some towns. Fighting crossbow soldiers, archers, knights, catapults and other medieval stuff.

Ceagon Xylas
Member #5,495
February 2005
avatar

Thanks for the idea, I'll most likely do that now =] Specially if I can find someone willing to do the dragon art ^_^

Quote:

It'd also help if you used sprites with some texture instead of circles. You'll basically get the benefit of lots of little sprites without actually having them.

I'm afraid I don't understand the last part of what you're saying here.

Krzysztof Kluczek
Member #4,191
January 2004
avatar

Quote:

It'd also help if you used sprites with some texture instead of circles.

Rotating these sprites properly also can help a lot (of course anti-aliasing is probably a must here). In Painkiller it worked really well. :)

Elverion
Member #6,239
September 2005
avatar

Yep. You've definantly made some improvement! It looks very nice now. As for the "It'd also help if you used sprites with some texture instead of circles. You'll basically get the benefit of lots of little sprites without actually having them.", he is suggesting that you make a better sprite, simply put. Look at the example I included in that zip file I attached in an earlier post. In your case, you might want it to be more yellowish in the sprite itself.

I suggest GIMP ( www.gimp.org ) for doing any sort of texturing or making sprites like this.

--
SolarStrike Software - MicroMacro home - Automation software.

Ceagon Xylas
Member #5,495
February 2005
avatar

Okay, I like this idea -- but not for the fire. So I may use it for my smoke 'engine' instead. It's taking alot more CPU though. =/

[edit]
Oh, and after I thought about it... Heat rises.
So instead of velY+=0.008 I'm using velY-=(float)roll(250)/10000

Elverion
Member #6,239
September 2005
avatar

Yep. If you just use a better effect with fewer particles, maybe you can get it to work great. But, I think what you have right now is good enough. It looks like fire at least.

Might I be able to get your full source on this?

--
SolarStrike Software - MicroMacro home - Automation software.

Ceagon Xylas
Member #5,495
February 2005
avatar

Yeah, most all of it is right up there ^

1int roll(short sides) {
2 static bool seeded;
3 int val;
4 if(!seeded) seeded=true;
5 val = rand() % (100000);
6 val = (val % sides);
7 return val;
8};
9 
10BITMAP *buffer;
11const int MAX_FIRE=1024;
12int fire_counter=0;
13 
14 
15class fire{
16public:
17 float x,y,velX,velY; //obvious what these do
18 short life; //life of the fire 'particle'
19 bool visible; //weather or not it's visible
20 
21 void deploy(short x1,short y1,float velX1,float velY1);
22 void update();
23}fire[MAX_FIRE];
24 
25void fire::deploy(short x1,short y1,float velX1,float velY1) {
26 x=x1; y=y1; velX=velX1; velY=velY1;
27 life=200+roll(55); visible=true;
28
29 fire_counter++;
30 if(fire_counter>=MAX_FIRE-1)
31 fire_counter=0;
32};
33 
34void fire::update() {
35 if(visible && life>0) {
36 life--;
37 if(velX<-0.01) velX+=(float)roll(50)/1000;
38 else if(velX>0.01) velX-=(float)roll(50)/1000;
39 else velX=0;
40 if(velY<-3.7) velY=-3.7; else velY-=(float)roll(250)/100000;
41 //call for collision detection here if you need it.
42 x+=velX;
43 y+=velY;
44
45 drawing_mode(DRAW_MODE_TRANS,NULL,NULL,NULL);
46 for(short i=1; i<5; i++) {
47 set_add_blender(0,0,0,life/8+life/2/5%i);
48 circlefill(buffer,x,y,i+life/51,makecol(255,life/1.25,life/4+life/2/5%i));
49 }
50 solid_mode();
51 }
52};
53 
54main() {
55 float angle=4.353; //set this to whatever you want in radiants
56 while(!game_over) {
57 if(mouse_b&1)
58 fire[fire_counter].deploy(mouse_x,mouse_y,3*cos(angle),3*sin(angle));
59 
60 for(short i=0; i<MAX_FIRE; i++) fire<i>.update();
61 blit(buffer);
62 }
63}

Michael Jensen
Member #2,870
October 2002
avatar

Quote:

If you want to use software graphics,

Actually I was planning on learning managed Direct 3D for my next game (probably a 2D game in VB.NET, overhead view with zooming) thanks for the articles and code posted... I'll try to read it -- starting with nehe #19.

edit: hmmm.. I couldn't find a binary to download of nehe's example (didn't feel like downloading opengl sdk or whatever it is that you need, and the source and trying to compile it...) -- but from his explination, it's not that impressive, the only thing he has incorporated that I never tried to was particles with images bound to them instead of colors...

I suppose that could be kind of cool... maybe if it also supported alpha blending like someone else said in this thread, each particle could be bitmapped/rotated/blended.

edit: CX I like the topleft implimentation of the fire.

Ceagon Xylas
Member #5,495
February 2005
avatar

Feel free to use my fire if you want. I'll ask that you be nice and give me credit, but I wont hold it to you. Freesource. A further note on that is you may need to output 3 'particles' at once instead of just one. Something like

if(mouse_b&1)
  for(short i=0; i<3; i++)
    fire[fire_counter].deploy(...);

And here's the Binary for lesson 19. The NeHe binaries are found at the bottom of the page in the VC++ zip:

Quote:

  • DOWNLOAD Visual C++ Code For This Lesson.

Michael Jensen
Member #2,870
October 2002
avatar

Ahh, it just said code and I didn't realize... Yeah just what I thought, blending sprites instead of dots... cool.

Go to: