summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorArnold <[email protected]>2023-05-26 12:09:26 -0400
committerGitHub <[email protected]>2023-05-26 12:09:26 -0400
commite81e2ea117a67364786184aa328bc6e2b543e38f (patch)
treeb3b10f3aef85f321f958b22bebc96ceff98cc833
parent030ae6b44015005401589eb9b3b055cb10bd7285 (diff)
downloadRodeoKit-e81e2ea117a67364786184aa328bc6e2b543e38f.tar.gz
RodeoKit-e81e2ea117a67364786184aa328bc6e2b543e38f.zip
implemented 2d collision system
-rw-r--r--CMakeLists.txt1
-rw-r--r--include/rodeo/collision.h29
-rw-r--r--include/rodeo/collision_t.h11
-rw-r--r--src/collision/rodeo_collision.c126
4 files changed, 161 insertions, 6 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6cd566d..cccc4de 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,6 +11,7 @@ add_library(${PROJECT_NAME}
"src/log/rodeo_log.c"
"src/input/rodeo_input.c"
"src/audio/rodeo_audio.c"
+ "src/collision/rodeo_collision.c"
)
set_property(TARGET RodeoKit PROPERTY C_STANDARD 99)
diff --git a/include/rodeo/collision.h b/include/rodeo/collision.h
index 9e7b856..277b780 100644
--- a/include/rodeo/collision.h
+++ b/include/rodeo/collision.h
@@ -7,7 +7,9 @@ rodeo_collision_2d_world_t
rodeo_collision_2d_world_create(void);
void
-rodeo_collision_2d_world_destroy(void);
+rodeo_collision_2d_world_destroy(
+ rodeo_collision_2d_world_t *world
+);
cvec_collision_2d_world_item_value*
rodeo_collision_2d_world_item_create(
@@ -17,19 +19,34 @@ rodeo_collision_2d_world_item_create(
void
rodeo_collision_2d_world_item_destroy(
- rodeo_collision_2d_world_t *world,
cvec_collision_2d_world_item_value* cvec_value
);
void
+rodeo_collision_2d_world_item_destroy_by_id(
+ world_id id
+);
+
+rodeo_collision_2d_world_item_t*
+rodeo_collision_2d_world_item_get_by_id(
+ world_id id
+);
+
+void
rodeo_collision_2d_world_compare_self(
- rodeo_collision_2d_world_t *world
- // resolve function?
+ rodeo_collision_2d_world_t *world,
+ void (*resolve)(
+ rodeo_collision_2d_world_item_t *a,
+ rodeo_collision_2d_world_item_t *b
+ )
);
void
rodeo_collision_2d_world_compare_other(
rodeo_collision_2d_world_t *world_a,
- rodeo_collision_2d_world_t *world_b
- // resolve function?
+ rodeo_collision_2d_world_t *world_b,
+ void (*resolve)(
+ rodeo_collision_2d_world_item_t *a,
+ rodeo_collision_2d_world_item_t *b
+ )
);
diff --git a/include/rodeo/collision_t.h b/include/rodeo/collision_t.h
index e51386c..e75d243 100644
--- a/include/rodeo/collision_t.h
+++ b/include/rodeo/collision_t.h
@@ -4,10 +4,19 @@
#include <stdint.h>
#include <stdbool.h>
+struct cvec_collision_2d_world_item;
+
typedef
struct
{
uint32_t id;
+ struct cvec_collision_2d_world_item *world;
+} world_id;
+
+typedef
+struct
+{
+ world_id id;
float x;
float y;
float dx;
@@ -18,6 +27,7 @@ struct
}
rodeo_collision_2d_world_item_t;
+
int rodeo_collision_2d_item_cmp(
const rodeo_collision_2d_world_item_t* a,
const rodeo_collision_2d_world_item_t* b
@@ -28,4 +38,5 @@ int rodeo_collision_2d_item_cmp(
#define i_type cvec_collision_2d_world_item
#include "stc/cvec.h"
+
typedef cvec_collision_2d_world_item rodeo_collision_2d_world_t;
diff --git a/src/collision/rodeo_collision.c b/src/collision/rodeo_collision.c
new file mode 100644
index 0000000..e4791bf
--- /dev/null
+++ b/src/collision/rodeo_collision.c
@@ -0,0 +1,126 @@
+#include "rodeo/collision.h"
+#include "rodeo/collision_t.h"
+#include <stdio.h>
+
+bool detect_collision(
+ const rodeo_collision_2d_world_item_t *a,
+ const rodeo_collision_2d_world_item_t *b
+)
+{
+ return !(a->x+a->dx > b->x+b->dx + b->width ||
+ b->x+b->dx > a->x+a->dx + a->width ||
+ a->y+a->dy > b->y+b->dy + b->height ||
+ b->y+b->dy > a->y+a->dy + a->height);
+}
+
+rodeo_collision_2d_world_t
+rodeo_collision_2d_world_create(void)
+{
+ return cvec_collision_2d_world_item_init();
+}
+
+void
+rodeo_collision_2d_world_destroy(
+rodeo_collision_2d_world_t *world
+)
+{
+ cvec_collision_2d_world_item_drop(world);
+}
+
+cvec_collision_2d_world_item_value*
+rodeo_collision_2d_world_item_create(
+ rodeo_collision_2d_world_t *world,
+ rodeo_collision_2d_world_item_t item_params
+)
+{
+ static uint32_t next_id = 0;
+ item_params.id.id = next_id++;
+ item_params.id.world = world;
+ cvec_collision_2d_world_item_value* new_item = cvec_collision_2d_world_item_push(world, item_params);
+
+ return new_item;
+}
+
+void
+rodeo_collision_2d_world_item_destroy(
+ cvec_collision_2d_world_item_value* cvec_value
+)
+{
+
+ cvec_collision_2d_world_item_value temp = *cvec_collision_2d_world_item_back(cvec_value->id.world);
+ *cvec_collision_2d_world_item_back(cvec_value->id.world) = *cvec_value;
+ *cvec_value = temp;
+ cvec_collision_2d_world_item_pop(cvec_value->id.world);
+}
+
+void
+rodeo_collision_2d_world_item_destroy_by_id(
+ world_id id
+)
+{
+ rodeo_collision_2d_world_item_t* item = rodeo_collision_2d_world_item_get_by_id(id);
+ rodeo_collision_2d_world_item_destroy(item);
+}
+
+rodeo_collision_2d_world_item_t*
+rodeo_collision_2d_world_item_get_by_id(
+ world_id id
+)
+{
+ c_foreach(i, cvec_collision_2d_world_item, *id.world) {
+ if (i.ref->id.id == id.id) {
+ return i.ref;
+ }
+ }
+ return NULL;
+}
+
+void
+rodeo_collision_2d_world_compare_self(
+ rodeo_collision_2d_world_t *world,
+ void (*resolve)(
+ rodeo_collision_2d_world_item_t *a,
+ rodeo_collision_2d_world_item_t *b
+ )
+)
+{
+ c_foreach(i, cvec_collision_2d_world_item, *world) {
+ c_foreach(j, cvec_collision_2d_world_item, cvec_collision_2d_world_item_advance(i, 1), cvec_collision_2d_world_item_end(world)) {
+ if (detect_collision(i.ref, j.ref)) {
+ resolve(i.ref, j.ref);
+ }
+ }
+ }
+}
+
+void
+rodeo_collision_2d_world_compare_other(
+ rodeo_collision_2d_world_t *world_a,
+ rodeo_collision_2d_world_t *world_b,
+ void (*resolve)(
+ rodeo_collision_2d_world_item_t *a,
+ rodeo_collision_2d_world_item_t *b
+ )
+)
+{
+ c_foreach(i, cvec_collision_2d_world_item, *world_a) {
+ c_foreach(j, cvec_collision_2d_world_item, *world_b) {
+ if (detect_collision(i.ref, j.ref)) {
+ resolve(i.ref, j.ref);
+ }
+ }
+ }
+}
+
+
+int rodeo_collision_2d_item_cmp(
+ const rodeo_collision_2d_world_item_t* a,
+ const rodeo_collision_2d_world_item_t* b
+)
+{
+ if (a->id.id == b->id.id) {
+ return 0;
+ } else {
+ return a->id.id > b->id.id ? 1 : -1;
+ }
+}