Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » A Simple Particle Explosion

This thread is locked; no one can reply to it. rss feed Print
 1   2 
A Simple Particle Explosion
yohosuff
Member #10,022
July 2008
avatar

I've been searching like a bloodhound through forum archives for some working source code of a particle explosion. Does anyone think they could point me towards a tutorial or just provide some code directly? I'll keep searching but I think human's understand what I'm looking for better than the search algorithm does. :)

blargmob
Member #8,356
February 2007
avatar

Create a particle struct or class containing x, y, vel, dir, color. Array or vector containing the amount of particles you want in the explosion.\ When explosion happens For each particle give particle random dir give particle a vel After explosion happens For each particle update particles position (calculate xS and yS from vel and dir)

---
"No amount of prayer would have produced the computers you use to spread your nonsense." Arthur Kalliokoski

amber
Member #6,783
January 2006
avatar

Blargmob's basic approach is good, though I'd recommend that you dispense with the array and just simply maintain a big list of "graphical objects" in your program, all of which can have individual velocity, acceleration, lifetimes, and so on.

In my recent projects, having every sprite/etc. on the screen be considered a "Particle" and treated the same has simplified rendering and updating significantly, at the expense of slightly more memory and CPU usage (that is not an issue at all on a PC built this century).

SiegeLord
Member #7,827
October 2006
avatar

If you use the hardware accelerated approach, blargmob's method is better, since you don't have to switch textures between each particle, leading to enormous speed benefits.

You could look at the sources of these demos I guess.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

amber
Member #6,783
January 2006
avatar

That's assuming all of your particles in the system are the same texture, and your "big list" isn't optimized to provide similar benefits.

In my case, neither of those assumptions are true, but I agree, mileage may vary. :)

yohosuff
Member #10,022
July 2008
avatar

I appreciate your replies, but I have to admit that I don't know what you are all talking about.

I tried the sources of the demos you provided a link to, but they are all way to complex for me to understand with my limited knowledge of this particular aspect of programming.

Is it difficult to write the code for a simple explosion? I learn best from working code. I heard that there are simple examples somewhere, but I haven't been able to locate them.

Thanks again for all your help so far. :)

Onewing
Member #6,152
August 2005
avatar

Quote:

I learn best from working code.

I think you'd learn even better by trying. Write some thoughts down on how you think it would be done and then try to code it yourself. When you get stuck at this point, then come here and show your work.

------------
Solo-Games.org | My Tech Blog: The Digital Helm

blargmob
Member #8,356
February 2007
avatar

Quote:

I have to admit that I don't know what you are all talking about.

First learn what we say. Then try to code it.

---
"No amount of prayer would have produced the computers you use to spread your nonsense." Arthur Kalliokoski

yohosuff
Member #10,022
July 2008
avatar

Thanks for the advice, but I'm still going to go with learning by example.

I believe the phrase goes something like, "Why reinvent the wheel?" :)

I'd really appreciate it if someone would post something that I could learn from. I want to learn. I want to.........LEARN!!! :p

Schyfis
Member #9,752
May 2008
avatar

Try something like this.

1//define a particle structure
2typedef struct particle {
3 //we'll need an x and y position for each particle
4 double x, y;
5 //the particles are going to be moving,
6 //so here's x velocity and y velocity
7 double xvel, yvel;
8 //let's also keep track of the old
9 //x and y positions so we can draw the
10 //particles as lines instead of just points
11 double oldx, oldy;
12};
13//create a vector of pointers to particles (kind of like an array)
14vector<particle*> particles;
15/*
16explode: a function to make a particle explosion
17parameters:
18 x: the horizontal position of the explosion's center
19 y: the vertical position of the explosion's center
20 num: number of particles in the explosion
21*/
22void explode(double x, double y, int num) {
23 //initializes the random number generator with the current time as the seed
24 srand(time(0));
25 //for loop to create num particles
26 for(int i=0; i<num; i++) {
27 //allocates memory for our new particle
28 //note that this is a pointer to a particle, not the particle itself
29 particle* p = (particle*)malloc(sizeof(particle));
30 //set x, y, oldx, and oldy to the center of the explosion
31 (*p).x = (*p).oldx = x;
32 (*p).y = (*p).oldy = y;
33 //set xvel and yvel to random numbers between -4 and 4
34 (*p).xvel=rand()%4-rand()%4;
35 (*p).yvel=rand()%4-rand()%4;
36 //add the particle pointer to our vector
37 particles.push_back(p);
38 }
39}
40/*
41stepParticles: a function to step the particles through one frame of movement
42parameters: none
43notes:
44 -call this function every time you go through your game loop.
45 -remember that particles is a vector of pointers, so you have to dereference them!
46*/
47void stepParticles(){
48 //iterate through our vector of particle pointers
49 //particles.size() gets the total number of elements in the vector
50 for(int i=0; i<particles.size(); i++){
51 //set oldx and oldy to the current values of x and y
52 (*particles.at(i)).oldx=(*particles.at(i)).x;
53 (*particles.at(i)).oldy=(*particles.at(i)).y;
54 //now we add xvel and yvel to x and y so the particles move
55 (*particles.at(i)).x+=(*particles.at(i)).xvel;
56 (*particles.at(i)).y+=(*particles.at(i)).yvel;
57 }
58}
59/*
60drawParticles: a function to draw the particles on the screen
61parameters: none
62notes: call this function every time you go through your game loop.
63*/
64void drawParticles() {
65 //iterate through the vector like last time
66 for(int i=0; i<particles.size(); i++){
67 //you'll have to have a BITMAP named buffer for this to work,
68 //assuming you're double buffering
69 line(buffer,
70 (*particles.at(i)).x, (*particles.at(i)).y,
71 (*particles.at(i)).oldx, (*particles.at(i)).oldy,
72 makecol(255,127,0));
73 //it spans many lines to make it easier to read
74 }
75}
76//an example of your game loop
77while(!key[KEY_ESC]){
78 clear_keybuf();
79 if(key[KEY_SPACE]){
80 srand(time(0));
81 //make explosion at random place on the screen
82 explode(rand()%SCREEN_W, rand()%SCREEN_H, 20);
83 }
84 clear(buffer);
85 stepParticles();
86 drawParticles();
87 blit(buffer,screen,0,0,0,0,buffer->w,buffer->h);
88 rest(20);
89}

I didn't test it, but that should get you started. If you want images attached to your particles, you may not need oldx or oldy, they're just for drawing the line.
Correct me if I'm missing anything, but I think this code needs to include allegro.h, ctime, math.h, and vector.
Let us know how the learning goes!

________________________________________________________________________________________________________
[freedwill.us]
[unTied Games]

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

And a good way to learn is by doing... Blargmob gave you an algorithm you could implement in your very first reply. Translating it to code shouldn't be too difficult if you just try. Here's an example based on his algorithm (untested, uncompiled) :

1//
2 
3#include <vector>
4#include <cmath>
5#include <allegro.h>
6 
7 
8class Particle {
9 public :
10 int x,y;// display position
11 float fx,fy;// accurate position
12 float fvx,fvy;// component velocities
13 float fspeed;// absolute speed
14 float direction;// angle of travel in radians
15 int color;
16 unsigned int num_updates_allowed;
17 unsigned int updates_left;
18
19 Particle() : x(0) , y(0) , fx(0.0f) , fy(0.0f) ,
20 fspeed(0.0f) , direction(0.0f) , color(makecol(0,0,0)) , num_updates_allowed(0) {}
21
22 void SetPersistence(unsigned int num_updates) {
23 num_updates_allowed = num_updates;
24 updates_left = num_updates_allowed;
25 }
26
27 void SetColor(int newcolor) {color = newcolor;}
28
29 void SetPos(float xpos , float ypos) {
30 fx = xpos;
31 fy = ypos;
32 x = (int)fx;
33 y = (int)fy;
34 }
35
36 void SetMovement(float speed , float angle_radians) {
37 if (speed < 0.0f) {speed = -speed;}
38 fspeed = speed;
39 direction = angle_radians;
40 fvx = fspeed*cos(angle_radians);
41 fvy = fspeed*sin(angle_radians);
42 }
43
44 unsigned int UpdatePos() {
45 if (updates_left) {
46 fx += fvx;
47 fy += fvy;
48 x = (int)fx;
49 y = (int)fy;
50 --updates_left;
51 }
52 return updates_left;
53 }
54
55 void Draw(BITMAP* bmp) {
56 putpixel(bmp , x , y , color);
57 }
58};
59 
60class Explosion {
61 public :
62 std::vector<Particle*> particles;
63 unsigned int particle_count;
64
65 Explosion(unsigned int num_particles , int ex , int ey) {
66 Particle* p = NULL;
67 float basespeed = 5.0f;
68 float pspeed = 0.0f;
69 float angle = 0.0f;
70 particle_count = 0;
71 for (unsigned int i = 0 ; i < num_particles ; ++i) {
72 p = new Particle;
73 if (p) {
74 p->SetPos((float)ex + 0.5f , (float)ey + 0.5f);
75 pspeed = basespeed + (float)((rand() % 5) - 2);
76 angle = ((float)(rand() % 3600))/10.0f;
77 angle = angle*(M_PI/180.0f)
78 p->SetMovement(pspeed , angle);
79
80 p->SetPersistence(125 + rand()%50);
81 p->SetColor(makecol(128 + rand()%128 , 128 + rand()%128 , 64));
82
83 particles.pushback(p);
84 ++particle_count;
85 }
86 }
87 }
88
89 ~Explosion() {
90 std::vector<Particle*>::iterator it;
91 for (it = particles.begin() ; it != particles.end() ; ) {
92 if (*it) {delete (*it);}
93 }
94 particles.clear();
95 }
96
97 unsigned int UpdateExplosion() {
98 std::vector<Particle*>::iterator it;
99 for (it = particles.begin() ; it != particles.end() ; ) {
100 if ((*it)->UpdatePos()) {// check the return value of Particle::UPdatePos to
101 // see if there are any updates left for this particle
102 ++it;
103 } else {
104 delete *it;
105 it = particles.erase(it);
106 --particle_count;
107 }
108 }
109 return particle_count;
110 }
111
112 void Draw(BITMAP* bmp) {
113 std::vector<Particle*>::iterator it;
114 for (it = particles.begin() ; it != particles.end() ; ) {
115 (*it)->Draw(bmp);
116 }
117 }
118
119 private :
120
121};
122 
123 
124//

And a quick example of usage :

1unsigned int num_particles = 100;
2Explosion* exp = new Explosion(num_particles , SCREEN_W/2 , SCREEN_H/2);
3if (!exp) {return 0;}
4 
5clear_keybuf();readkey();
6 
7bool stop = false;
8while (!stop) {
9 clear_to_color(buffer , makecol(0,0,0));
10 exp->Draw(buffer);
11 blit(buffer , screen , 0 , 0 , 0 , 0 buffer->w , buffer->h);
12 if (exp->Update() == 0) {
13 stop = true;
14 } else {
15 rest(25);
16 }
17}
18 
19delete exp;
20clear_keybuf();readkey();
21 
22return 0;

Timorg
Member #2,028
March 2002

Schyfis said:

(*p).x = (*p).oldx = x;

perhaps going p->x = p->oldx = x; would actually be clearer.

Edit:
Memory allocations are quite expensive, so you could use an array. If the array is full and you need to insert a new particle, you can over-write the oldest.

Particles lend themselves to C++, with a pixel class, but I did my example in C. You could easily roll this up into a class, but I am in a C mood. (The code, binary and code::blocks project is attached.)

1#include <allegro.h>
2 
3typedef struct
4{
5 float x, y;
6 float dx, dy;
7 unsigned int alive;
8}PARTICLE;
9 
10void particle_init (PARTICLE *p);
11PARTICLE particle_create(float _x, float _y);
12void particle_update(PARTICLE *p);
13void particle_render(PARTICLE p, BITMAP *buffer);
14 
15void manager_init (PARTICLE *particle, int count);
16void manager_update(PARTICLE *particle, int count);
17void manager_render(PARTICLE *particle, int count, BITMAP *buffer);
18void manager_insert(PARTICLE *particle, int count, PARTICLE p);
19 
20 
21volatile int logic_counter = 0;
22void logic_counter_handler()
23{
24 logic_counter++;
25}
26END_OF_FUNCTION(logic_counter_handler)
27 
28 
29 
30#define MAX_PARTICLES 256
31 
32int main(int argc, char **argv)
33{
34 PARTICLE particle[MAX_PARTICLES];
35 PARTICLE p;
36 int quitting = 0;
37 
38 if (allegro_init() != 0)
39 {
40 allegro_message("Unable to initilize allegro. :(");
41 return 1;
42 }
43 
44 if (install_keyboard() != 0)
45 {
46 allegro_message("Unable to install keyboard driver. :(");
47 return 1;
48 }
49 
50 if (install_mouse() == -1)
51 {
52 allegro_message("Unable to install mouse driver. :(");
53 return 1;
54 }
55 
56 if (install_timer() != 0)
57 {
58 allegro_message("Unable to install timer driver. :(");
59 return 1;
60 }
61 
62 LOCK_VARIABLE(logic_counter);
63 LOCK_FUNCTION(logic_counter_handler);
64 
65 set_color_depth(32);
66 if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0) != 0)
67 {
68 allegro_message("Unable to set gfx mode. :(\n(%s)", allegro_error);
69 return 1;
70 }
71 
72 BITMAP *buffer = create_bitmap(SCREEN_W, SCREEN_H);
73 if (buffer == NULL)
74 {
75 allegro_message("Unable to create back buffer. :(");
76 return 1;
77 }
78 
79 show_mouse(screen);
80 
81 manager_init(particle, MAX_PARTICLES);
82 
83 if (install_int(logic_counter_handler, 33) != 0)
84 {
85 allegro_message("Unable to install logic timer. :(");
86 quitting = 1;
87 }
88 logic_counter = 0;
89 while(!quitting)
90 {
91 
92 if (logic_counter > 0)
93 {
94 if (mouse_b & 1)
95 {
96 p = particle_create(mouse_x, mouse_y);
97 manager_insert(particle, MAX_PARTICLES, p);
98 }
99 manager_update(particle, MAX_PARTICLES);
100 logic_counter--;
101 }
102 
103 
104 clear_bitmap(buffer);
105 manager_render(particle, MAX_PARTICLES, buffer);
106 
107 
108 scare_mouse();
109 blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
110 unscare_mouse();
111 
112 if (key[KEY_ESC])
113 {
114 quitting = 1;
115 }
116 }
117 
118 
119 show_mouse(NULL);
120 destroy_bitmap(buffer);
121 
122 return 0;
123}
124END_OF_MAIN()
125 
126void particle_init(PARTICLE *p)
127{
128 p->x = 0;
129 p->y = 0;
130 p->dx = 0;
131 p->dy = 0;
132 p->alive = 0;
133}
134 
135PARTICLE particle_create(float _x, float _y)
136{
137 PARTICLE p;
138 p.x = _x;
139 p.y = _y;
140 p.dx = ((float)((rand() % 101) - 50)) / 10;
141 p.dy = ((float)((rand() % 101) - 50)) / 10;
142 p.alive = 255;
143 return p;
144}
145 
146void particle_update(PARTICLE *p)
147{
148 if (p->alive > 0)
149 {
150 p->dy += .1;
151 p->x += p->dx;
152 p->y += p->dy;
153 p->alive--;
154 }
155}
156 
157void particle_render(PARTICLE p, BITMAP *buffer)
158{
159 if (p.alive > 0)
160 {
161 putpixel(buffer, p.x, p.y, makecol(p.alive, p.alive, p.alive));
162 }
163}
164 
165void manager_init(PARTICLE *particle, int count)
166{
167 int c;
168 for (c = 0; c < count; c++)
169 {
170 particle_init(&particle[c]);
171 }
172}
173 
174void manager_update(PARTICLE *particle, int count)
175{
176 int c;
177 for (c = 0; c < count; c++)
178 {
179 particle_update(&particle[c]);
180 }
181}
182 
183void manager_render(PARTICLE *particle, int count, BITMAP *buffer)
184{
185 int c;
186 for (c = 0; c < count; c++)
187 {
188 particle_render(particle[c], buffer);
189 }
190}
191 
192void manager_insert(PARTICLE *particle, int count, PARTICLE p)
193{
194 int c;
195 int oldest = 0;
196 for (c = 0; c < count; c++)
197 {
198 if (particle[c].alive == 0)
199 {
200 particle[c] = p;
201 return;
202 }
203 if (particle[c].alive < particle[oldest].alive)
204 oldest = c;
205 }
206 particle[oldest] = p;
207}

____________________________________________________________________________________________
"c is much better than c++ if you don't need OOP simply because it's smaller and requires less load time." - alethiophile
OMG my sides are hurting from laughing so hard... :D

Neil Walker
Member #210
April 2000
avatar

Schyfis said:

malloc(sizeof(particle));

Why use malloc when you're using c++, why use doubles? you don't seem to have the ability to end the life of a particle, or group particles together as distinct units, or reuse the memory for new particles.

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Schyfis
Member #9,752
May 2008
avatar

Quote:

Why use malloc when you're using c++, why use doubles? you don't seem to have the ability to end the life of a particle, or group particles together as distinct units, or reuse the memory for new particles.

Because it's a simple example, I didn't include anything for deleting particles, but you could easily give each particle a lifetime and do something like this:

1//a function to remove particles that have died
2void removeDeadParticles() {
3 //set up a vector of particles that are still alive
4 vector<particle*> alive;
5 for(int i=0; i<particles.size();i++){
6 //decrement each particle's life
7 (*particles.at(i)).life--;
8 if((*particles.at(i)).life<=0){
9 //if the particle is dead, free the memory
10 free(particles.at(i));
11 }else{
12 //if the particle is still alive, put it in the alive vector
13 alive.push_back(particles.at(i));
14 }
15 }
16 //change the contents of vector particles to the contents of vector alive
17 particles.assign(alive.begin(),alive.end());
18}

What would you recommend for my example other than malloc? I'm still working with my first project that uses structures, so I'm still quite new to the various uses of malloc, new, free, and delete. You should be able to malloc or new a structure, right?
As for the doubles, feel free to use floats. That would take up less memory, right?

________________________________________________________________________________________________________
[freedwill.us]
[unTied Games]

Timorg
Member #2,028
March 2002

The thing is new and delete are part of C++, that is memory allocation and freeing are part of the language, when in C (malloc and free), they are provided by the system library.

When you use new it calls that class constructor if there is one, and delete calls the destructor. If new for some reason can't allocate the memory, the default action is to throw an exception, where malloc just returns a NULL pointer.

You can use malloc to allocate an area in memory for a struct, but you can't really use it to create a class on the heap.

(AFAIK you can use malloc, then manually call the constructor, then manually call the destructor before freeing it, but you are really asking for trouble if you go down that path.)

Edit:
and please for the love of whatever deity you follow, use -> to dereference your pointers

____________________________________________________________________________________________
"c is much better than c++ if you don't need OOP simply because it's smaller and requires less load time." - alethiophile
OMG my sides are hurting from laughing so hard... :D

Idealius
Member #1,619
November 2001

I think there's a little miscommunication in this thread... as to the skill of the original poster (Op).

Not taking in account sound and keyboard input.. this is how I (self taught game dev) learned:

1-Create a program that draws a rectangle.
2-Then try to change it's color.
3-Then try to change it's color rapidly with a loop.
4-Once you've got that then try to move it.
5-Then try to make it bounce off the edges of the screen.
6-Then fiddle around with random ideas like "What if I make it change color everytime it bounces?"
7-Then make an array of rectangles so you have 20 or more bouncing off the screen.
8-That should give you enough working knowledge to write your own particle explosion, starfields, etc.

I'm curious, which step is the OP at? :p

Neil Black
Member #7,867
October 2006
avatar

What is the specific task the OP is having trouble with?

Idealius: your example fails. It took me less than a day to learn how to bounce rectangles around on the screen. Ok, I used circles instead of rectangles, but it's the same thing. A particle explosion is much different.

Idealius
Member #1,619
November 2001

You're probably right as I learned on Qbasic long before Allegro ever existed..
And computers were less mainstream back then, too.

I guess I'm just wondering if the OP has a basic understanding of arrays. Once you have that a particle explosion should be easy to create.

Of course creating, tracking, and deleting it as an object is another layer of complexity..

kudos to circles =)

Neil Black
Member #7,867
October 2006
avatar

I learned in QBASIC too!

My biggest problem with a particle explosion was always the random direction thing. I could make things go up, down, left, right, or at a 45 degree angle to any of those, but it wasn't until just recently that I learned how to make things go in any direction. I still have trouble with particle effects, though.

Idealius
Member #1,619
November 2001

Oh cool. I guess I just assumed you started on Allegro.

Yeah I think I bridged that gap by using float's instead of int's for the particle's coords and deltas. And of course knowing how to make a random value that can be negative OR positive helped, too..

Then there are more complex ways to do it, by giving the particles' starting points based on the shape of a circle so when they travel the same basic circular plot is maintained.. like fireworks.

..using vectors (not the class)..etc. Ah memories. Thanks..

yohosuff
Member #10,022
July 2008
avatar

I began working with 2d environments a little over 2 weeks ago. Before that, it was all text, learning for and while loops, arrays, etc, etc, all the basics. I'm still not that familiar with implementing physics for objects in 2d. I made a bouncy ball program but I'm pretty sure I cheated.

I'd say I'm probably around step 5.

I'm going to try out some of the examples posted here, although I can already tell that it may be difficult for me to understand. I'll post back later with how I did.

Thanks for all the replies! :) I woke up this morning and was like, "Whoa! 17 replies!!" :D

----------

I can't seem to figure out how to add a post right after my last post, so I'm just going to use the "minus bar" and edit this post. :)

Schyfis, I tried out your code and I threw together a working program below (oh yeah, I don't know how to put it in a cool code window). I'm a little confused about it though, mainly this line:

particle* p = (particle*)malloc(sizeof(particle));

This allocates memory for each particle in the vector, am I right? But, why is it necessary to do this? Is it because particle p has been declared as a pointer? And if so, why not just directly declare p as not a pointer? Full working program below:

#include <allegro.h>
#include <ctime>
#include <math.h>
#include <vector>

using namespace std;

BITMAP* buffer;

//define a particle structure
typedef struct particle {
//we'll need an x and y position for each particle
int x, y;
//the particles are going to be moving,
//so here's x velocity and y velocity
int xvel, yvel;
//let's also keep track of the old
//x and y positions so we can draw the
//particles as lines instead of just points
int oldx, oldy;
};
//create a vector of pointers to particles (kind of like an array)
vector <particle*> particles;
/*
explode: a function to make a particle explosion
parameters:
x: the horizontal position of the explosion's center
y: the vertical position of the explosion's center
num: number of particles in the explosion
*/
void explode(int x, int y, int num) {
//initializes the random number generator with the current time as the seed
srand(time(0));
//for loop to create num particles
for(int i=0; i<num; i++) {
//allocates memory for our new particle
//note that this is a pointer to a particle, not the particle itself
particle* p = (particle*)malloc(sizeof(particle));
//set x, y, oldx, and oldy to the center of the explosion
(*p).x = (*p).oldx = x;
(*p).y = (*p).oldy = y;
//set xvel and yvel to random numbers between -4 and 4
(*p).xvel=rand()%64-rand()%64;
(*p).yvel=rand()%64-rand()%64;
// (*p).xvel=-1;
// (*p).yvel=0;
//add the particle pointer to our vector
particles.push_back(p);
}
}
/*
stepParticles: a function to step the particles through one frame of movement
parameters: none
notes:
-call this function every time you go through your game loop.
-remember that particles is a vector of pointers, so you have to dereference them!
*/
void stepParticles(){
//iterate through our vector of particle pointers
//particles.size() gets the total number of elements in the vector
for(int i=0; i<particles.size(); i++){
//set oldx and oldy to the current values of x and y
(*particles.at(i)).oldx=(*particles.at(i)).x;
(*particles.at(i)).oldy=(*particles.at(i)).y;
//now we add xvel and yvel to x and y so the particles move
(*particles.at(i)).x+=(*particles.at(i)).xvel;
(*particles.at(i)).y+=(*particles.at(i)).yvel;
}
}
/*
drawParticles: a function to draw the particles on the screen
parameters: none
notes: call this function every time you go through your game loop.
*/
void drawParticles() {
//iterate through the vector like last time
for(int i=0; i<particles.size(); i++){
//you'll have to have a BITMAP named buffer for this to work,
//assuming you're double buffering
line(buffer,
(*particles.at(i)).x, (*particles.at(i)).y,
(*particles.at(i)).oldx, (*particles.at(i)).oldy,
makecol(255,127,0));
//it spans many lines to make it easier to read
}
}

int main(){
allegro_init();
install_keyboard();
set_gfx_mode(GFX_AUTODETECT_WINDOWED,640,480,0,0);
set_color_depth(32);

buffer = create_bitmap(640,480);

// particle.x = 200;
// particle.y = 200;
// particle.xvel = 5;
// particle.yvel = 5;

//an example of your game loop
while(!key[KEY_ESC]){
clear_keybuf();
if(key[KEY_SPACE]){

srand(time(0));
//make explosion at random place on the screen
//explode(rand()%SCREEN_W, rand()%SCREEN_H, 5);
explode(300,240,100);
}

clear(buffer);
stepParticles();
drawParticles();
blit(buffer,screen,0,0,0,0,buffer->w,buffer->h);


rest(20);

}
}
END_OF_MAIN();

someone972
Member #7,719
August 2006
avatar

To put code into the codebox just put [code] and [/code] around it.

The particles are declared as a pointer so they can be allocated on the heap(correct me if I'm wrong). This way they can be deleted. The stack is what items are declared on if you don't allocate memory, and it is hard to delete them off of it. The stack will also go out of scope. Ex:

int* return_stack(void)
{
   int number = 10; //declare on stack, valid now
   return &number; //return address of number
};

int main()
{
   int* p_num;
   p_num = return_stack(); //number goes out of scope,
   printf("%d",*p_num); //causing p_num to be some random value
}

The heap is where memory that was allocated by malloc or new resides. It doesn't go out of scope Ex:

int* return_stack(void)
{
   int* number = (int*)malloc(sizeof(int)); //declare on heap, valid now
   *number = 10;
   return number; //return address pointed to by number
};

int main()
{
   int* p_num;
   p_num = return_stack(); //number doesn't go out of scope,
   printf("%d",*p_num); //causing it to stay 10
   //deallocate it (forgot the code)
}

Always be sure to deallocate memory or there will be a memory leak.

______________________________________
As long as it remains classified how long it took me to make I'll be deemed a computer game genius. - William Labbett
Theory is when you know something, but it doesn't work. Practice is when something works, but you don't know why. Programmers combine theory and practice: Nothing works and they don't know why. -Unknown
I have recklessly set in motion a chain of events with the potential to so-drastically change the path of my life that I can only find it to be beautifully frightening.

yohosuff
Member #10,022
July 2008
avatar

Thanks someone972, for showing me how to do the code thing. :)

By the way, what's a memory leak?

I'll play around with the particles for a while a post back if I run into more trouble with it. Thanks for all the help everyone! :D

Trezker
Member #1,739
December 2001
avatar

Memory leak occurs when allocated memory is not freed when you're done with it.
Example relevant is when you keep creating more particles but never free any, then the old particles stay in memory, and when you have reused the the old pointers to point to the new particles you have no way to access the old particles, they have leaked out of your control.

Onewing
Member #6,152
August 2005
avatar

Quote:

By the way, what's a memory leak?

Whenever you allocate memory, either using malloc (plain C) or new (C++), you are putting your hands around a bit of memory that can't be used for anything else. It is good practice to deallocate anything you allocate, either using free (plain C) or delete (C++). Most OS (that is, I believe it is the OS that does this), deallocates memory on the program's exit. However, it's still good practice to do it yourself, and if you are allocating memory for things that only exist for a moment in your program, you are wasting memory and this can cause the entire computer to run out.

------------
Solo-Games.org | My Tech Blog: The Digital Helm

 1   2 


Go to: