155 lines
4.6 KiB
C
155 lines
4.6 KiB
C
#include "player.h"
|
|
#include "input_axis.h"
|
|
#include "physics_entity.h"
|
|
#include "rigidbody.h"
|
|
#include "input.h"
|
|
#include "physics_world.h"
|
|
#include "game_world.h"
|
|
#include <SDL2/SDL_gamecontroller.h>
|
|
|
|
static const float _anim_speed = 1.0/8.0;
|
|
|
|
static
|
|
void player_input_h(Player* self, InputEvent val) {
|
|
self->directional.x = val.as_float * 5.f;
|
|
if(val.as_float > 0.0) {
|
|
sprite_flip_horizontal(self->sprite, 0);
|
|
} else if(val.as_float < 0.0) {
|
|
sprite_flip_horizontal(self->sprite, 1);
|
|
}
|
|
}
|
|
|
|
static
|
|
void player_input_jump(Player* self, InputEvent down) {
|
|
if(down.as_bool && self->is_grounded) {
|
|
Vector velocity = rigidbody_get_velocity(self->rigidbody);
|
|
self->directional.y = 0;
|
|
velocity.y = -20.f;
|
|
rigidbody_set_velocity(self->rigidbody, velocity);
|
|
}
|
|
}
|
|
|
|
static inline
|
|
void _internal_player_init_input(Player* self) {
|
|
// default to keyboard if no controllers are available
|
|
if(input_get_device_by_id(0) != NULL)
|
|
self->player_input = playerinput_new(self, 0);
|
|
else
|
|
self->player_input = playerinput_new(self, -1);
|
|
|
|
// KEYBOARD ------------------------------------------------
|
|
// WALK
|
|
playerinput_add(self->player_input, CompositeAxis1D_as_InputAxis(compositeaxis1d_new(
|
|
KeyBind_as_InputAxis(keybind_new(SDL_SCANCODE_A)),
|
|
KeyBind_as_InputAxis(keybind_new(SDL_SCANCODE_D)),
|
|
InputEvent_Float
|
|
)), (InputDelegateFn)player_input_h);
|
|
// JUMP
|
|
playerinput_add(self->player_input, KeyBind_as_InputAxis(
|
|
keybind_new(SDL_SCANCODE_W)
|
|
), (InputDelegateFn)player_input_jump);
|
|
|
|
// CONTROLLER ------------------------------------------------
|
|
// WALK
|
|
playerinput_add(self->player_input, ControllerAxis_as_InputAxis(
|
|
controlleraxis_new(0)
|
|
), (InputDelegateFn)player_input_h);
|
|
// JUMP
|
|
playerinput_add(self->player_input, ControllerButton_as_InputAxis(
|
|
controllerbutton_new(SDL_CONTROLLER_BUTTON_A)
|
|
), (InputDelegateFn)player_input_jump);
|
|
}
|
|
|
|
Player* player_new() {
|
|
Spritesheet* spr_player_standing = spritesheet_load("assets/sprites/player.png", (IVector){128, 128});
|
|
|
|
float ex_w = 0.1f;
|
|
float h = .75f;
|
|
float r = 0.01f;
|
|
float rr = 0.01f;
|
|
Player* self = malloc(sizeof(Player));
|
|
*self = (Player) {
|
|
.transform = {ZeroVector, {4, 4}, 0},
|
|
.sprite = sprite_from_spritesheet(spr_player_standing, 0),
|
|
.shape = shape_new((Vector[]){
|
|
{ex_w, -rr}, {ex_w-r, 0.f},
|
|
{r-ex_w, 0.f}, {-ex_w, -rr},
|
|
{-ex_w, rr-h}, {r-ex_w, -h},
|
|
{ex_w-r, -h}, {ex_w, rr-h},
|
|
}, 8)
|
|
};
|
|
|
|
self->rigidbody = rigidbody_make(Player_as_Transformable(self));
|
|
rigidbody_set_mass(self->rigidbody, 10.f);
|
|
physics_world_add_entity(Player_as_PhysicsEntity(self));
|
|
sprite_set_origin(self->sprite, (Vector){0.25f, 1.f});
|
|
rigidbody_set_bounce(self->rigidbody, 0.0);
|
|
|
|
_internal_player_init_input(self);
|
|
|
|
return self;
|
|
}
|
|
|
|
void player_spawn(Player* self, Vector at) {
|
|
rigidbody_get_transform(self->rigidbody)->position = at;
|
|
game_world_add_entity(Player_as_BehaviourEntity(self));
|
|
}
|
|
|
|
void player_collision_solver(Player* self, List* contacts) {
|
|
physics_entity_solve_contacts(Player_as_PhysicsEntity(self), contacts);
|
|
}
|
|
|
|
void player_start(Player* self) {}
|
|
|
|
void player_update(Player* self, float dt) {
|
|
Vector velocity = rigidbody_get_velocity(self->rigidbody);
|
|
Vector velocity_target = {self->is_grounded ? self->directional.x : velocity.x, velocity.y};
|
|
rigidbody_accelerate(self->rigidbody, vmulff(vsubf(velocity_target, velocity), 50.f), 0);
|
|
rigidbody_accelerate(self->rigidbody, (Vector){0.0f, 100.f}, 0);
|
|
self->is_grounded = 0;
|
|
|
|
self->frame_timer -= dt;
|
|
if(self->frame_timer <= 0.0) {
|
|
sprite_set_tile(self->sprite, sprite_get_tile(self->sprite) + 1);
|
|
self->frame_timer = _anim_speed;
|
|
}
|
|
}
|
|
|
|
void player_draw(Player* self) {
|
|
sprite_entity_draw(Player_as_SpriteEntity(self));
|
|
}
|
|
|
|
void player_free(Player* self) {
|
|
rigidbody_destroy(self->rigidbody);
|
|
shape_destroy(self->shape);
|
|
sprite_destroy(self->sprite);
|
|
playerinput_drop(self->player_input);
|
|
free(self);
|
|
}
|
|
|
|
void player_collision(Player* self, Collision hit) {
|
|
if(hit.point.y > -0.01f) {
|
|
self->is_grounded = 1;
|
|
}
|
|
}
|
|
|
|
Sprite* player_get_sprite(Player* self) {
|
|
return self->sprite;
|
|
}
|
|
|
|
Transform* player_get_transform(Player* self) {
|
|
return &self->transform;
|
|
}
|
|
|
|
Transform* player_get_rigidbody_transform(Player* self) {
|
|
return rigidbody_get_transform(self->rigidbody);
|
|
}
|
|
|
|
RigidBody* player_get_rigidbody(Player* self) {
|
|
return self->rigidbody;
|
|
}
|
|
|
|
Shape* player_get_shape(Player* self) {
|
|
return self->shape;
|
|
}
|