Starting ent stuff
This commit is contained in:
@@ -1,11 +0,0 @@
|
|||||||
# Copyright (c) 2025 Dominic Masters
|
|
||||||
#
|
|
||||||
# This software is released under the MIT License.
|
|
||||||
# https://opensource.org/licenses/MIT
|
|
||||||
|
|
||||||
# Sources
|
|
||||||
target_sources(${DUSK_TARGET_NAME}
|
|
||||||
PRIVATE
|
|
||||||
physicscircle.c
|
|
||||||
physicsbox.c
|
|
||||||
)
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "physicscircle.h"
|
|
||||||
#include "physicsbox.h"
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "physicsbox.h"
|
|
||||||
|
|
||||||
void physicsBoxCheckBox(
|
|
||||||
const physicsbox_t a,
|
|
||||||
const physicsbox_t b,
|
|
||||||
physicsboxboxresult_t *out
|
|
||||||
) {
|
|
||||||
float_t dx = (b.min[0] + b.max[0]) / 2.0f - (a.min[0] + a.max[0]) / 2.0f;
|
|
||||||
float_t dy = (b.min[1] + b.max[1]) / 2.0f - (a.min[1] + a.max[1]) / 2.0f;
|
|
||||||
float_t combinedHalfWidths = (a.max[0] - a.min[0]) / 2.0f + (b.max[0] - b.min[0]) / 2.0f;
|
|
||||||
float_t combinedHalfHeights = (a.max[1] - a.min[1]) / 2.0f + (b.max[1] - b.min[1]) / 2.0f;
|
|
||||||
|
|
||||||
if (fabsf(dx) < combinedHalfWidths && fabsf(dy) < combinedHalfHeights) {
|
|
||||||
out->hit = true;
|
|
||||||
float_t overlapX = combinedHalfWidths - fabsf(dx);
|
|
||||||
float_t overlapY = combinedHalfHeights - fabsf(dy);
|
|
||||||
|
|
||||||
if (overlapX < overlapY) {
|
|
||||||
if (dx > 0) {
|
|
||||||
out->normal[0] = 1.0f;
|
|
||||||
out->normal[1] = 0.0f;
|
|
||||||
} else {
|
|
||||||
out->normal[0] = -1.0f;
|
|
||||||
out->normal[1] = 0.0f;
|
|
||||||
}
|
|
||||||
out->depth = overlapX;
|
|
||||||
} else {
|
|
||||||
if (dy > 0) {
|
|
||||||
out->normal[0] = 0.0f;
|
|
||||||
out->normal[1] = 1.0f;
|
|
||||||
} else {
|
|
||||||
out->normal[0] = 0.0f;
|
|
||||||
out->normal[1] = -1.0f;
|
|
||||||
}
|
|
||||||
out->depth = overlapY;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
out->hit = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "dusk.h"
|
|
||||||
|
|
||||||
typedef struct physicsbox_s {
|
|
||||||
vec2 min;
|
|
||||||
vec2 max;
|
|
||||||
} physicsbox_t;
|
|
||||||
|
|
||||||
typedef struct physicsboxboxresult_s {
|
|
||||||
bool_t hit;
|
|
||||||
vec2 normal;
|
|
||||||
float_t depth;
|
|
||||||
} physicsboxboxresult_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check for collision between two boxes.
|
|
||||||
*
|
|
||||||
* @param a The first box.
|
|
||||||
* @param b The second box.
|
|
||||||
* @param out Pointer to the result structure to populate.
|
|
||||||
*/
|
|
||||||
void physicsBoxCheckBox(
|
|
||||||
const physicsbox_t a,
|
|
||||||
const physicsbox_t b,
|
|
||||||
physicsboxboxresult_t *out
|
|
||||||
);
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "physicscircle.h"
|
|
||||||
|
|
||||||
void physicsCircleCheckCircle(
|
|
||||||
const physicscircle_t a,
|
|
||||||
const physicscircle_t b,
|
|
||||||
physicscirclecircleresult_t *out
|
|
||||||
) {
|
|
||||||
vec2 delta;
|
|
||||||
glm_vec2_sub(b.position, a.position, delta);
|
|
||||||
float_t distSq = glm_vec2_dot(delta, delta);
|
|
||||||
float_t radiusSum = a.radius + b.radius;
|
|
||||||
float_t radiusSumSq = radiusSum * radiusSum;
|
|
||||||
|
|
||||||
if(distSq < radiusSumSq) {
|
|
||||||
out->hit = true;
|
|
||||||
if (distSq != 0.0f) {
|
|
||||||
glm_vec2_normalize_to(delta, out->normal);
|
|
||||||
} else {
|
|
||||||
out->normal[0] = 1.0f;
|
|
||||||
out->normal[1] = 0.0f;
|
|
||||||
}
|
|
||||||
out->depth = radiusSum - sqrtf(distSq);
|
|
||||||
} else {
|
|
||||||
out->hit = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "dusk.h"
|
|
||||||
|
|
||||||
typedef struct physicscircle_s {
|
|
||||||
vec2 position;
|
|
||||||
float_t radius;
|
|
||||||
} physicscircle_t;
|
|
||||||
|
|
||||||
typedef struct physicscirclecircleresult_s {
|
|
||||||
bool_t hit;
|
|
||||||
vec2 normal;
|
|
||||||
float_t depth;
|
|
||||||
} physicscirclecircleresult_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check for collision between two circles.
|
|
||||||
*
|
|
||||||
* @param a The first circle.
|
|
||||||
* @param b The second circle.
|
|
||||||
* @param out Pointer to the result structure to populate.
|
|
||||||
*/
|
|
||||||
void physicsCircleCheckCircle(
|
|
||||||
const physicscircle_t a,
|
|
||||||
const physicscircle_t b,
|
|
||||||
physicscirclecircleresult_t *out
|
|
||||||
);
|
|
||||||
@@ -25,7 +25,6 @@ void entityInit(entity_t *entity, const entitytype_t type) {
|
|||||||
memoryZero(entity, sizeof(entity_t));
|
memoryZero(entity, sizeof(entity_t));
|
||||||
entity->id = (uint8_t)(entity - ENTITIES);
|
entity->id = (uint8_t)(entity - ENTITIES);
|
||||||
entity->type = type;
|
entity->type = type;
|
||||||
entity->hitboxRadius = .5f;
|
|
||||||
|
|
||||||
// Init. I did use a callback struct but it was not flexible enough.
|
// Init. I did use a callback struct but it was not flexible enough.
|
||||||
switch(type) {
|
switch(type) {
|
||||||
@@ -47,62 +46,8 @@ void entityUpdate(entity_t *entity) {
|
|||||||
assertTrue(entity->type < ENTITY_TYPE_COUNT, "Invalid entity type");
|
assertTrue(entity->type < ENTITY_TYPE_COUNT, "Invalid entity type");
|
||||||
assertTrue(entity->type != ENTITY_TYPE_NULL, "Cannot have NULL entity type");
|
assertTrue(entity->type != ENTITY_TYPE_NULL, "Cannot have NULL entity type");
|
||||||
|
|
||||||
//
|
// Movement code.
|
||||||
if(entity->type == ENTITY_TYPE_PLAYER) {
|
if(entity->type == ENTITY_TYPE_PLAYER) {
|
||||||
playerMovement(entity);
|
playerMovement(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply velocity
|
|
||||||
if(
|
|
||||||
entity->velocity[0] != 0.0f ||
|
|
||||||
entity->velocity[1] != 0.0f ||
|
|
||||||
entity->velocity[2] != 0.0f
|
|
||||||
) {
|
|
||||||
entity->position[0] += entity->velocity[0] * TIME.fixedDelta;
|
|
||||||
entity->position[1] += entity->velocity[1] * TIME.fixedDelta;
|
|
||||||
entity->position[2] += entity->velocity[2] * TIME.fixedDelta;
|
|
||||||
|
|
||||||
// Hit test on other entities.
|
|
||||||
entity_t *start = ENTITIES;
|
|
||||||
entity_t *end = &ENTITIES[ENTITY_COUNT];
|
|
||||||
|
|
||||||
// Our hitbox
|
|
||||||
physicscircle_t self;
|
|
||||||
glm_vec2_copy(entity->position, self.position);
|
|
||||||
self.radius = entity->hitboxRadius;
|
|
||||||
|
|
||||||
physicscircle_t other;
|
|
||||||
|
|
||||||
// TODO: what if multiple collisions?
|
|
||||||
do {
|
|
||||||
if(start == entity) continue;
|
|
||||||
if(start->type == ENTITY_TYPE_NULL) continue;
|
|
||||||
other.radius = start->hitboxRadius;
|
|
||||||
glm_vec2_copy(start->position, other.position);
|
|
||||||
|
|
||||||
physicscirclecircleresult_t result;
|
|
||||||
physicsCircleCheckCircle(self, other, &result);
|
|
||||||
|
|
||||||
if(result.hit) {
|
|
||||||
entity->position[0] -= result.normal[0] * result.depth;
|
|
||||||
entity->position[1] -= result.normal[1] * result.depth;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while((start++) != end);
|
|
||||||
|
|
||||||
// Friction (and dampening)
|
|
||||||
glm_vec3_muladds(
|
|
||||||
entity->velocity, -ENTITY_FRICTION * TIME.fixedDelta, entity->velocity
|
|
||||||
);
|
|
||||||
|
|
||||||
if(mathAbs(entity->velocity[0]) < ENTITY_MIN_VELOCITY) {
|
|
||||||
entity->velocity[0] = 0.0f;
|
|
||||||
}
|
|
||||||
if(mathAbs(entity->velocity[1]) < ENTITY_MIN_VELOCITY) {
|
|
||||||
entity->velocity[1] = 0.0f;
|
|
||||||
}
|
|
||||||
if(mathAbs(entity->velocity[2]) < ENTITY_MIN_VELOCITY) {
|
|
||||||
entity->velocity[2] = 0.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -9,10 +9,7 @@
|
|||||||
#include "direction.h"
|
#include "direction.h"
|
||||||
#include "rpg/entity/player.h"
|
#include "rpg/entity/player.h"
|
||||||
#include "npc.h"
|
#include "npc.h"
|
||||||
#include "physics/physics.h"
|
|
||||||
|
|
||||||
#define ENTITY_FRICTION 16.0f
|
|
||||||
#define ENTITY_MIN_VELOCITY 0.1f
|
|
||||||
#define ENTITY_COUNT 256
|
#define ENTITY_COUNT 256
|
||||||
|
|
||||||
typedef struct map_s map_t;
|
typedef struct map_s map_t;
|
||||||
@@ -29,10 +26,7 @@ typedef struct entity_s {
|
|||||||
uint8_t id;
|
uint8_t id;
|
||||||
entitytype_t type;
|
entitytype_t type;
|
||||||
direction_t direction;
|
direction_t direction;
|
||||||
vec3 position;
|
uint32_t position;// Tile index
|
||||||
vec3 velocity;
|
|
||||||
|
|
||||||
float_t hitboxRadius;
|
|
||||||
|
|
||||||
union {
|
union {
|
||||||
player_t player;
|
player_t player;
|
||||||
|
|||||||
@@ -8,11 +8,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "dusk.h"
|
#include "dusk.h"
|
||||||
|
|
||||||
#define PLAYER_SPEED 48.0f
|
|
||||||
#define PLAYER_SPEED_RUNNING 72.0f
|
|
||||||
#define PLAYER_INTERACTION_RANGE 1.0f
|
|
||||||
#define PLAYER_INTERACTION_SIZE 0.5f
|
|
||||||
|
|
||||||
typedef struct entity_s entity_t;
|
typedef struct entity_s entity_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user