#include "animation.h" #include "asset.h" #include "map.h" #include "maths.h" #include "obj.h" #include "physics.h" #include "plat.h" #include "render.h" #include "world.h" void init_player(Player* p) { p->anim = asset_id_guy_run_right_anm; p->x = 0; p->y = 0; p->vx = 0; p->vy = 0; p->frame = 0; p->grounded = 0; p->headbutted = 0; p->on_ramp = 0; p->jumping = 0; p->cooldown = 0; p->face = face_right; } void update_player_anim(Player* p) { const Animation* anim = get_animation(p->anim); update_anim(anim, &p->frame, &p->rect); } void update_player_phys(Player* p, const Map* map) { const Rect r = { 5 << fbits, 4 << fbits, 5 << fbits, 12 << fbits }; update_body( map, &p->x, &p->y, &p->vx, &p->vy, &p->grounded, &p->headbutted, &p->on_ramp, &r ); } void update_player_move(Player* p, const App* a, World* w) { int grounded = p->grounded < 3; int mf = player_move_force; int nanim, moving, t; int jumping = p->jumping; Face* face = &p->face; p->cooldown--; if (!grounded) { mf = player_air_move_force; } if (btn_pressed(a, btn_left)) { p->vx -= mf; *face = face_left; } if (btn_pressed(a, btn_right)) { p->vx += mf; *face = face_right; } p->vx = p->vx < -player_max_vel ? -player_max_vel: p->vx > player_max_vel ? player_max_vel: p->vx; moving = absolute(p->vx); moving = moving > player_stop_thresh; if (p->grounded == 0 || p->headbutted) { p->jumping = 0; } jumping = p->jumping; if (jumping) { if (p->grounded < 10 && btn_pressed(a, btn_jump)) { t = absolute(p->vy + 1); t = (f1 << fbits) / t; p->vy -= (player_jump_power_air * t) >> fbits; } if (p->vy < 0 && btn_just_released(a, btn_jump)) { p->vy += f1; p->jumping = 0; } } if (grounded && btn_just_pressed(a, btn_jump)) { p->vy = -player_jump_power; p->jumping = 1; play_sound(500); } if (p->cooldown <= 0 && btn_just_pressed(a, btn_shoot)) { int sx, sy; int anim; if (p->face == face_left) { anim = asset_id_slash_left_anm; sx = (p->x >> fbits) - 45; sy = (p->y >> fbits); } else { anim = asset_id_slash_right_anm; sx = (p->x >> fbits) + 16; sy = (p->y >> fbits); } inst_particle(w, sx, sy, anim, asset_id_arms_img); p->cooldown = 10; } jumping = p->jumping; nanim = p->anim; switch (p->face) { case face_left: nanim = grounded ? moving ? asset_id_guy_run_left_anm: asset_id_guy_idle_left_anm: p->vy < 0 ? asset_id_guy_jump_left_anm: asset_id_guy_fall_left_anm; break; case face_right: nanim = grounded ? moving ? asset_id_guy_run_right_anm: asset_id_guy_idle_right_anm: p->vy < 0 ? asset_id_guy_jump_right_anm: asset_id_guy_fall_right_anm; break; default: break; } if (nanim != p->anim) { p->frame = 0; p->anim = nanim; } } void update_player( Player* p, World* w, const App* app, const Map* map ) { update_player_move(p, app, w); update_player_phys(p, map); update_player_anim(p); } void ren_player(const Player* p, struct Renderer* r) { const Bitmap* b = get_bitmap(asset_id_guy_img); ren_map(r, p->x >> fbits, p->y >> fbits, &p->rect, b); }