Magic Emitters: Motion, gravity, & spawning

Hearts float up, sparkles float down (and sometimes spawn).
Everyone gets random initial movement.
This commit is contained in:
Bill Kendrick 2024-12-26 20:29:44 -08:00
parent 51e28bdfb0
commit e1b9f29c2f

View file

@ -34,8 +34,8 @@
#include "SDL_mixer.h" #include "SDL_mixer.h"
#include "SDL2_rotozoom.h" #include "SDL2_rotozoom.h"
#define EMITTER_QUEUE_SIZE 32 #define EMITTER_QUEUE_SIZE 64
#define EMITTER_QUEUE_SIZE_SCALE 4 #define EMITTER_QUEUE_SIZE_SCALE 8
#define EMITTER_DRAW_THRESHOLD 16 #define EMITTER_DRAW_THRESHOLD 16
@ -74,6 +74,30 @@ int emitter_rotate[NUM_EMITTERS] = {
180, 180,
}; };
/* Scale of emitter xm/ym speeds */
#define EMITTER_SPEED 64
/* Max random-direction speed for each emitter type */
int emitter_speed[NUM_EMITTERS] = {
16,
8,
4,
};
/* Gravity (if any) of the emitter */
int emitter_gravity[NUM_EMITTERS] = {
-2,
2,
0,
};
/* Whether emitter duplicates itself */
int emitter_duplicate[NUM_EMITTERS] = {
0,
1,
0,
};
/* Our globals: */ /* Our globals: */
static Mix_Chunk *emitter_snds[NUM_EMITTERS]; static Mix_Chunk *emitter_snds[NUM_EMITTERS];
@ -82,6 +106,7 @@ Uint8 emitter_r, emitter_g, emitter_b;
int emitter_max_trail_length; int emitter_max_trail_length;
int emitter_cur_trail_length; int emitter_cur_trail_length;
int emitter_queue_x[EMITTER_QUEUE_SIZE], emitter_queue_y[EMITTER_QUEUE_SIZE]; int emitter_queue_x[EMITTER_QUEUE_SIZE], emitter_queue_y[EMITTER_QUEUE_SIZE];
int emitter_queue_xm[EMITTER_QUEUE_SIZE], emitter_queue_ym[EMITTER_QUEUE_SIZE];
SDL_Surface * * emitter_images[NUM_EMITTERS][EMITTER_QUEUE_SIZE]; SDL_Surface * * emitter_images[NUM_EMITTERS][EMITTER_QUEUE_SIZE];
/* Function prototypes: */ /* Function prototypes: */
@ -264,28 +289,58 @@ void emitter_drag(magic_api *api, int which, SDL_Surface *canvas,
SDL_BlitSurface(last, NULL, canvas, NULL); SDL_BlitSurface(last, NULL, canvas, NULL);
/* Move all of the objects */
for (i = 0; i < emitter_cur_trail_length; i++)
{
emitter_queue_x[i] += emitter_queue_xm[i] / EMITTER_SPEED;
emitter_queue_y[i] += emitter_queue_ym[i] / EMITTER_SPEED;
emitter_queue_ym[i] += emitter_gravity[which];
if (emitter_duplicate[which] && (rand() % 16) == 0)
{
int d;
d = (rand() % (i + 1));
emitter_queue_x[d] = emitter_queue_x[i];
emitter_queue_y[d] = emitter_queue_y[i];
emitter_queue_xm[d] = emitter_queue_xm[i];
emitter_queue_ym[d] = emitter_queue_ym[i] * 2;
}
}
/* If we've moved a significant distance, emit another object */
if (abs(x - last_x) > EMITTER_DRAW_THRESHOLD || abs(y - last_y) > EMITTER_DRAW_THRESHOLD) if (abs(x - last_x) > EMITTER_DRAW_THRESHOLD || abs(y - last_y) > EMITTER_DRAW_THRESHOLD)
{ {
if (emitter_cur_trail_length < emitter_max_trail_length - 1) if (emitter_cur_trail_length < emitter_max_trail_length - 1)
{ {
/* Trail not full, add another */
emitter_cur_trail_length++; emitter_cur_trail_length++;
} }
else else
{ {
/* Trail is full, rotate queue */
for (i = 0; i < emitter_cur_trail_length; i++) for (i = 0; i < emitter_cur_trail_length; i++)
{ {
emitter_queue_x[i] = emitter_queue_x[i + 1]; emitter_queue_x[i] = emitter_queue_x[i + 1];
emitter_queue_y[i] = emitter_queue_y[i + 1]; emitter_queue_y[i] = emitter_queue_y[i + 1];
emitter_queue_xm[i] = emitter_queue_xm[i + 1];
emitter_queue_ym[i] = emitter_queue_ym[i + 1];
} }
} }
/* Add the new object */
emitter_queue_x[emitter_cur_trail_length] = x; emitter_queue_x[emitter_cur_trail_length] = x;
emitter_queue_y[emitter_cur_trail_length] = y; emitter_queue_y[emitter_cur_trail_length] = y;
emitter_queue_xm[emitter_cur_trail_length] = (rand() % emitter_speed[which] * 2) - emitter_speed[which];
emitter_queue_ym[emitter_cur_trail_length] = (rand() % emitter_speed[which] * 2) - emitter_speed[which];
last_x = x; last_x = x;
last_y = y; last_y = y;
} }
/* Draw all of them */
for (i = 0; i < emitter_cur_trail_length + 1; i++) for (i = 0; i < emitter_cur_trail_length + 1; i++)
{ {
img = (emitter_cur_trail_length - i); img = (emitter_cur_trail_length - i);
@ -384,6 +439,8 @@ void emitter_click(magic_api *api, int which, int mode ATTRIBUTE_UNUSED,
{ {
emitter_queue_x[0] = x; emitter_queue_x[0] = x;
emitter_queue_y[0] = y; emitter_queue_y[0] = y;
emitter_queue_xm[0] = (rand() % emitter_speed[which] * 2) - emitter_speed[which];
emitter_queue_ym[0] = (rand() % emitter_speed[which] * 2) - emitter_speed[which];
emitter_cur_trail_length = 0; emitter_cur_trail_length = 0;
last_x = -100; last_x = -100;
last_y = -100; last_y = -100;