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_state_update() { current_attacker = instance_place(x, y, oEnemyHitbox); 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 state_free() { y_spd += global.g; if _on_wall != 0 && y_spd > 0 y_spd = min(y_spd, 3); /*下面是动画与视觉*/ var _current_sprite = sprite_index; image_speed = 1; if _move_dir != 0 { facing = _move_dir; if _on_ground sprite_index = sPlayerWalk; } else sprite_index = sPlayerIdle; if !_on_ground { image_speed = 0; if _on_wall == facing sprite_index = sPlayerWall; else { sprite_index = sPlayerJump; image_index = (y_spd < 0) ? 0 : 1; } } if _current_sprite != sprite_index image_index = 0; /**/ player_check_dodge_y(); if state == player_dodge_y 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 !_on_ground jump_cnt = max(jump_cnt, 1); if animation_end() { state = state_free; player_check_attack(); } player_check_dodge_y(); } function state_attack() { player_check_movement(); player_check_jump(); y_spd += global.g; if image_index == 1 { var _up = oInput._up; var _down = oInput._down; var _hb = icd(oPlayerHitboxRec); _hb.owner = id; var _base = 2; if _up { _hb.y -= 64; _hb.image_xscale = 72 / _base; _hb.image_yscale = 224 / _base; _hb.kb_dir_x = 0; _hb.kb_dir_y = -1; } else if _down && !_on_ground { _hb.y += 64; _hb.image_xscale = 72 / _base; _hb.image_yscale = 224 / _base; _hb.kb_dir_x = 0; _hb.kb_dir_y = 1; } else { _hb.x += 72 * facing; _hb.image_xscale = 144 / _base * facing; _hb.image_yscale = 96 / _base; _hb.kb_dir_x = facing; _hb.kb_dir_y = 0; } //攻击碰撞箱跟随 _hb.x_offset = _hb.x - x; _hb.y_offset = _hb.y - y; } // 冲刺预输入 & 预读帧数 if image_index >= 2 { with(oPlayerHitboxRec) { instance_destroy(); } player_check_dash(); } // 攻击后摇结束 if animation_end() state = state_free; } function player_check_dash() { if dash_buffer > 0 && dash_cooldown <= 0 && can_dash { dash_buffer = 0; state = state_dash; sprite_index = sPlayerDash; image_index = 0; image_speed = 1; 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_attacked() { if current_attacker == noone || is_invincible || state == player_dodge_y 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 = player_hitstun; sprite_index = sPlayerHitstun; image_speed = 1; image_index = 0; //effects } 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 = 12; 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; sprite_index = sPlayerAttack; image_speed = 1; image_index = 0; } } function player_perform_pogo() { y_spd = jump_spd * 0.8; jump_cnt = 1; can_dash = true; coyote_timer = 0; //hitstop = 3; } function player_perform_recoil() { x_spd = -image_xscale * 3; move_lock_timer = 6; //hitstop = 3; } function player_hitstun() { x_spd = lerp(x_spd, 0, 0.1); y_spd += global.g; if animation_end() state = state_free; } function player_check_dodge_y() { if (oInput._down || oInput._up) && _on_ground && (oInput._dash || state == state_dash) { state = player_dodge_y; sprite_index = sPlayerDodgeYWait; image_index = 0; image_speed = 1; dodge_phase = "WAIT"; dodge_timer = 0; marked_target = noone; is_marked = false; is_perfect = false; } } function player_dodge_y() { if dodge_phase == "WAIT" { x_spd = 0; if !is_marked player_check_mark_y(); if current_attacker != noone || animation_end() { y_spd = jump_spd; dodge_phase = "DODGE"; sprite_index = sPlayerDodgeYDodge; image_index = 0; 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 = player_arc_slash; sprite_index = sPlayerArcSlash; image_index = 0; image_speed = 1; } else { state = player_dodge_y_ending; sprite_index = sPlayerDodgeYEnding; image_index = 0; } } } } function player_arc_slash() { if image_index == 7 { var _hb = icd(oPlayerHitboxArc); _hb.owner = id; if facing == 1 _hb.image_xscale = 1; else _hb.image_xscale = -1; } else if animation_end() { global.time_scale = 1.0; state = state_free; } } function player_dodge_y_ending() { if animation_end() state = state_free; } function player_check_mark_y() { // 定义矩形相对于玩家中心的偏移和尺寸 var _width = 2 * (72 + 16); var _height = 64; var _x_offset = facing * (36 + 16); var _y_offset = 0; // 计算出矩形的四个边界坐标 var x1 = x + _x_offset - (_width / 2); var y1 = y + _y_offset; var x2 = x + _x_offset + (_width / 2); var y2 = y + _y_offset + _height; // 将这些坐标存入变量 debug_hitbox_x1 = x1; debug_hitbox_y1 = y1; debug_hitbox_x2 = x2; debug_hitbox_y2 = y2; // 执行核心碰撞检测 var _target = collision_rectangle(x1, y1, x2, y2, oParentEnemy, false, true); if _target != noone { is_marked = true; marked_target = _target; // animation // instance_create_layer(_target.x, _target.y, "FX", oFx_Marked); } }