#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" const Rect player_rect = { 5, 4, 5, 12 }; 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->slashing = 0; p->face = face_right; p->inv = 0; p->hp = player_health; } 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) { Rect r = player_rect; r.x <<= fbits; r.y <<= fbits; r.w <<= fbits; r.h <<= 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 = p->y >> fbits, vx; int anim; Rect dz; if (p->face == face_left) { anim = asset_id_slash_left_anm; sx = (p->x >> fbits) - 45; vx = f1 * 3; } else { anim = asset_id_slash_right_anm; sx = (p->x >> fbits) + 16; vx = -f1 * 3; } dz.x = sx; dz.y = sy; dz.w = 45; dz.h = 17; inst_particle(w, sx, sy, anim, asset_id_arms_img); inst_deathzone(w, &dz, vx, 0, player_slash_damage, 4, 1); p->cooldown = 10; p->slashing = get_animation(asset_id_guy_slash_left_anm)->fc; } if (p->slashing) { p->slashing--; } jumping = p->jumping; nanim = p->anim; switch (p->face) { case face_left: nanim = p->slashing? asset_id_guy_slash_left_anm: 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 = p->slashing? asset_id_guy_slash_right_anm: 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_hurt(Player* p, World* w) { int i; Rect r = player_rect; r.x += p->x >> fbits; r.y += p->y >> fbits; if (p->inv) { p->inv--; return; } for (i = 0; i < w->deathzone_count; i++) { const Deathzone* dz = &w->deathzones[i]; if (!dz->friendly && rects_overlap(&r, &dz->r)) { p->hp -= dz->hp; p->vx -= dz->vx; p->vy -= dz->vy; p->inv = enemy_inv_frames; } } } void update_player( Player* p, World* w, const App* app, const Map* map ) { update_player_move(p, app, w); update_player_hurt(p, 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); }