FPS
This commit is contained in:
@@ -6,22 +6,25 @@
|
||||
*/
|
||||
|
||||
#include "entity.h"
|
||||
#include "rpg/world/map.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
#include "display/tileset/tileset_entities.h"
|
||||
#include "time/time.h"
|
||||
#include "util/math.h"
|
||||
|
||||
void entityInit(entity_t *entity, const entitytype_t type, map_t *map) {
|
||||
entity_t ENTITIES[ENTITY_COUNT];
|
||||
|
||||
void entityInit(entity_t *entity, const entitytype_t type) {
|
||||
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||
assertNotNull(map, "Map pointer cannot be NULL");
|
||||
assertTrue(type < ENTITY_TYPE_COUNT, "Invalid entity type");
|
||||
assertTrue(type != ENTITY_TYPE_NULL, "Cannot have NULL entity type");
|
||||
assertTrue(
|
||||
entity >= ENTITIES && entity < ENTITIES + ENTITY_COUNT,
|
||||
"Entity pointer is out of bounds"
|
||||
);
|
||||
|
||||
memoryZero(entity, sizeof(entity_t));
|
||||
entity->type = type;
|
||||
entity->map = map;
|
||||
|
||||
// Init. I did use a callback struct but it was not flexible enough.
|
||||
switch(type) {
|
||||
@@ -42,66 +45,4 @@ void entityUpdate(entity_t *entity) {
|
||||
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||
assertTrue(entity->type < ENTITY_TYPE_COUNT, "Invalid entity type");
|
||||
assertTrue(entity->type != ENTITY_TYPE_NULL, "Cannot have NULL entity type");
|
||||
|
||||
// Handle movement logic
|
||||
switch(entity->type) {
|
||||
case ENTITY_TYPE_PLAYER:
|
||||
playerMovement(entity);
|
||||
break;
|
||||
|
||||
case ENTITY_TYPE_NPC:
|
||||
npcUpdate(entity);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Apply velocity
|
||||
if(entity->velocity[0] != 0.0f || entity->velocity[1] != 0.0f) {
|
||||
entity->position[0] += entity->velocity[0] * TIME.delta;
|
||||
entity->position[1] += entity->velocity[1] * TIME.delta;
|
||||
|
||||
// Hit test on other entities.
|
||||
entity_t *start = entity->map->entities;
|
||||
entity_t *end = &entity->map->entities[entity->map->entityCount];
|
||||
|
||||
// Our hitbox
|
||||
physicscircle_t self;
|
||||
glm_vec2_copy(entity->position, self.position);
|
||||
self.radius = TILESET_ENTITIES.tileWidth / 2.0f;
|
||||
|
||||
physicscircle_t other;
|
||||
other.radius = self.radius;
|
||||
|
||||
// TODO: what if multiple collisions?
|
||||
do {
|
||||
if(start == entity) continue;
|
||||
if(start->type == ENTITY_TYPE_NULL) continue;
|
||||
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)
|
||||
entity->velocity[0] *= ENTITY_FRICTION * TIME.delta;
|
||||
entity->velocity[1] *= ENTITY_FRICTION * TIME.delta;
|
||||
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(entity->type == ENTITY_TYPE_PLAYER) {
|
||||
playerInteraction(entity);
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,11 @@
|
||||
#include "rpg/entity/player.h"
|
||||
#include "npc.h"
|
||||
#include "physics/physics.h"
|
||||
#include "rpg/world/worldunit.h"
|
||||
|
||||
#define ENTITY_FRICTION 0.9f
|
||||
#define ENTITY_MIN_VELOCITY 0.05f
|
||||
#define ENTITY_FRICTION 1
|
||||
#define ENTITY_MIN_VELOCITY 1
|
||||
#define ENTITY_COUNT 256
|
||||
|
||||
typedef struct map_s map_t;
|
||||
|
||||
@@ -25,12 +27,10 @@ typedef enum {
|
||||
} entitytype_t;
|
||||
|
||||
typedef struct entity_s {
|
||||
map_t *map;
|
||||
entitytype_t type;
|
||||
direction_t direction;
|
||||
|
||||
vec2 position;
|
||||
vec2 velocity;
|
||||
worldchunkpos_t position[3];
|
||||
worldsubtile_t velocity[3];
|
||||
|
||||
union {
|
||||
player_t player;
|
||||
@@ -38,14 +38,15 @@ typedef struct entity_s {
|
||||
};
|
||||
} entity_t;
|
||||
|
||||
extern entity_t ENTITIES[ENTITY_COUNT];
|
||||
|
||||
/**
|
||||
* Initializes an entity structure.
|
||||
*
|
||||
* @param entity Pointer to the entity structure to initialize.
|
||||
* @param type The type of the entity.
|
||||
* @param map Pointer to the map the entity belongs to.
|
||||
*/
|
||||
void entityInit(entity_t *entity, const entitytype_t type, map_t *map);
|
||||
void entityInit(entity_t *entity, const entitytype_t type);
|
||||
|
||||
/**
|
||||
* Updates an entity.
|
||||
|
||||
@@ -17,98 +17,98 @@ void playerInit(entity_t *entity) {
|
||||
void playerMovement(entity_t *entity) {
|
||||
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||
|
||||
// Update velocity.
|
||||
vec2 dir = {
|
||||
inputAxis(INPUT_ACTION_LEFT, INPUT_ACTION_RIGHT),
|
||||
inputAxis(INPUT_ACTION_DOWN, INPUT_ACTION_UP)
|
||||
};
|
||||
if(dir[0] == 0 && dir[1] == 0) return;
|
||||
// // Update velocity.
|
||||
// vec2 dir = {
|
||||
// inputAxis(INPUT_ACTION_LEFT, INPUT_ACTION_RIGHT),
|
||||
// inputAxis(INPUT_ACTION_DOWN, INPUT_ACTION_UP)
|
||||
// };
|
||||
// if(dir[0] == 0 && dir[1] == 0) return;
|
||||
|
||||
glm_vec2_normalize(dir);
|
||||
entity->velocity[0] += PLAYER_SPEED * dir[0];
|
||||
entity->velocity[1] += PLAYER_SPEED * dir[1];
|
||||
// glm_vec2_normalize(dir);
|
||||
// entity->velocity[0] += PLAYER_SPEED * dir[0];
|
||||
// entity->velocity[1] += PLAYER_SPEED * dir[1];
|
||||
|
||||
// Update direction.
|
||||
if(dir[0] > 0) {
|
||||
if(entity->direction == DIRECTION_RIGHT) {
|
||||
entity->direction = DIRECTION_RIGHT;
|
||||
} else {
|
||||
if(dir[1] < 0) {
|
||||
entity->direction = DIRECTION_UP;
|
||||
} else if(dir[1] > 0) {
|
||||
entity->direction = DIRECTION_DOWN;
|
||||
} else {
|
||||
entity->direction = DIRECTION_RIGHT;
|
||||
}
|
||||
}
|
||||
} else if(dir[0] < 0) {
|
||||
if(entity->direction == DIRECTION_LEFT) {
|
||||
entity->direction = DIRECTION_LEFT;
|
||||
} else {
|
||||
if(dir[1] < 0) {
|
||||
entity->direction = DIRECTION_UP;
|
||||
} else if(dir[1] > 0) {
|
||||
entity->direction = DIRECTION_DOWN;
|
||||
} else {
|
||||
entity->direction = DIRECTION_LEFT;
|
||||
}
|
||||
}
|
||||
} else if(dir[1] < 0) {
|
||||
entity->direction = DIRECTION_UP;
|
||||
} else if(dir[1] > 0) {
|
||||
entity->direction = DIRECTION_DOWN;
|
||||
}
|
||||
// // Update direction.
|
||||
// if(dir[0] > 0) {
|
||||
// if(entity->direction == DIRECTION_RIGHT) {
|
||||
// entity->direction = DIRECTION_RIGHT;
|
||||
// } else {
|
||||
// if(dir[1] < 0) {
|
||||
// entity->direction = DIRECTION_UP;
|
||||
// } else if(dir[1] > 0) {
|
||||
// entity->direction = DIRECTION_DOWN;
|
||||
// } else {
|
||||
// entity->direction = DIRECTION_RIGHT;
|
||||
// }
|
||||
// }
|
||||
// } else if(dir[0] < 0) {
|
||||
// if(entity->direction == DIRECTION_LEFT) {
|
||||
// entity->direction = DIRECTION_LEFT;
|
||||
// } else {
|
||||
// if(dir[1] < 0) {
|
||||
// entity->direction = DIRECTION_UP;
|
||||
// } else if(dir[1] > 0) {
|
||||
// entity->direction = DIRECTION_DOWN;
|
||||
// } else {
|
||||
// entity->direction = DIRECTION_LEFT;
|
||||
// }
|
||||
// }
|
||||
// } else if(dir[1] < 0) {
|
||||
// entity->direction = DIRECTION_UP;
|
||||
// } else if(dir[1] > 0) {
|
||||
// entity->direction = DIRECTION_DOWN;
|
||||
// }
|
||||
}
|
||||
|
||||
void playerInteraction(entity_t *entity) {
|
||||
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||
// assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||
|
||||
if(!inputPressed(INPUT_ACTION_ACCEPT)) return;
|
||||
// if(!inputPressed(INPUT_ACTION_ACCEPT)) return;
|
||||
|
||||
physicsbox_t interactBox;
|
||||
// physicsbox_t interactBox;
|
||||
|
||||
// Get direction vector
|
||||
directionGetVec2(entity->direction, interactBox.min);
|
||||
// // Get direction vector
|
||||
// directionGetVec2(entity->direction, interactBox.min);
|
||||
|
||||
// Scale by interact range
|
||||
glm_vec2_scale(interactBox.min, PLAYER_INTERACTION_RANGE, interactBox.min);
|
||||
// // Scale by interact range
|
||||
// glm_vec2_scale(interactBox.min, PLAYER_INTERACTION_RANGE, interactBox.min);
|
||||
|
||||
// Add entity position, this makes the center of the box.
|
||||
glm_vec2_add(interactBox.min, entity->position, interactBox.min);
|
||||
// // Add entity position, this makes the center of the box.
|
||||
// glm_vec2_add(interactBox.min, entity->position, interactBox.min);
|
||||
|
||||
// Copy to max
|
||||
glm_vec2_copy(interactBox.min, interactBox.max);
|
||||
// // Copy to max
|
||||
// glm_vec2_copy(interactBox.min, interactBox.max);
|
||||
|
||||
// Size of the hitbox
|
||||
vec2 halfSize = {
|
||||
TILESET_ENTITIES.tileWidth * PLAYER_INTERACTION_SIZE * 0.5f,
|
||||
TILESET_ENTITIES.tileHeight * PLAYER_INTERACTION_SIZE * 0.5f
|
||||
};
|
||||
// // Size of the hitbox
|
||||
// vec2 halfSize = {
|
||||
// TILESET_ENTITIES.tileWidth * PLAYER_INTERACTION_SIZE * 0.5f,
|
||||
// TILESET_ENTITIES.tileHeight * PLAYER_INTERACTION_SIZE * 0.5f
|
||||
// };
|
||||
|
||||
// Subtract from min, add to max.
|
||||
glm_vec2_sub(interactBox.min, halfSize, interactBox.min);
|
||||
glm_vec2_add(interactBox.max, halfSize, interactBox.max);
|
||||
// // Subtract from min, add to max.
|
||||
// glm_vec2_sub(interactBox.min, halfSize, interactBox.min);
|
||||
// glm_vec2_add(interactBox.max, halfSize, interactBox.max);
|
||||
|
||||
// For each entity
|
||||
entity_t *start = entity->map->entities;
|
||||
entity_t *end = &entity->map->entities[entity->map->entityCount];
|
||||
vec2 otherSize = { TILESET_ENTITIES.tileWidth, TILESET_ENTITIES.tileHeight };
|
||||
physicsbox_t otherBox;
|
||||
physicsboxboxresult_t result;
|
||||
// // For each entity
|
||||
// entity_t *start = entity->map->entities;
|
||||
// entity_t *end = &entity->map->entities[entity->map->entityCount];
|
||||
// vec2 otherSize = { TILESET_ENTITIES.tileWidth, TILESET_ENTITIES.tileHeight };
|
||||
// physicsbox_t otherBox;
|
||||
// physicsboxboxresult_t result;
|
||||
|
||||
do {
|
||||
if(start->type != ENTITY_TYPE_NPC) continue;
|
||||
// do {
|
||||
// if(start->type != ENTITY_TYPE_NPC) continue;
|
||||
|
||||
// Setup other box.
|
||||
glm_vec2_copy(start->position, otherBox.min);
|
||||
glm_vec2_copy(start->position, otherBox.max);
|
||||
glm_vec2_sub(otherBox.min, otherSize, otherBox.min);
|
||||
glm_vec2_add(otherBox.min, otherSize, otherBox.max);
|
||||
// // Setup other box.
|
||||
// glm_vec2_copy(start->position, otherBox.min);
|
||||
// glm_vec2_copy(start->position, otherBox.max);
|
||||
// glm_vec2_sub(otherBox.min, otherSize, otherBox.min);
|
||||
// glm_vec2_add(otherBox.min, otherSize, otherBox.max);
|
||||
|
||||
physicsBoxCheckBox(interactBox, otherBox, &result);
|
||||
if(!result.hit) continue;
|
||||
// physicsBoxCheckBox(interactBox, otherBox, &result);
|
||||
// if(!result.hit) continue;
|
||||
|
||||
printf("Interacted with entity at (%.2f, %.2f)\n", start->position[0], start->position[1]);
|
||||
break;
|
||||
} while(++start != end);
|
||||
// printf("Interacted with entity at (%.2f, %.2f)\n", start->position[0], start->position[1]);
|
||||
// break;
|
||||
// } while(++start != end);
|
||||
}
|
||||
@@ -6,13 +6,21 @@
|
||||
*/
|
||||
|
||||
#include "rpg.h"
|
||||
#include "entity/entity.h"
|
||||
|
||||
errorret_t rpgInit(void) {
|
||||
// TEST
|
||||
entityInit(&ENTITIES[0], ENTITY_TYPE_PLAYER);
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void rpgUpdate(void) {
|
||||
|
||||
entity_t *ent = &ENTITIES[0];
|
||||
do {
|
||||
if(ent->type == ENTITY_TYPE_NULL) continue;
|
||||
entityUpdate(ent);
|
||||
} while(++ent < &ENTITIES[ENTITY_COUNT]);
|
||||
}
|
||||
|
||||
void rpgDispose(void) {
|
||||
|
||||
Reference in New Issue
Block a user