[Add] Primitive special effect system with explosions!!
This commit is contained in:
parent
21deb8709d
commit
80d78756ad
4
.clang_complete
Normal file
4
.clang_complete
Normal file
@ -0,0 +1,4 @@
|
||||
-I /usr/include/SDL/
|
||||
-I /usr/include/freetype2/
|
||||
-I lib/lua/
|
||||
|
BIN
gfx/spfx/exps.png
Normal file
BIN
gfx/spfx/exps.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "SDL.h"
|
||||
#include <SDL.h>
|
||||
|
||||
// Input types.
|
||||
typedef enum { KEYBIND_NULL, KEYBIND_KEYBOARD, KEYBIND_JAXIS, KEYBIND_JBUTTON } KeybindType;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "toolkit.h"
|
||||
#include "pilot.h"
|
||||
#include "sound.h"
|
||||
#include "spfx.h"
|
||||
#include "music.h"
|
||||
|
||||
#define XML_START_ID "Start"
|
||||
@ -150,6 +151,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
// Data loading.
|
||||
factions_load();
|
||||
spfx_load();
|
||||
outfit_load();
|
||||
ships_load();
|
||||
fleet_load();
|
||||
@ -203,6 +205,7 @@ int main(int argc, char** argv) {
|
||||
fleet_free();
|
||||
ships_free();
|
||||
outfit_free();
|
||||
spfx_free(); // Remove the special effects.
|
||||
factions_free();
|
||||
gl_freeFont(&gl_smallFont);
|
||||
|
||||
@ -242,6 +245,7 @@ static void fps_control(void) {
|
||||
// Update the game.
|
||||
static void update_space(void) {
|
||||
weapons_update(dt);
|
||||
spfx_update(dt);
|
||||
pilots_update(dt);
|
||||
}
|
||||
|
||||
@ -254,8 +258,8 @@ static void update_space(void) {
|
||||
// | Back layer weapons.
|
||||
// X
|
||||
// N | NPC ships.
|
||||
// | Normal layer particles (above ships).
|
||||
// | Front layer weapons.
|
||||
// | Normal layer particles (above ships).
|
||||
// X
|
||||
// FG | Player.
|
||||
// | Foreground particles.
|
||||
@ -270,8 +274,10 @@ static void render_space(void) {
|
||||
// N.
|
||||
pilots_render();
|
||||
weapons_render(WEAPON_LAYER_FG);
|
||||
spfx_render(SPFX_LAYER_BACK);
|
||||
// FG.
|
||||
player_render();
|
||||
spfx_render(SPFX_LAYER_FRONT);
|
||||
display_fps(dt);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <string.h>
|
||||
#include "SDL.h"
|
||||
#include <SDL.h>
|
||||
|
||||
#include "toolkit.h"
|
||||
#include "log.h"
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <vorbis/vorbisfile.h>
|
||||
#include "SDL.h"
|
||||
#include <SDL.h>
|
||||
|
||||
#include "lephisto.h"
|
||||
#include "log.h"
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "weapon.h"
|
||||
#include "pilot.h"
|
||||
#include "spfx.h"
|
||||
#include "pause.h"
|
||||
|
||||
// Main thing with pausing is to allow things based on time to
|
||||
@ -22,6 +23,7 @@ void pause(void) {
|
||||
|
||||
pilots_pause();
|
||||
weapons_pause();
|
||||
spfx_pause();
|
||||
|
||||
paused = 1; // We should unpause it.
|
||||
}
|
||||
@ -31,6 +33,7 @@ void unpause(void) {
|
||||
|
||||
pilots_unpause();
|
||||
weapons_unpause();
|
||||
spfx_unpause();
|
||||
|
||||
paused = 0;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <AL/alc.h>
|
||||
#include "SDL.h"
|
||||
#include "SDL_thread.h"
|
||||
#include <SDL.h>
|
||||
#include <SDL_thread.h>
|
||||
|
||||
#include "lephisto.h"
|
||||
#include "log.h"
|
||||
|
221
src/spfx.c
Normal file
221
src/spfx.c
Normal file
@ -0,0 +1,221 @@
|
||||
#include <SDL.h>
|
||||
|
||||
#include "lephisto.h"
|
||||
#include "log.h"
|
||||
#include "pilot.h"
|
||||
#include "physics.h"
|
||||
#include "opengl.h"
|
||||
#include "pause.h"
|
||||
#include "spfx.h"
|
||||
|
||||
#define SPFX_GFX "../gfx/spfx/" // Graphics location.
|
||||
#define SPFX_CHUNK 10 // Chunk to allocate when needed.
|
||||
|
||||
typedef struct SPFX_Base_ {
|
||||
char* name;
|
||||
|
||||
int anim; // Total duration in ms.
|
||||
glTexture* gfx; // Will use each sprite as a frame.
|
||||
} SPFX_Base;
|
||||
|
||||
static SPFX_Base* spfx_effects = NULL;
|
||||
static int spfx_neffects = 0;
|
||||
|
||||
typedef struct SPFX_ {
|
||||
Vec2 pos, vel; // They don't accelerate.
|
||||
|
||||
int lastframe; // Need when pausing.
|
||||
int effect; // Actual effect.
|
||||
unsigned int t; // Start.
|
||||
} SPFX;
|
||||
|
||||
// Front stack is for effects on player.
|
||||
// Back is for everything else.
|
||||
static SPFX* spfx_stack_front = NULL;
|
||||
static int spfx_nstack_front = 0;
|
||||
static int spfx_mstack_front = 0;
|
||||
static SPFX* spfx_stack_back = NULL;
|
||||
static int spfx_nstack_back = 0;
|
||||
static int spfx_mstack_back = 0;
|
||||
|
||||
static int spfx_base_load(char* name, int anim, char* gfx, int sx, int sy);
|
||||
static void spfx_base_free(SPFX_Base* effect);
|
||||
static void spfx_destroy(SPFX* layer, int* nlayer, int spfx);
|
||||
static void spfx_update_layer(SPFX* layer, int* nlayer, const double dt);
|
||||
static void spfx_pause_layer(SPFX* layer, int nlayer);
|
||||
static void spfx_unpause_layer(SPFX* layer, int nlayer);
|
||||
|
||||
// Load the SPFX_Base.
|
||||
static int spfx_base_load(char* name, int anim, char* gfx, int sx, int sy) {
|
||||
SPFX_Base* cur;
|
||||
char buf[PATH_MAX];
|
||||
|
||||
spfx_effects = realloc(spfx_effects, ++spfx_neffects*sizeof(SPFX_Base));
|
||||
cur = &spfx_effects[spfx_neffects-1];
|
||||
|
||||
cur->name = strdup(name);
|
||||
cur->anim = anim;
|
||||
sprintf(buf, SPFX_GFX"%s", gfx);
|
||||
cur->gfx = gl_newSprite(buf, sx, sy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spfx_base_free(SPFX_Base* effect) {
|
||||
if(effect->name) free(effect->name);
|
||||
if(effect->gfx) gl_freeTexture(effect->gfx);
|
||||
}
|
||||
|
||||
// Load/Unload.
|
||||
int spfx_load(void) {
|
||||
spfx_base_load("ExpS", 600, "exps.png", 6, 5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spfx_free(void) {
|
||||
int i;
|
||||
|
||||
// Get rid of all the particles and free the stacks.
|
||||
spfx_clear();
|
||||
if(spfx_stack_front) free(spfx_stack_front);
|
||||
spfx_stack_front = NULL;
|
||||
spfx_mstack_front = 0;
|
||||
if(spfx_stack_back) free(spfx_stack_back);
|
||||
spfx_stack_back = NULL;
|
||||
spfx_mstack_back = 0;
|
||||
|
||||
for(i = 0; i < spfx_neffects; i++)
|
||||
spfx_base_free(&spfx_effects[i]);
|
||||
free(spfx_effects);
|
||||
spfx_effects = NULL;
|
||||
spfx_neffects = 0;
|
||||
}
|
||||
|
||||
void spfx_add(int effect, const Vec2* pos, const Vec2* vel, const int layer) {
|
||||
SPFX* cur_spfx;
|
||||
|
||||
if(layer == SPFX_LAYER_FRONT) {
|
||||
// Front layer.
|
||||
if(spfx_mstack_front < spfx_nstack_front+1) {
|
||||
// We need more memory.
|
||||
spfx_mstack_front += SPFX_CHUNK;
|
||||
spfx_stack_front = realloc(spfx_stack_front, spfx_mstack_front*sizeof(SPFX));
|
||||
}
|
||||
cur_spfx = &spfx_stack_front[spfx_nstack_front];
|
||||
spfx_nstack_front++;
|
||||
}
|
||||
else if(layer == SPFX_LAYER_BACK) {
|
||||
// Back layer.
|
||||
if(spfx_mstack_back < spfx_nstack_back+1) {
|
||||
// Need more memory.
|
||||
spfx_mstack_back += SPFX_CHUNK;
|
||||
spfx_stack_back = realloc(spfx_stack_back, spfx_mstack_back*sizeof(SPFX));
|
||||
}
|
||||
cur_spfx = &spfx_stack_back[spfx_nstack_back];
|
||||
spfx_nstack_back++;
|
||||
}
|
||||
|
||||
cur_spfx->effect = effect;
|
||||
vectcpy(&cur_spfx->pos, pos);
|
||||
vectcpy(&cur_spfx->vel, vel);
|
||||
cur_spfx->t = SDL_GetTicks();
|
||||
}
|
||||
|
||||
void spfx_clear(void) {
|
||||
int i;
|
||||
for(i = spfx_nstack_front-1; i >= 0; i--)
|
||||
spfx_destroy(spfx_stack_front, &spfx_nstack_front, i);
|
||||
|
||||
for(i = spfx_nstack_back-1; i >= 0; i--)
|
||||
spfx_destroy(spfx_stack_back, &spfx_nstack_back, i);
|
||||
}
|
||||
|
||||
static void spfx_destroy(SPFX* layer, int* nlayer, int spfx) {
|
||||
int i;
|
||||
(*nlayer)--;
|
||||
for(i = spfx; i < *nlayer; i++)
|
||||
memcpy(&layer[i], &layer[i+1], sizeof(SPFX));
|
||||
}
|
||||
|
||||
void spfx_update(const double dt) {
|
||||
spfx_update_layer(spfx_stack_front, &spfx_nstack_front, dt);
|
||||
spfx_update_layer(spfx_stack_back, &spfx_nstack_back, dt);
|
||||
}
|
||||
|
||||
static void spfx_update_layer(SPFX* layer, int* nlayer, const double dt) {
|
||||
int i;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
|
||||
for(i = 0; i < *nlayer; i++) {
|
||||
// Time to die!!!
|
||||
if(t > (layer[i].t + spfx_effects[layer[i].effect].anim)) {
|
||||
spfx_destroy(layer, nlayer, i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
// Mkay. Update it now.
|
||||
vect_cadd(&layer[i].pos, dt*VX(layer[i].vel), dt*VY(layer[i].vel));
|
||||
}
|
||||
}
|
||||
|
||||
void spfx_render(const int layer) {
|
||||
SPFX* spfx_stack;
|
||||
int i, spfx_nstack;
|
||||
SPFX_Base* effect;
|
||||
int sx, sy;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
|
||||
// Get the appropriate layer.
|
||||
switch(layer) {
|
||||
case SPFX_LAYER_FRONT:
|
||||
spfx_stack = spfx_stack_front;
|
||||
spfx_nstack = spfx_nstack_front;
|
||||
break;
|
||||
case SPFX_LAYER_BACK:
|
||||
spfx_stack = spfx_stack_back;
|
||||
spfx_nstack = spfx_nstack_back;
|
||||
break;
|
||||
}
|
||||
for(i = 0; i < spfx_nstack; i++) {
|
||||
effect = &spfx_effects[spfx_stack[i].effect];
|
||||
|
||||
sx = (int)effect->gfx->sx;
|
||||
sy = (int)effect->gfx->sy;
|
||||
|
||||
if(!paused) // Don't calculate frame if paused.
|
||||
spfx_stack[i].lastframe = sx * sy
|
||||
* MIN(((double)(t - spfx_stack[i].t)/(double)effect->anim), 1.);
|
||||
|
||||
gl_blitSprite(effect->gfx,
|
||||
VX(spfx_stack[i].pos), VY(spfx_stack[i].pos),
|
||||
spfx_stack[i].lastframe % sx,
|
||||
spfx_stack[i].lastframe / sx,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void spfx_pause(void) {
|
||||
spfx_pause_layer(spfx_stack_front, spfx_nstack_front);
|
||||
spfx_pause_layer(spfx_stack_back, spfx_nstack_back);
|
||||
|
||||
}
|
||||
|
||||
static void spfx_pause_layer(SPFX* layer, int nlayer) {
|
||||
int i;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
for(i = 0; i < nlayer; i++)
|
||||
layer[i].t -= t;
|
||||
}
|
||||
|
||||
void spfx_unpause(void) {
|
||||
spfx_unpause_layer(spfx_stack_front, spfx_nstack_front);
|
||||
spfx_unpause_layer(spfx_stack_back, spfx_nstack_back);
|
||||
}
|
||||
|
||||
static void spfx_unpause_layer(SPFX* layer, int nlayer) {
|
||||
int i;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
for(i = 0; i < nlayer; i++)
|
||||
layer[i].t += t;
|
||||
}
|
||||
|
22
src/spfx.h
Normal file
22
src/spfx.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "physics.h"
|
||||
|
||||
#define SPFX_LAYER_FRONT 0
|
||||
#define SPFX_LAYER_BACK 1
|
||||
|
||||
void spfx_add(const int effect,
|
||||
const Vec2* pos, const Vec2* vel, const int layer);
|
||||
|
||||
// Stack manipulation functions.
|
||||
void spfx_update(const double dt);
|
||||
void spfx_render(const int layer);
|
||||
void spfx_clear(void);
|
||||
|
||||
// Load/free.
|
||||
int spfx_load(void);
|
||||
void spfx_free(void);
|
||||
|
||||
// Pause/Unpause routines.
|
||||
void spfx_pause(void);
|
||||
void spfx_unpause(void);
|
||||
|
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "SDL.h"
|
||||
#include <SDL.h>
|
||||
#include "opengl.h"
|
||||
#include "font.h"
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "pilot.h"
|
||||
#include "collision.h"
|
||||
#include "player.h"
|
||||
#include "spfx.h"
|
||||
#include "weapon.h"
|
||||
|
||||
#define weapon_isSmart(w) (w->think)
|
||||
@ -236,8 +237,11 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
|
||||
// Good shot.
|
||||
static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer) {
|
||||
// Someone should let the ai know it's been attacked.
|
||||
if(!pilot_isPlayer(p))
|
||||
if(!pilot_isPlayer(p)) {
|
||||
ai_attacked(p, w->parent);
|
||||
spfx_add(0, &w->solid->pos, &p->solid->vel, SPFX_LAYER_BACK);
|
||||
} else
|
||||
spfx_add(0, &w->solid->pos, &p->solid->vel, SPFX_LAYER_FRONT);
|
||||
if(w->parent == PLAYER_ID)
|
||||
// Make hostile to player.
|
||||
pilot_setFlag(p, PILOT_HOSTILE);
|
||||
|
Loading…
Reference in New Issue
Block a user