Refine the squish
parent
19e61744ce
commit
ad7d2d3fa4
|
@ -2,7 +2,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
// 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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
159
obj/squishy.c
159
obj/squishy.c
|
@ -1,23 +1,16 @@
|
|||
#include "header.h"
|
||||
#include <rlgl.h>
|
||||
|
||||
#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;i<BEZIER_POINTS;++i)
|
||||
DrawTriangle(vertices[i], center,vertices[i+1], square->color);
|
||||
three_point_beizerfan(square->topright, square->right_handle, square->bottomright, vertices);
|
||||
for(i=0;i<BEZIER_POINTS;++i)
|
||||
DrawTriangle(vertices[i], center,vertices[i+1], square->color);
|
||||
three_point_beizerfan(square->bottomright, square->bottom_handle, square->bottomleft, vertices);
|
||||
for(i=0;i<BEZIER_POINTS;++i)
|
||||
DrawTriangle(vertices[i], center,vertices[i+1], square->color);
|
||||
three_point_beizerfan(square->bottomleft, square->left_handle, square->topleft, vertices);
|
||||
for(i=0;i<BEZIER_POINTS;++i)
|
||||
DrawTriangle(vertices[i], center,vertices[i+1],square->color);
|
||||
rlPushMatrix();
|
||||
//rlScalef(0.5, 0.5, 1.0); // Scale Sun
|
||||
//rlTranslatef(square->center.x, square->center.y, 0.0f);
|
||||
int i;
|
||||
for(i=0;i<BEZIER_POINTS;++i){
|
||||
DrawTriangle(square->top_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){
|
||||
|
|
Loading…
Reference in New Issue