diff --git a/include/header.h b/include/header.h index a1a9dfd..877d8f3 100644 --- a/include/header.h +++ b/include/header.h @@ -2,7 +2,7 @@ #include // Global Constants -#define BEZIER_POINTS 7 +#define BEZIER_POINTS 5 #define LEFT KEY_LEFT #define RIGHT KEY_RIGHT #define JUMP KEY_SPACE @@ -46,18 +46,17 @@ struct squishy_square { struct kinematic_obj *parent; Color color; - Vector2 topleft; - Vector2 topright; - Vector2 bottomleft; - Vector2 bottomright; - Vector2 top_handle; - Vector2 bottom_handle; - Vector2 left_handle; - Vector2 right_handle; + Vector2 center; + double top_offset; double bottom_offset; double left_offset; double right_offset; + + Vector2 top_vertices[BEZIER_POINTS+1]; + Vector2 bottom_vertices[BEZIER_POINTS+1]; + Vector2 left_vertices[BEZIER_POINTS+1]; + Vector2 right_vertices[BEZIER_POINTS+1]; }; // Object functions, kinematics.c diff --git a/obj/player.c b/obj/player.c index c68cf7d..ef0b73d 100644 --- a/obj/player.c +++ b/obj/player.c @@ -3,7 +3,7 @@ #define PLAYER_ACCEL 1600 #define AIR_ACCEL 400 -#define RUN_INIT_SPD 270 +#define RUN_INIT_SPD 230 #define JUMP_SPD 500 #define GRAV 1200 diff --git a/obj/squishy.c b/obj/squishy.c index c97a37b..0564dc1 100644 --- a/obj/squishy.c +++ b/obj/squishy.c @@ -1,23 +1,16 @@ #include "header.h" +#include -#define INTERP_FACTOR 0.5 +#define INTERP_FACTOR 0.2 #define OFFSET_VALUE 20 -void three_point_beizerfan(Vector2 start, Vector2 mid, Vector2 end, Vector2* arr); +void three_point_beizer(Vector2 start, Vector2 mid, Vector2 end, Vector2* arr); void calc_offsets(struct squishy_square *square); struct squishy_square init_squishy_square(struct kinematic_obj *parent, Color color){ struct squishy_square sqr = { .parent = parent, .color = color, - .topleft = (Vector2){0,0}, - .topright= (Vector2){0,0}, - .bottomleft = (Vector2){0,0}, - .bottomright = (Vector2){0,0}, - .top_handle = (Vector2){0,0}, - .bottom_handle = (Vector2){0,0}, - .left_handle = (Vector2){0,0}, - .right_handle = (Vector2){0,0}, .top_offset = 0.0, .bottom_offset = 0.0, .left_offset = 0.0, @@ -29,100 +22,104 @@ struct squishy_square init_squishy_square(struct kinematic_obj *parent, Color co void update_squishy(struct squishy_square *square){ calc_offsets(square); + // TODO: Should be centered at zero, then transformed during drawing // Update to follow the player - square->topleft.x = square->parent->rect.x; - square->topleft.y = square->parent->rect.y; - square->topright.x = square->parent->rect.x + square->parent->rect.width; - square->topright.y = square->parent->rect.y; - square->bottomleft.x = square->parent->rect.x; - square->bottomleft.y = square->parent->rect.y + square->parent->rect.height; - square->bottomright.x = square->parent->rect.x + square->parent->rect.width; - square->bottomright.y = square->parent->rect.y + square->parent->rect.height; + Vector2 topleft = (Vector2){square->parent->rect.x, square->parent->rect.y}; + Vector2 topright = (Vector2){square->parent->rect.x+square->parent->rect.width, square->parent->rect.y}; + Vector2 bottomleft = (Vector2){square->parent->rect.x, square->parent->rect.y+ square->parent->rect.height}; + Vector2 bottomright = (Vector2){square->parent->rect.x+ square->parent->rect.width, + square->parent->rect.y+ square->parent->rect.height}; - square->top_handle.x = square->parent->rect.x + square->parent->rect.width / 2; - square->top_handle.y = square->parent->rect.y + square->top_offset; - square->bottom_handle.x = square->parent->rect.x + square->parent->rect.width / 2; - square->bottom_handle.y = square->parent->rect.y + square->parent->rect.height - square->bottom_offset; - square->left_handle.x = square->parent->rect.x + square->left_offset; - square->left_handle.y = square->parent->rect.y + square->parent->rect.height / 2; - square->right_handle.x = square->parent->rect.x + square->parent->rect.width - square->right_offset; - square->right_handle.y = square->parent->rect.y + square->parent->rect.height / 2; + // This is assuming the shape remains AABB + square->center.x = (topleft.x + topright.x)/2; + square->center.y = (topleft.y + bottomleft.y)/2; + + Vector2 top_handle = (Vector2){square->center.x, topleft.y + square->top_offset}; + Vector2 bottom_handle = (Vector2){square->center.x, bottomright.y - square->bottom_offset}; + Vector2 left_handle = (Vector2){topleft.x + square->left_offset, square->center.y}; + Vector2 right_handle = (Vector2){topright.x - square->right_offset, square->center.y}; + + three_point_beizer(topleft, top_handle, topright, square->top_vertices); + three_point_beizer(topright, right_handle, bottomright, square->right_vertices); + three_point_beizer(bottomright, bottom_handle, bottomleft, square->bottom_vertices); + three_point_beizer(bottomleft, left_handle, topleft, square->left_vertices); } void calc_offsets(struct squishy_square *square){ + /* 0 - left, 1 - top, 2 - right, 3 - bottom + */ // TODO: Normalise the offsets - double left_target_offset = 0; - double right_target_offset = 0; - double top_target_offset = 0; - double bottom_target_offset = 0; + double target_offsets[4] = {0,0,0,0}; if (IsKeyDown(KEY_A)){ - left_target_offset = OFFSET_VALUE; - if (place_meeting(square->parent, (Vector2){1, 0})){ - top_target_offset = -OFFSET_VALUE / 2; - bottom_target_offset = -OFFSET_VALUE / 2; - }else{ - right_target_offset = -OFFSET_VALUE * 0.8; - } + target_offsets[0] += OFFSET_VALUE; + target_offsets[2] += -OFFSET_VALUE * 0.5; } if (IsKeyDown(KEY_D)){ - right_target_offset = OFFSET_VALUE; - if (place_meeting(square->parent, (Vector2){-1, 0})){ - top_target_offset = -OFFSET_VALUE / 2; - bottom_target_offset = -OFFSET_VALUE / 2; - }else{ - left_target_offset = -OFFSET_VALUE * 0.8; - } + target_offsets[2] += OFFSET_VALUE; + target_offsets[0] += -OFFSET_VALUE * 0.5; } if (IsKeyDown(KEY_W)){ - top_target_offset = OFFSET_VALUE; - if (place_meeting(square->parent, (Vector2){0, 1})){ - right_target_offset = -OFFSET_VALUE / 2; - left_target_offset = -OFFSET_VALUE / 2; - }else{ - bottom_target_offset = -OFFSET_VALUE * 0.8; - } + target_offsets[1] += OFFSET_VALUE; + target_offsets[3] += -OFFSET_VALUE * 0.5; } if (IsKeyDown(KEY_S)){ - bottom_target_offset = OFFSET_VALUE; - if (place_meeting(square->parent, (Vector2){0, -1})){ - right_target_offset = -OFFSET_VALUE / 2; - left_target_offset = -OFFSET_VALUE / 2; - }else{ - top_target_offset = -OFFSET_VALUE * 0.8; + target_offsets[3] += OFFSET_VALUE; + target_offsets[1] += -OFFSET_VALUE * 0.5; + } + bool contacts[4]; + int n_contacts = 0; + contacts[0] = place_meeting(square->parent, (Vector2){-1, 0}); + contacts[1] = place_meeting(square->parent, (Vector2){0, -1}); + contacts[2] = place_meeting(square->parent, (Vector2){1, 0}); + contacts[3] = place_meeting(square->parent, (Vector2){0, 1}); + + // Redistribute the offset on contact + for (int i=0; i < 4; ++i){ + if (contacts[i] == true && target_offsets[i] < 0){ + unsigned int n = 0; + unsigned int j; + unsigned int ind; + for (j=0; j < 3; ++j){ + ind = (i+1+j) % 4; + if (contacts[ind] == false) + ++n; + } + if (n > 0){ + for (j=0; j < 3; ++j){ + ind = (i+1+j) % 4; + if (contacts[ind] == false) + target_offsets[ind] += target_offsets[i] / n; + } + } + target_offsets[i] = 0; } } - - approach(&square->left_offset, left_target_offset, INTERP_FACTOR); - approach(&square->right_offset, right_target_offset, INTERP_FACTOR); - approach(&square->top_offset, top_target_offset, INTERP_FACTOR); - approach(&square->bottom_offset, bottom_target_offset, INTERP_FACTOR); + approach(&square->left_offset, target_offsets[0], INTERP_FACTOR); + approach(&square->top_offset, target_offsets[1], INTERP_FACTOR); + approach(&square->right_offset, target_offsets[2], INTERP_FACTOR); + approach(&square->bottom_offset, target_offsets[3], INTERP_FACTOR); } void draw_squishy(struct squishy_square *square){ - Vector2 center = (Vector2){ - .x = (square->topleft.x + square->topright.x)/2, - .y = (square->topleft.y + square->bottomleft.y)/2 - }; - Vector2 vertices[BEZIER_POINTS+1]; - int i; - three_point_beizerfan(square->topleft, square->top_handle, square->topright, vertices); - for(i=0;icolor); - three_point_beizerfan(square->topright, square->right_handle, square->bottomright, vertices); - for(i=0;icolor); - three_point_beizerfan(square->bottomright, square->bottom_handle, square->bottomleft, vertices); - for(i=0;icolor); - three_point_beizerfan(square->bottomleft, square->left_handle, square->topleft, vertices); - for(i=0;icolor); + rlPushMatrix(); + //rlScalef(0.5, 0.5, 1.0); // Scale Sun + //rlTranslatef(square->center.x, square->center.y, 0.0f); + int i; + for(i=0;itop_vertices[i], square->center, square->top_vertices[i+1], square->color); + DrawTriangle(square->bottom_vertices[i], square->center, square->bottom_vertices[i+1], square->color); + DrawTriangle(square->left_vertices[i], square->center, square->left_vertices[i+1], square->color); + DrawTriangle(square->right_vertices[i], square->center, square->right_vertices[i+1],square->color); + } + rlPopMatrix(); } -void three_point_beizerfan(Vector2 start, Vector2 mid, Vector2 end, Vector2* arr){ +void three_point_beizer(Vector2 start, Vector2 mid, Vector2 end, Vector2* arr){ + /* Generate the vertices for a beizer curve + */ double t; double t_prime; for (int i=0;i<=BEZIER_POINTS;++i){