Implemented a simple particle engine.
This commit is contained in:
parent
753448efdb
commit
93c0623fe4
|
@ -43,7 +43,7 @@ if (NOT WIN32)
|
|||
)
|
||||
endif (NOT WIN32)
|
||||
|
||||
set(CMAKE_C_FLAGS_DEBUG "-DDEBUG")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG")
|
||||
|
||||
# PROGRAMS:
|
||||
add_executable(breakhack
|
||||
|
@ -70,6 +70,7 @@ add_executable(breakhack
|
|||
src/item_builder
|
||||
src/pointer
|
||||
src/gui_button
|
||||
src/particle_engine
|
||||
)
|
||||
|
||||
target_link_libraries(breakhack
|
||||
|
|
|
@ -465,6 +465,9 @@ gui_destroy(Gui *gui)
|
|||
for (int i = 0; i < LOG_LINES_COUNT; ++i)
|
||||
texture_destroy(gui->log_lines[i]);
|
||||
|
||||
for (int i = 0; i < LABEL_COUNT; ++i)
|
||||
sprite_destroy(gui->labels[i]);
|
||||
|
||||
ht_destroy_custom(gui->textures, (void (*)(void*)) &texture_destroy);
|
||||
free(gui);
|
||||
}
|
||||
|
|
17
src/main.c
17
src/main.c
|
@ -18,6 +18,7 @@
|
|||
#include "item_builder.h"
|
||||
#include "pointer.h"
|
||||
#include "gui_button.h"
|
||||
#include "particle_engine.h"
|
||||
|
||||
static SDL_Window *gWindow = NULL;
|
||||
static SDL_Renderer *gRenderer = NULL;
|
||||
|
@ -27,6 +28,7 @@ static RoomMatrix *gRoomMatrix = NULL;
|
|||
static Gui *gGui = NULL;
|
||||
static Pointer *gPointer = NULL;
|
||||
static unsigned int cLevel = 1;
|
||||
static float deltaTime = 1.0;
|
||||
static double renderScale = 1.0;
|
||||
static GameState gGameState;
|
||||
static Camera gCamera;
|
||||
|
@ -135,6 +137,7 @@ bool init(void)
|
|||
gGui = gui_create(gRenderer);
|
||||
item_builder_init(gRenderer);
|
||||
gPointer = pointer_create(gRenderer);
|
||||
particle_engine_init();
|
||||
}
|
||||
|
||||
gGameState = PLAYING;
|
||||
|
@ -213,6 +216,7 @@ run_game(void)
|
|||
roommatrix_build_lightmap(gRoomMatrix);
|
||||
|
||||
gui_update_player_stats(gGui, gPlayer, gMap, gRenderer);
|
||||
particle_engine_update(deltaTime);
|
||||
|
||||
if (gPlayer->steps >= gPlayer->stats.speed) {
|
||||
player_reset_steps(gPlayer);
|
||||
|
@ -224,6 +228,7 @@ run_game(void)
|
|||
|
||||
SDL_RenderSetViewport(gRenderer, &gameViewport);
|
||||
map_render(gMap, &gCamera);
|
||||
particle_engine_render(&gCamera);
|
||||
player_render(gPlayer, &gCamera);
|
||||
roommatrix_render_lightmap(gRoomMatrix, &gCamera);
|
||||
|
||||
|
@ -249,6 +254,9 @@ run_game(void)
|
|||
static
|
||||
void run(void)
|
||||
{
|
||||
static int oldTime = 0;
|
||||
static int currentTime = 0;
|
||||
|
||||
bool quit = false;
|
||||
Timer* fpsTimer = timer_create();
|
||||
|
||||
|
@ -281,6 +289,14 @@ void run(void)
|
|||
if (ticks < 1000/60)
|
||||
SDL_Delay((1000/60) - ticks);
|
||||
timer_stop(fpsTimer);
|
||||
|
||||
if (currentTime == 0)
|
||||
currentTime = SDL_GetTicks();
|
||||
else {
|
||||
oldTime = currentTime;
|
||||
currentTime = SDL_GetTicks();
|
||||
deltaTime = (currentTime - oldTime) / 1000.0;
|
||||
}
|
||||
}
|
||||
|
||||
timer_destroy(fpsTimer);
|
||||
|
@ -295,6 +311,7 @@ void close(void)
|
|||
gui_destroy(gGui);
|
||||
pointer_destroy(gPointer);
|
||||
item_builder_close();
|
||||
particle_engine_close();
|
||||
SDL_DestroyRenderer(gRenderer);
|
||||
SDL_DestroyWindow(gWindow);
|
||||
gWindow = NULL;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "item.h"
|
||||
#include "item_builder.h"
|
||||
#include "map.h"
|
||||
#include "particle_engine.h"
|
||||
|
||||
static void
|
||||
monster_load_texts(Monster *m, SDL_Renderer *renderer)
|
||||
|
@ -231,6 +232,11 @@ monster_hit(Monster *monster, unsigned int dmg)
|
|||
if (dmg > 0) {
|
||||
monster->hitText->active = true;
|
||||
monster->missText->active = false;
|
||||
Position p = monster->sprite->pos;
|
||||
p.x += 8;
|
||||
p.y += 8;
|
||||
Dimension d = { 8, 8 };
|
||||
particle_engine_bloodspray(p, d);
|
||||
} else {
|
||||
monster->missText->active = true;
|
||||
monster->hitText->active = false;
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
#include <stdlib.h>
|
||||
#include "particle_engine.h"
|
||||
#include "linkedlist.h"
|
||||
#include "util.h"
|
||||
#include "defines.h"
|
||||
#include "vector2d.h"
|
||||
|
||||
typedef struct Particle_t {
|
||||
Position pos;
|
||||
Vector2d velocity;
|
||||
Dimension dim;
|
||||
unsigned int movetime;
|
||||
unsigned int lifetime;
|
||||
SDL_Color color;
|
||||
} Particle;
|
||||
|
||||
typedef struct Engine_t {
|
||||
LinkedList *particles;
|
||||
} Engine;
|
||||
|
||||
static Engine *engine = NULL;
|
||||
|
||||
static void
|
||||
check_engine(void)
|
||||
{
|
||||
if (!engine)
|
||||
fatal("Particle engine not initiated");
|
||||
}
|
||||
|
||||
void
|
||||
particle_engine_init(void)
|
||||
{
|
||||
if (engine != NULL)
|
||||
fatal("Engine already initiated");
|
||||
|
||||
engine = ec_malloc(sizeof(Engine));
|
||||
engine->particles = linkedlist_create();
|
||||
}
|
||||
|
||||
void
|
||||
particle_engine_bloodspray(Position pos, Dimension dim)
|
||||
{
|
||||
int x, y, xv, yv, w, h, i;
|
||||
unsigned int mt, lt;
|
||||
Particle *p;
|
||||
|
||||
check_engine();
|
||||
|
||||
for (i = 0; i < 15; ++i) {
|
||||
x = (rand() % dim.width) + pos.x;
|
||||
y = (rand() % dim.height) + pos.y;
|
||||
|
||||
xv = (rand() % 200) - 100;
|
||||
yv = (rand() % 200) - 100;
|
||||
|
||||
mt = (rand() % 10) + 10;
|
||||
lt = (rand() % 120) + 60;
|
||||
|
||||
w = (rand() % 3) + 2;
|
||||
h = (rand() % 3) + 2;
|
||||
|
||||
p = ec_malloc(sizeof(Particle));
|
||||
p->pos = (Position) { x, y };
|
||||
p->velocity = (Vector2d) { xv, yv };
|
||||
p->movetime = mt;
|
||||
p->lifetime = lt;
|
||||
p->dim = (Dimension) { w, h };
|
||||
p->color = (SDL_Color) { 255, 0, 0, 255 };
|
||||
linkedlist_append(&engine->particles, p);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
move_particle(Particle *particle, float deltaTime)
|
||||
{
|
||||
if (!particle->movetime)
|
||||
return;
|
||||
|
||||
particle->pos.x += particle->velocity.x * deltaTime;
|
||||
particle->pos.y += particle->velocity.y * deltaTime;
|
||||
}
|
||||
|
||||
void
|
||||
particle_engine_update(float deltaTime)
|
||||
{
|
||||
check_engine();
|
||||
LinkedList *current, *last;
|
||||
Particle *particle;
|
||||
|
||||
current = engine->particles;
|
||||
last = NULL;
|
||||
|
||||
while (current) {
|
||||
particle = current->data;
|
||||
|
||||
if (particle->movetime)
|
||||
particle->movetime--;
|
||||
|
||||
if (particle->lifetime > 0) {
|
||||
particle->lifetime--;
|
||||
move_particle(current->data, deltaTime);
|
||||
last = current;
|
||||
current = current->next;
|
||||
} else {
|
||||
if (!last) {
|
||||
engine->particles = current->next;
|
||||
free(current->data);
|
||||
free(current);
|
||||
current = engine->particles;
|
||||
} else {
|
||||
last->next = current->next;
|
||||
free(current->data);
|
||||
free(current);
|
||||
current = last->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
render_particle(Particle *p, Camera *cam)
|
||||
{
|
||||
Position pos = camera_to_camera_position(cam, &p->pos);
|
||||
SDL_Rect box = { pos.x, pos.y, p->dim.width, p->dim.height };
|
||||
SDL_SetRenderDrawColor(cam->renderer,
|
||||
p->color.r,
|
||||
p->color.b,
|
||||
p->color.g,
|
||||
p->color.a);
|
||||
SDL_RenderFillRect(cam->renderer, &box);
|
||||
}
|
||||
|
||||
void
|
||||
particle_engine_render(Camera *cam)
|
||||
{
|
||||
check_engine();
|
||||
LinkedList *particles = engine->particles;
|
||||
|
||||
while (particles) {
|
||||
render_particle(particles->data, cam);
|
||||
particles = particles->next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
particle_engine_close(void)
|
||||
{
|
||||
check_engine();
|
||||
|
||||
while (engine->particles)
|
||||
free(linkedlist_pop(&engine->particles));
|
||||
|
||||
free(engine);
|
||||
engine = NULL;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef PARTICLE_ENGINE_H_
|
||||
#define PARTICLE_ENGINE_H_
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include "position.h"
|
||||
#include "dimension.h"
|
||||
#include "camera.h"
|
||||
|
||||
void
|
||||
particle_engine_init(void);
|
||||
|
||||
void
|
||||
particle_engine_bloodspray(Position, Dimension);
|
||||
|
||||
void
|
||||
particle_engine_update(float deltatime);
|
||||
|
||||
void
|
||||
particle_engine_render(Camera*);
|
||||
|
||||
void
|
||||
particle_engine_close(void);
|
||||
|
||||
#endif // PARTICLE_ENGINE_H_
|
|
@ -7,6 +7,7 @@
|
|||
#include "util.h"
|
||||
#include "gui.h"
|
||||
#include "item.h"
|
||||
#include "particle_engine.h"
|
||||
|
||||
#define ENGINEER_STATS { 12, 12, 5, 7, 2, 1, 1 }
|
||||
#define MAGE_STATS { 12, 12, 5, 7, 2, 1, 1 }
|
||||
|
@ -309,6 +310,10 @@ player_hit(Player *p, unsigned int dmg)
|
|||
if (dmg > 0) {
|
||||
p->hitText->active = true;
|
||||
p->missText->active = false;
|
||||
Position pos = p->sprite->pos;
|
||||
pos.x += 8;
|
||||
pos.y += 8;
|
||||
particle_engine_bloodspray(pos, (Dimension) { 8, 8 });
|
||||
} else {
|
||||
p->missText->active = true;
|
||||
p->hitText->active = false;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <stdlib.h>
|
||||
#include "pointer.h"
|
||||
#include "util.h"
|
||||
#include "particle_engine.h"
|
||||
|
||||
Pointer *
|
||||
pointer_create(SDL_Renderer *renderer)
|
||||
|
@ -25,7 +26,7 @@ pointer_handle_event(Pointer *p, SDL_Event *event)
|
|||
if (event->type == SDL_MOUSEMOTION) {
|
||||
p->sprite->pos.x = event->motion.x;
|
||||
p->sprite->pos.y = event->motion.y;
|
||||
debug("Pointer pos: %dx%d", p->sprite->pos.x, p->sprite->pos.y);
|
||||
// debug("Pointer pos: %dx%d", p->sprite->pos.x, p->sprite->pos.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef VECTOR2D_H_
|
||||
#define VECTOR2D_H_
|
||||
|
||||
typedef struct Vector2d_t {
|
||||
float x;
|
||||
float y;
|
||||
} Vector2d;
|
||||
|
||||
#endif // VECTOR2D_H_
|
Loading…
Reference in New Issue