function hex_ai() { switch(state) { case "IDLE": if hp < 240 { cnt = 0; roll_init(); } break; case "ROLL": rebounce_timer--; var _roll_spd; if abs(roll_angle + roll_spd) >= 60 _roll_spd = (60 - abs(roll_angle)) * sign(roll_angle); else if sign(roll_angle) == -sign(roll_angle + roll_spd) _roll_spd = -roll_angle; else _roll_spd = roll_spd; if collision_line(x, y, x + 144 * sign(-_roll_spd), y, oParentSolid, false, false) != noone && rebounce_timer <= 0 { roll_spd *= -1; rebounce_timer = 10; screen_shake(20); ++cnt; if cnt == 1 roll_acc *= -1; if cnt == 3 { cnt = 1; smash_init(); } } roll_spd += roll_acc; if abs(roll_angle) == 60 || roll_angle == 0 { roll_angle = 0; y = 916; var _base_angle = (roll_spd > 0) ? 240 : 300; pivot_x = x + lengthdir_x(side_len, _base_angle); pivot_y = y + lengthdir_y(side_len, _base_angle); } roll_angle += _roll_spd; image_angle += _roll_spd; var _current_angle = point_direction(pivot_x, pivot_y, x, y); var _new_angle = _current_angle + _roll_spd; x = pivot_x + lengthdir_x(side_len, _new_angle); y = pivot_y + lengthdir_y(side_len, _new_angle); break; case "SMASH_BEGIN": x += x_spd; y += y_spd; image_angle += 0.4 * spd; if y < target_y { state = "SMASH"; image_angle = round(image_angle / 60) * 60; y_spd = 20; y_acc = 1; break; } spd += acc; x_spd = lengthdir_x(spd, dir); y_spd = lengthdir_y(spd, dir); break; case "SMASH": y += y_spd; if collision_line(x, y, x, y + 108 + y_spd, oParentSolid, false, false) != noone { while collision_line(x, y, x, y + 108, oParentSolid, false, false) == noone y++; hex_var_erase(); screen_shake(20); if !--cnt hex_pick_attack(); else smash_init(); } y_spd += y_acc; var _x_alter = global.player.x - x x += max(4, _x_alter / 200) * sign(_x_alter); break; case "SPAWN": image_angle += abs(y_spd); y += y_spd; if y_spd == 15 { image_angle -= abs(y_spd); hex_var_erase(); screen_shake(20); icd(oEnemyHex, x, 998, depth + 1); if !--cnt hex_pick_attack(); else spawn_init(); } y_spd += y_acc; break; case "BOUNCE": if collision_line(x, y, x + 144 * sign(x_spd), y, oParentSolid, false, false) != noone x_spd = 0; image_angle += facing * 9; x += x_spd; y += y_spd; if y_spd == 20 { hex_var_erase(); screen_shake(15); if !--cnt hex_pick_attack(); else bounce_init(); break; } y_spd += y_acc; break; } } function roll_init() { state = "ROLL"; roll_spd = 5 * sign(global.player.x - x); roll_acc = -0.1 * sign(global.player.x - x); var _base_angle = (roll_spd > 0) ? 240 : 300; pivot_x = x + lengthdir_x(side_len, _base_angle); pivot_y = y + lengthdir_y(side_len, _base_angle); } function smash_init() { state = "SMASH_BEGIN"; target_x = clamp(global.player.x, 200, 1920 - 200 - 64); target_y = y - 480; dir = point_direction(x, y, target_x, target_y); spd = 15; acc = 0.3; x_spd = lengthdir_x(spd, dir); y_spd = lengthdir_y(spd, dir); } function spawn_init() { y_spd = -15; y_acc = 0.6; state = "SPAWN"; } function bounce_init() { state = "BOUNCE"; y_spd = -20; y_acc = 1; facing = sign(global.player.x - x); x_spd = facing * 9; } function hex_pick_attack() { hex_var_erase(); // 构建候选池 var pool = []; var forbidden = []; // 定义禁止规则 if last_attack != -1 array_push(forbidden, last_attack); if instance_number(oEnemyHex) >= 2 if array_get_index(forbidden, 3) == -1 array_push(forbidden, 3); // 将不在forbidden中的技能加入候选池 for (var i = 0; i < 4; i++) { if array_get_index(forbidden, i) == -1 array_push(pool, i); } // 从候选池随机选一个 var pick = pool[irandom(array_length(pool) - 1)]; last_attack = pick; switch(pick) { case 0: cnt = 0; roll_init(); break; case 1: cnt = 3; smash_init(); break; case 2: cnt = 5; bounce_init(); break; case 3: cnt = 2; spawn_init(); break; } } function hex_var_erase() { spd = 0; acc = 0; dir = 0; x_spd = 0; y_spd = 0; x_acc = 0; y_acc = 0; roll_spd = 0; roll_acc = 0; roll_angle = 0; y = base_y; }