#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 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; }