This commit is contained in:
2026-07-19 14:05:46 -05:00
parent 725338cd5a
commit 13a435e9c1
12 changed files with 389 additions and 0 deletions
@@ -0,0 +1,6 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
add_subdirectory(overworld)
@@ -0,0 +1,9 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
entityplayer.c
)
@@ -0,0 +1,88 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "entityplayer.h"
#include "entity/entitymanager.h"
#include "entity/component/physics/entityphysics.h"
#include "entity/component/display/entitycamera.h"
#include "input/input.h"
#include "util/memory.h"
#define ENTITY_PLAYER_MOVE_SPEED_DEFAULT 4.0f
#define ENTITY_PLAYER_JUMP_IMPULSE_DEFAULT 6.0f
void entityPlayerInit(
entitymanager_t *mgr,
const entityid_t entityId,
const componentid_t componentId
) {
entityplayer_t *player = entityPlayerGet(mgr, entityId, componentId);
memoryZero(player, sizeof(entityplayer_t));
player->moveSpeed = ENTITY_PLAYER_MOVE_SPEED_DEFAULT;
player->jumpImpulse = ENTITY_PLAYER_JUMP_IMPULSE_DEFAULT;
entityUpdateAdd(mgr, entityId, entityPlayerUpdate, componentId, NULL);
}
entityplayer_t *entityPlayerGet(
entitymanager_t *mgr,
const entityid_t entityId,
const componentid_t componentId
) {
return componentGetData(mgr, entityId, componentId, COMPONENT_TYPE_PLAYER);
}
void entityPlayerUpdate(
entitymanager_t *mgr,
const entityid_t entityId,
const componentid_t componentId,
void *user
) {
componentid_t physComp = entityGetComponent(
mgr, entityId, COMPONENT_TYPE_PHYSICS
);
if(physComp == COMPONENT_ID_INVALID) return;
entityplayer_t *player = entityPlayerGet(mgr, entityId, componentId);
vec2 moveInput;
inputAxis2D(
INPUT_BIND_LEFT, INPUT_BIND_RIGHT,
INPUT_BIND_DOWN, INPUT_BIND_UP,
moveInput
);
// Move relative to the current camera's horizontal facing, not fixed
// world axes, so "up" always means "away from the camera".
vec2 forward = { 0.0f, -1.0f };
vec2 right = { 1.0f, 0.0f };
entityid_t camEntity = entityCameraGetCurrent(mgr);
if(camEntity != ENTITY_ID_INVALID) {
entityCameraGetForward(mgr, camEntity, forward);
entityCameraGetRight(mgr, camEntity, right);
}
vec2 moveDir = {
right[0] * moveInput[0] + forward[0] * moveInput[1],
right[1] * moveInput[0] + forward[1] * moveInput[1]
};
// Clamp to unit length so diagonal input isn't faster than cardinal.
float_t mag = sqrtf(moveDir[0] * moveDir[0] + moveDir[1] * moveDir[1]);
if(mag > 1.0f) {
moveDir[0] /= mag;
moveDir[1] /= mag;
}
vec3 velocity;
entityPhysicsGetVelocity(mgr, entityId, physComp, velocity);
velocity[0] = moveDir[0] * player->moveSpeed;
velocity[2] = moveDir[1] * player->moveSpeed;
entityPhysicsSetVelocity(mgr, entityId, physComp, velocity);
}
@@ -0,0 +1,64 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "entity/entitybase.h"
typedef struct {
float_t moveSpeed;
float_t jumpImpulse;
} entityplayer_t;
/**
* Initializes the player component: sets default move speed and jump
* impulse.
*
* @param mgr The entity manager that owns the entity.
* @param entityId The entity ID.
* @param componentId The component ID.
*/
void entityPlayerInit(
entitymanager_t *mgr,
const entityid_t entityId,
const componentid_t componentId
);
/**
* Gets the underlying player structure (temporarily) for the given entity.
* This is really just intended for doing operations faster than using the
* getters and setters, but it is preferred that you use those.
*
* @param mgr The entity manager that owns the entity.
* @param entityId The entity ID.
* @param componentId The component ID.
* @return The player component data for the given entity and component ID.
*/
entityplayer_t *entityPlayerGet(
entitymanager_t *mgr,
const entityid_t entityId,
const componentid_t componentId
);
/**
* Per-tick update for the player component: reads the movement input axes
* and drives the entity's physics velocity, relative to the current
* camera's horizontal facing (so "up" always moves away from the camera
* and "left"/"right" strafe relative to its view), rather than fixed world
* axes. No-op if the entity has no physics component. Registered
* automatically as an update callback by entityPlayerInit.
*
* @param mgr The entity manager that owns the entity.
* @param entityId The entity ID.
* @param componentId The component ID.
* @param user Unused.
*/
void entityPlayerUpdate(
entitymanager_t *mgr,
const entityid_t entityId,
const componentid_t componentId,
void *user
);