mirror of
https://github.com/zoriya/Gamacon.git
synced 2026-06-06 05:05:36 +00:00
collisions are working
This commit is contained in:
@@ -7,17 +7,28 @@
|
||||
|
||||
#include "engine.h"
|
||||
#include <stdbool.h>
|
||||
#include "vertex_component.h"
|
||||
|
||||
static inline bool gc_vector2_is_ccw(gc_vector2 a, gc_vector2 b,gc_vector2 c)
|
||||
{
|
||||
return ((c.y - a.y) * (b.x - a.x) > (b.y - a.x) * (c.x - a.x));
|
||||
}
|
||||
//! @brief Checks if a point q is on the segment pr
|
||||
bool is_on_segment(gc_vector2 p, gc_vector2 q, gc_vector2 r);
|
||||
|
||||
static inline bool gc_vector2_is_intersect(gc_vector2 a, gc_vector2 b, \
|
||||
gc_vector2 c, gc_vector2 d)
|
||||
{
|
||||
return (gc_vector2_is_ccw(a, c, d) != gc_vector2_is_ccw(b, c, d) &&\
|
||||
gc_vector2_is_ccw(a, b, c) != gc_vector2_is_ccw(a, b, d));
|
||||
}
|
||||
//! @brief Checks how the points are beetween each others
|
||||
//! @return 0 if points are colinear
|
||||
//! @return 1 if points are clockwise
|
||||
//! @return 2 if points are counterclockwise
|
||||
int orientation(gc_vector2 p, gc_vector2 q, gc_vector2 r);
|
||||
|
||||
bool map_manage_click(gc_engine *engine, int id, gc_vector2 pos);
|
||||
//! @brief Checks if segments p1q1 and p2q2 intersects
|
||||
bool gc_vector2_do_intersect(gc_vector2 p1, gc_vector2 q1, gc_vector2 p2, gc_vector2 q2);
|
||||
|
||||
//! @brief Checks if a point is in a polygon
|
||||
//! @note The segment created to check is [10000, p.x] so beware when checking with large coordinates
|
||||
//! @param polygon An array of points creating the polygon
|
||||
//! @note Beware of the order of the points the polygon ABCD is different from ABDC
|
||||
//! @param n The number of points of the polygon
|
||||
//! @note you can't set n less than 3
|
||||
//! @param p Position of the point to check
|
||||
bool is_point_in_polygon(gc_vector2 *polygon, int n, gc_vector2 p);
|
||||
|
||||
bool map_manage_click(gc_engine *engine, int id, gc_vector2 pos);
|
||||
bool is_pos_in_tile(gc_vector2 pos, struct tile *tile);
|
||||
@@ -46,7 +46,7 @@ void sfml_play_music(void *music);
|
||||
void sfml_stop_music(gc_engine *engine);
|
||||
void sfml_resize(gc_engine *engine, gc_vector2 size);
|
||||
gc_vector2 sfml_get_screen_size(gc_engine *engine);
|
||||
gc_vector2 sfml_engine_get_cursor_pos(gc_engine *engine);
|
||||
gc_vector2i sfml_engine_get_cursor_pos(gc_engine *engine);
|
||||
|
||||
void entities_update_to_cam(gc_scene *scene, \
|
||||
struct sfml_renderer_system *renderer, struct camerafollow_system *cam);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#define ANGLE_X 45
|
||||
#define ANGLE_Y 35
|
||||
#define INF 10000
|
||||
|
||||
gc_vector2 get_tile_coords_to_pixels(float x, float y, float z)
|
||||
{
|
||||
@@ -24,55 +25,78 @@ gc_vector2 get_tile_coords_to_pixels(float x, float y, float z)
|
||||
};
|
||||
}
|
||||
|
||||
int nb_intersection_between_vectors(gc_vector2 x1, gc_vector2 x2, gc_vector2 polygon[4])
|
||||
bool is_on_segment(gc_vector2 p, gc_vector2 q, gc_vector2 r)
|
||||
{
|
||||
int nb_intersects = 0;
|
||||
if (q.x <= fmaxf(p.x, r.x) && q.x >= fminf(p.x, r.x) && \
|
||||
q.y <= fmaxf(p.y, r.y) && q.y >= fminf(p.y, r.y))
|
||||
return (true);
|
||||
return (false);
|
||||
}
|
||||
|
||||
//printf("pos x : %f y : %f\n", x1.x, x1.y);
|
||||
//printf("x2 x : %f y : %f\n", x2.x, x2.y);
|
||||
//printf("c1 x : %f y : %f\n", polygon[0].x, polygon[0].y);
|
||||
if (gc_vector2_is_intersect(x1, x2, polygon[0], polygon[1])) {
|
||||
nb_intersects++;
|
||||
printf("1 p0 : x:%f f:%f\n", polygon[0].x, polygon[0].y);
|
||||
printf("1 p1 : x:%f f:%f\n", polygon[1].x, polygon[1].y);
|
||||
}
|
||||
if (gc_vector2_is_intersect(x1, x2, polygon[1], polygon[3])) {
|
||||
nb_intersects++;
|
||||
printf("2 p1 : x:%f f:%f\n", polygon[1].x, polygon[1].y);
|
||||
printf("2 p2 : x:%f f:%f\n", polygon[3].x, polygon[3].y);
|
||||
}
|
||||
if (gc_vector2_is_intersect(x1, x2, polygon[3], polygon[2])) {
|
||||
nb_intersects++;
|
||||
printf("3 p2 : x:%f f:%f\n", polygon[2].x, polygon[2].y);
|
||||
printf("3 p3 : x:%f f:%f\n", polygon[3].x, polygon[3].y);
|
||||
}
|
||||
if (gc_vector2_is_intersect(x1, x2, polygon[2], polygon[0])) {
|
||||
nb_intersects++;
|
||||
printf("4 p2 : x:%f f:%f\n", polygon[2].x, polygon[2].y);
|
||||
printf("4 p0 : x:%f f:%f\n", polygon[0].x, polygon[0].y);
|
||||
}
|
||||
return (nb_intersects);
|
||||
int orientation(gc_vector2 p, gc_vector2 q, gc_vector2 r)
|
||||
{
|
||||
int tmp = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
|
||||
|
||||
if (tmp == 0)
|
||||
return (0);
|
||||
return ((tmp > 0) ? 1 : 2);
|
||||
}
|
||||
|
||||
bool gc_vector2_do_intersect(gc_vector2 p1, gc_vector2 q1, gc_vector2 p2, gc_vector2 q2)
|
||||
{
|
||||
int o1 = orientation(p1, q1, p2);
|
||||
int o2 = orientation(p1, q1, q2);
|
||||
int o3 = orientation(p2, q2, p1);
|
||||
int o4 = orientation(p2, q2, q1);
|
||||
|
||||
if (o1 != o2 && o3 != o4)
|
||||
return (true);
|
||||
if (o1 == 0 && is_on_segment(p1, p2, q1))
|
||||
return (true);
|
||||
if (o2 == 0 && is_on_segment(p1, q2, q1))
|
||||
return (true);
|
||||
if (o3 == 0 && is_on_segment(p2, p1, q2))
|
||||
return (true);
|
||||
if (o4 == 0 && is_on_segment(p2, q1, q2))
|
||||
return (true);
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool is_point_in_polygon(gc_vector2 *polygon, int n, gc_vector2 p)
|
||||
{
|
||||
gc_vector2 segment = {-INF, p.y};
|
||||
int count = 0;
|
||||
int next = 0;
|
||||
int i = 0;
|
||||
|
||||
if (n < 3)
|
||||
return (false);
|
||||
do {
|
||||
next = (i + 1) % n;
|
||||
if (gc_vector2_do_intersect(polygon[i], polygon[next], p, segment)) {
|
||||
if (orientation(polygon[i], p, polygon[next]) == 0)
|
||||
return (is_on_segment(polygon[i], p, polygon[next]));
|
||||
count++;
|
||||
}
|
||||
i = next;
|
||||
} while (i != 0);
|
||||
return (count & 1);
|
||||
}
|
||||
|
||||
bool is_pos_in_tile(gc_vector2 pos, struct tile *tile)
|
||||
{
|
||||
struct vertex **c = tile->corners;
|
||||
gc_vector2 inf = {INFINITY, INFINITY};
|
||||
gc_vector2 corners[4];
|
||||
int ret;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
corners[i] = get_tile_coords_to_pixels(c[i]->x, c[i]->y, c[i]->z);
|
||||
}
|
||||
|
||||
ret = nb_intersection_between_vectors(pos, inf, corners);
|
||||
//my_printf("nb int : %i\n", ret);
|
||||
if (!ret || ret % 2 != 0)
|
||||
return (false);
|
||||
printf("The polygon true\n");
|
||||
for (int i = 0; i < 4; i++)
|
||||
printf("%i :(x:%f, y:%f)\n", i + 1, corners[i].x, corners[i].y);
|
||||
return (true);
|
||||
corners[i] = get_tile_coords_to_pixels(c[i]->x, c[i]->y, c[i]->z);
|
||||
if (is_point_in_polygon(corners, 4, pos)) {
|
||||
//for (int i = 0; i < 4; i ++)
|
||||
// printf("%i :(x:%f, y:%f)\n", i + 1, corners[i].x, corners[i].y);
|
||||
// printf("\n");
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
struct tile *get_tile_from_pos(gc_engine *engine, struct vertex_component *map, gc_vector2 pos)
|
||||
@@ -92,7 +116,7 @@ bool map_manage_click(gc_engine *engine, int id, gc_vector2 pos)
|
||||
gc_scene *scene = engine->scene;
|
||||
gc_entity *entity = scene->get_entity(scene, id);
|
||||
struct vertex_component *map = entity->get_component(entity, "vertex_component");
|
||||
struct tile *ret;
|
||||
struct tile *ret = NULL;
|
||||
|
||||
printf("map_manage_click called id: %i coords x: %f y:%f\n", id, pos.x, pos.y);
|
||||
if (!map) {
|
||||
|
||||
@@ -51,8 +51,8 @@ static bool get_tiles(struct vertex_component *this, gc_scene *scene, node *n)
|
||||
for (vy = 0; this->vertices[v_x][vy].z != INT32_MIN; vy++) {
|
||||
this->map[inc].corners[0] = &this->vertices[v_x][vy];
|
||||
this->map[inc].corners[1] = &this->vertices[v_x][vy + 1];
|
||||
this->map[inc].corners[2] = &this->vertices[v_x + 1][vy];
|
||||
this->map[inc].corners[3] = &this->vertices[v_x + 1][vy + 1];
|
||||
this->map[inc].corners[3] = &this->vertices[v_x + 1][vy];
|
||||
this->map[inc].corners[2] = &this->vertices[v_x + 1][vy + 1];
|
||||
this->map[inc++].texture = scene->get_data(scene, "sprite", (inc % 2) ? "cobblestone" : "mossy_cobblestone");
|
||||
if (inc > 31 && inc < 56)
|
||||
this->map[inc - 1].texture = scene->get_data(scene, "sprite", "crafting_table");
|
||||
|
||||
@@ -36,10 +36,15 @@ void sfml_handle_events(gc_engine *engine)
|
||||
}
|
||||
}
|
||||
|
||||
gc_vector2 sfml_engine_get_cursor_pos(gc_engine *engine)
|
||||
gc_vector2i sfml_engine_get_cursor_pos(gc_engine *engine)
|
||||
{
|
||||
sfMouseMoveEvent mouse;
|
||||
sfMouse_getPositionRenderWindow(GETSYS(engine, sfml_renderer_system));
|
||||
sfVector2i pos;
|
||||
gc_vector2i ret;
|
||||
|
||||
pos = sfMouse_getPositionRenderWindow(GETSYS(engine, sfml_renderer_system));
|
||||
ret.x = pos.x;
|
||||
ret.y = pos.y;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void sfml_resize(gc_engine *engine, gc_vector2 size)
|
||||
|
||||
@@ -34,6 +34,6 @@ sfVertexArray *sfml_init_verticies(void)
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
sfVertexArray_append(arr, v[i]);
|
||||
sfVertexArray_setPrimitiveType(arr, sfTriangleStrip);
|
||||
sfVertexArray_setPrimitiveType(arr, sfTrianglesStrip);
|
||||
return (arr);
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "components/transform_component.h"
|
||||
#include "systems/sfml_renderer_system.h"
|
||||
#include "components/vertex_component.h"
|
||||
#include "map_managment.h"
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <SFML/Graphics.h>
|
||||
@@ -28,24 +29,51 @@ sfVector2f get_tile_coords(int x, int y, int z)
|
||||
}
|
||||
|
||||
void draw_tile(struct sfml_renderer_system *this, struct vertex_component \
|
||||
*info, struct tile tile)
|
||||
*info, struct tile *tile)
|
||||
{
|
||||
sfVertex *vert1 = sfVertexArray_getVertex(this->vertices, 1);
|
||||
sfVertex *vert2 = sfVertexArray_getVertex(this->vertices, 2);
|
||||
sfVertex *vert3 = sfVertexArray_getVertex(this->vertices, 3);
|
||||
sfVertex *vert2 = sfVertexArray_getVertex(this->vertices, 3);
|
||||
sfVertex *vert3 = sfVertexArray_getVertex(this->vertices, 2);
|
||||
int corners[9];
|
||||
|
||||
if (tile.corners[0]->z == INT32_MAX || !tile.corners[3]->y)
|
||||
|
||||
if (tile->corners[0]->z == INT32_MAX || !tile->corners[2]->y)
|
||||
return;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
corners[i * 3] = tile.corners[i + 1]->x;
|
||||
corners[i * 3 + 1] = tile.corners[i + 1]->y;
|
||||
corners[i * 3 + 2] = tile.corners[i + 1]->z;
|
||||
corners[i * 3] = tile->corners[i + 1]->x;
|
||||
corners[i * 3 + 1] = tile->corners[i + 1]->y;
|
||||
corners[i * 3 + 2] = tile->corners[i + 1]->z;
|
||||
}
|
||||
vert1->position = get_tile_coords(corners[0], corners[1], corners[2]);
|
||||
vert2->position = get_tile_coords(corners[3], corners[4], corners[5]);
|
||||
vert3->position = get_tile_coords(corners[6], corners[7], corners[8]);
|
||||
this->states->texture = (sfTexture *)tile.texture;
|
||||
sfVector2i vec = sfMouse_getPosition(this->window);
|
||||
sfVector2f world_pos = sfRenderWindow_mapPixelToCoords(this->window, vec, this->view);
|
||||
world_pos.y *= -1;
|
||||
//printf("mouse is x:%f, y:%f\n", world_pos.x, world_pos.y);
|
||||
if (!is_pos_in_tile((gc_vector2){world_pos.x, world_pos.y}, tile))
|
||||
this->states->texture = (sfTexture *)tile->texture;
|
||||
else
|
||||
this->states->texture = NULL;
|
||||
sfVertexArray_setPrimitiveType(this->vertices, sfTrianglesStrip);
|
||||
sfVertex *vert0 = sfVertexArray_getVertex(this->vertices, 0);
|
||||
vert0->color = sfWhite;
|
||||
vert1->color = sfWhite;
|
||||
vert2->color = sfWhite;
|
||||
vert3->color = sfWhite;
|
||||
sfRenderWindow_drawVertexArray(this->window, this->vertices, this->states);
|
||||
world_pos.y *= -1;
|
||||
sfVertexArray_setPrimitiveType(this->vertices, sfLinesStrip);
|
||||
vert0->position = world_pos;
|
||||
vert1->position = (sfVector2f){world_pos.x, world_pos.y};
|
||||
vert2->position = (sfVector2f){10000, -10000};
|
||||
vert3->position = (sfVector2f){10000, -10000};
|
||||
//printf("sfml inf is x:%f, y:%f\n", vert2->position.x, vert2->position.y);
|
||||
this->states->texture = NULL;
|
||||
vert0->color = sfRed;
|
||||
vert1->color = sfRed;
|
||||
vert2->color = sfRed;
|
||||
vert3->color = sfRed;
|
||||
sfRenderWindow_drawVertexArray(this->window, this->vertices, this->states);
|
||||
}
|
||||
|
||||
@@ -83,6 +111,6 @@ struct vertex_component *info)
|
||||
//if (!info->map[i].corners[0]->y)
|
||||
// continue;
|
||||
vert0->position = get_tile_coords(corners[0], corners[1], corners[2]);
|
||||
draw_tile(this, info, info->map[i]);
|
||||
draw_tile(this, info, &info->map[i]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user