Add target draw and collision

master
En Yi 2020-03-20 20:11:06 +08:00 committed by En Yi
parent 206b0d61a6
commit 11e7084586
6 changed files with 72 additions and 12 deletions

View File

@ -88,6 +88,11 @@ struct squishy_square
Vector2 right_vertices[BEZIER_POINTS+1];
};
struct target_obj
{
double radius;
struct kinematic_obj kinematic;
};
// Object functions, kinematics.c
struct kinematic_obj init_kinematic_obj(int width, int height);
void move(struct kinematic_obj *obj, Vector2 acceleration);
@ -101,6 +106,7 @@ double mag(Vector2 vec);
int sign(double val);
Vector2 dir(Vector2 vec);
void approach(double *val, double target, float f);
Vector2 center(Rectangle rect);
// Linked list, linked_list.c
void create_list(void);
@ -123,7 +129,7 @@ struct player_obj init_player_obj();
void player_input_check(struct player_obj *player);
//Target stuff, target.c
struct kinematic_obj init_target();
struct target_obj init_target();
//Debug stuff, debug.c
void state_string(char *str, enum PLAYER_STATE state);

14
main.c
View File

@ -24,6 +24,7 @@
#include "header.h"
struct kinematic_obj_node *kinematic_HEAD = NULL;
struct kinematic_obj_node *target_HEAD = NULL;
int PLAYER_ACCEL = 1500;
int JUMP_ACCEL = 15000;
int JUMP_SPD = 350;
@ -60,8 +61,6 @@ int main()
struct kinematic_obj tile6 = init_kinematic_obj(50, 300);
struct kinematic_obj tile7 = init_kinematic_obj(50, 300);
struct kinematic_obj target = init_target(50, 300);
set_position(&player.kinematic, 400, 100);
set_position(&tile, -50, 380);
set_position(&tile2, 100, 280);
@ -81,6 +80,11 @@ int main()
add_node(&tile6, &kinematic_HEAD);
add_node(&tile7, &kinematic_HEAD);
add_node(&player.kinematic, &kinematic_HEAD);
struct target_obj target = init_target(50, 300);
set_position(&target.kinematic, 150, 380);
add_node(&target.kinematic, &target_HEAD);
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@ -110,6 +114,11 @@ int main()
DrawRectangleLinesEx(current->obj->rect, 1, BLACK);
current = current->next;
}
current = target_HEAD;
while(current){
DrawCircle(current->obj->pos.x, current->obj->pos.y, current->obj->ori_width, BLACK);
current = current->next;
}
DrawFPS(0,0);
state_string(current_state, player.state);
DrawText(current_state, 250, 0, 12, BLACK);
@ -127,6 +136,7 @@ int main()
// De-Initialization
//--------------------------------------------------------------------------------------
free_list(&kinematic_HEAD);
free_list(&target_HEAD);
free_afterimages(&player);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

View File

@ -103,13 +103,6 @@ bool place_meeting(struct kinematic_obj *obj, Vector2 dir){
return false;
}
Vector2 center(Rectangle rect){
return (Vector2){
.x = rect.x + rect.width/2,
.y = rect.y + rect.height/2
};
}
void adjust_hitbox(struct kinematic_obj *obj){
approach(&obj->dim_reduction[0], obj->set_dim_reduction[0], 0.2);
approach(&obj->dim_reduction[1], obj->set_dim_reduction[1], 0.2);

View File

@ -34,6 +34,8 @@ const unsigned int afterimage_frames = 10;
static enum PLAYER_STATE state_buffer = IDLE;
unsigned int PLAYER_SIZE = 30;
extern struct kinematic_obj_node *target_HEAD;
// The player FSM
void player_input_check(struct player_obj *player){
Vector2 accel = (Vector2){

View File

@ -1,5 +1,47 @@
#include "header.h"
#include <raymath.h>
#include <math.h>
// Target is circular, thus a kinematic obj has w=h
struct target_obj init_target(){
return (struct target_obj){
.radius = 12,
.kinematic = init_kinematic_obj(12, 12)
};
}
struct kinematic_obj init_target(){
return init_kinematic_obj(25, 25);
bool collide_target(struct kinematic_obj *obj, struct target_obj *target){
/* The method is based off SAT
*/
Vector2 obj_center = center(obj->rect);
Vector2 target_center = center(target->kinematic.rect);
float dist = Vector2Distance(obj_center, target_center);
if (dist < target->radius)
return true;
double max_dim = fmax(obj->rect.width, obj->rect.height);
if (dist > max_dim + target->radius)
return false;
Vector2 n = Vector2Subtract(target_center, obj_center);
n = Vector2Normalize(n);
Vector2 pos_check = obj->pos;
double obj_proj1 = Vector2DotProduct(pos_check, n);
pos_check.x += obj->rect.width;
double obj_proj2 = Vector2DotProduct(pos_check, n);
pos_check.y += obj->rect.height;
double obj_proj3 = Vector2DotProduct(pos_check, n);
pos_check.x -= obj->rect.width;
double obj_proj4 = Vector2DotProduct(pos_check, n);
double min_proj = fmin(fmin(fmin(obj_proj1, obj_proj2), obj_proj3), obj_proj4);
double max_proj = fmax(fmax(fmax(obj_proj1, obj_proj2), obj_proj3), obj_proj4);
double target_proj = Vector2DotProduct(target_center, n);
if (!(max_proj < target_proj - target->radius) && !(min_proj > target_proj + target->radius))
return true;
return false;
}

View File

@ -7,4 +7,11 @@ int sign(double val){
void approach(double *val, double target, float f){
*val += (target - *val) * f;
}
Vector2 center(Rectangle rect){
return (Vector2){
.x = rect.x + rect.width/2,
.y = rect.y + rect.height/2
};
}