function player_move_and_collide() { if place_meeting(x, y + y_spd, oParentSolid) { while !place_meeting(x, y + sign(y_spd), oParentSolid) y += sign(y_spd); y_spd = 0; } y += y_spd; if place_meeting(x + x_spd, y, oParentSolid) { var _max_step = (y_spd == 0) ? 16 : 8; //前者地面容错,后者空中容错 var _stepped = false; for(var i = 0; i < _max_step; i++) if !place_meeting(x + x_spd, y - i, oParentSolid) { y -= i; _stepped = true; break; } if !_stepped { while !place_meeting(x + sign(x_spd), y, oParentSolid) x += sign(x_spd); x_spd = 0; } } x += x_spd; } function player_status_update() { current_attacker = instance_place(x, y, oEnemyHitbox); /**/ image_index += animation_spd; if oInput._dash dash_buffer = dash_buffer_max; if oInput._attack attack_buffer = attack_buffer_max; _move_dir = oInput._right - oInput._left; _on_ground = place_meeting(x, y + 1, oParentSolid) _on_wall = place_meeting(x + 1, y, oBlockClimbable) - place_meeting(x - 1, y, oBlockClimbable); if _on_ground || (_on_wall != 0) can_dash = true; if _on_ground { jump_cnt = 0; coyote_timer = coyote_max; } else if coyote_timer <= 0 && jump_cnt == 0 jump_cnt = 1; if dash_cooldown > 0 dash_cooldown--; if dash_buffer > 0 dash_buffer--; if attack_buffer > 0 attack_buffer--; if move_lock_timer > 0 move_lock_timer--; if coyote_timer > 0 coyote_timer--; } function player_check_dash() { if dash_buffer > 0 && dash_cooldown <= 0 && can_dash { dash_buffer = 0; state = state_dash; set_sprite(sPlayerDash); dash_cooldown = 36; x_spd = image_xscale * walk_spd * 3; y_spd = 0; can_dash = false; } } function player_check_movement() { if move_lock_timer <= 0 x_spd = _move_dir * walk_spd; } function player_check_jump() { if oInput.jump_buffer_timer > 0 { if coyote_timer > 0 { y_spd = jump_spd; jump_cnt = 1; oInput.jump_buffer_timer = 0; coyote_timer = 0; } else if _on_wall != 0 { y_spd = jump_spd; x_spd = -_on_wall * walk_spd * 1.5; jump_cnt = 1; move_lock_timer = 10; oInput.jump_buffer_timer = 0; } else if jump_cnt < jump_max { icl(oDoubleJumpEffect); y_spd = jump_spd * 0.9; jump_cnt++; oInput.jump_buffer_timer = 0; } } if oInput._jump_r && y_spd < 0 y_spd *= 0.4; } function player_check_attack() { if attack_buffer > 0 { attack_buffer = 0; state = state_attack; set_sprite(sPlayerAttack); } } function player_check_dodge() { if (oInput._down || oInput._up) && _on_ground && (oInput._dash || state == state_dash) { state = state_dodge; set_sprite(sPlayerDodgeWait); dodge_phase = "WAIT"; dodge_timer = 0; marked_target = noone; is_marked = false; is_perfect = false; var _hb = icl(oPlayerHitboxMark, x + facing * 60, y + 40); _hb.owner = id; _hb.x_offset = 60 * facing; _hb.y_offset = 40; } } function player_check_attacked() { if current_attacker == noone || is_invincible || (state == state_dodge && dodge_phase == "WAIT") return; global.playerHP -= current_attacker.damage; is_invincible = true; alarm[0] = 80; // 稍后取缔 var _dir = sign(x - current_attacker.x); if _dir == 0 _dir = facing; global.hitstop = 12; x_spd = _dir * 30; y_spd = -5; state = state_hitstun_attacked; set_sprite(sPlayerHitstunAttacked); //effects } function player_check_hazard() { var _hazard = instance_place(x, y, oParentHazard); if _hazard != noone { global.playerHP -= _hazard.damage; is_invincible = true; alarm[0] = 150; var _dir = sign(x - _hazard.x); if _dir == 0 _dir = facing; global.hitstop = 18; x_spd = _dir * 10; y_spd = -10; state = state_hitstun_hazard; set_sprite(sPlayerHitstunHazard); } } function state_hitstun_attacked() { x_spd = lerp(x_spd, 0, 0.1); y_spd += global.g; if animation_end() state = state_free; } function state_hitstun_hazard() { x_spd = lerp(x_spd, 0, 0.1); y_spd += global.g; if animation_end() { alarm[1] = 60; state = state_locked; var _fade = icl(oFade); _fade._callback = function() { oPlayer.x = 160;//oPlayer.last_safe_x; oPlayer.y = 2016;//oPlayer.last_safe_y; camera_snap(); }; } } function state_free() { y_spd += global.g; if _on_wall != 0 && y_spd > 0 y_spd = min(y_spd, 3); /*下面是动画与视觉*/ animation_spd = 0.25; if _move_dir != 0 //有输入 { facing = _move_dir; if _on_ground set_sprite(sPlayerWalk); //走路 } else set_sprite(sPlayerIdle); //待机 if !_on_ground { if _on_wall == facing set_sprite(sPlayerWall); else { set_sprite(sPlayerJump); image_index = (y_spd < 0) ? 0 : 1; } } /**/ player_check_dodge(); if state == state_dodge return; player_check_movement(); player_check_dash(); player_check_jump(); player_check_attack(); } function state_dash() { y_spd += 0.2 * global.g; icl(oPlayerAfterImage); if animation_end() { if !_on_ground jump_cnt = max(jump_cnt, 1); state = state_free; player_check_attack(); } player_check_dodge(); } function state_attack() { player_check_movement(); player_check_jump(); y_spd += global.g; if image_index == 1 { var _hb; if oInput._down && !_on_ground { _hb = icl(oPlayerHitboxVer, x, y + 64); _hb.y_offset = 64; } else if oInput._up { _hb = icl(oPlayerHitboxVer, x, y - 64); _hb.y_offset = -64; _hb.kb_factor_y = -5; } else { _hb = icl(oPlayerHitboxHor, x + 72 * facing); _hb.x_offset += 72 * facing; _hb.kb_factor_x *= facing; } _hb.owner = id; } // 冲刺预输入 if image_index >= 2 player_check_dash(); // 攻击后摇结束 if animation_end() state = state_free; } function state_locked() { x_spd = 0; y_spd += global.g; } function state_dodge() { if dodge_phase == "WAIT" { x_spd = 0; if current_attacker != noone || animation_end() { y_spd = jump_spd; dodge_phase = "DODGE"; set_sprite(sPlayerDodge); if current_attacker != noone && is_marked { is_perfect = true; is_invincible = true; global.time_scale = 0.2; global.hitstop = 20; alarm[0] = 210; //之后实机测试计算 } } } else if dodge_phase == "DODGE" { y_spd += global.g; if is_perfect icl(oPlayerAfterImage); if y_spd > 0 { timer = 0; y_spd = 0; if is_perfect { state = state_arc_slash; set_sprite(sPlayerArcSlash); } else { state = state_dodge_ending; set_sprite(sPlayerDodgeEnding); } } } } function state_arc_slash() { if image_index == 12 { var _hb = icd(oPlayerHitboxArc); _hb.owner = id; if facing == 1 { _hb.image_xscale = 1; _hb.image_angle = 30; _hb.kb_factor_x *= 1; } else { _hb.image_xscale = -1; _hb.image_angle = -30; _hb.kb_factor_x *= -1; } } else if image_index > 12 y_spd += global.g; if animation_end() { global.time_scale = 1.0; state = state_free; } } function state_dodge_ending() { if animation_end() state = state_free; } /* function player_check_hyper() { if oInput.hyper { } */