1
0

BossHexAI.gml 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. function hex_ai()
  2. {
  3. if state != "IDLE" && global.speedrun
  4. global.speedrun_timer++;
  5. switch(state)
  6. {
  7. case "IDLE":
  8. if hp < 240
  9. {
  10. if global.speedrun
  11. {
  12. timer_active = true;
  13. global.speedrun_timer = 0;
  14. }
  15. cnt = 0;
  16. roll_init();
  17. }
  18. break;
  19. case "WAIT":
  20. cooldown -= global.time_scale;
  21. if cooldown <= 0
  22. {
  23. cooldown = 0;
  24. switch(current_attack)
  25. {
  26. case 0:
  27. cnt = 0;
  28. roll_init();
  29. break;
  30. case 1:
  31. cnt = 3;
  32. smash_init();
  33. break;
  34. case 2:
  35. cnt = 5;
  36. bounce_init();
  37. break;
  38. case 3:
  39. cnt = 2;
  40. spawn_init();
  41. break;
  42. }
  43. }
  44. break;
  45. case "ROLL":
  46. rebounce_timer--;
  47. var _roll_spd;
  48. if abs(roll_angle + roll_spd) >= 60
  49. _roll_spd = (60 - abs(roll_angle)) * sign(roll_angle);
  50. else if sign(roll_angle) == -sign(roll_angle + roll_spd)
  51. _roll_spd = -roll_angle;
  52. else
  53. _roll_spd = roll_spd;
  54. if collision_line(x, y, x + 144 * sign(-_roll_spd), y, oParentSolid, false, false) != noone
  55. && rebounce_timer <= 0
  56. {
  57. roll_spd *= -1;
  58. rebounce_timer = 10;
  59. screen_shake(20);
  60. ++cnt;
  61. if cnt == 1
  62. roll_acc *= -1;
  63. if cnt == 3
  64. {
  65. cnt = 1;
  66. smash_init();
  67. }
  68. }
  69. roll_spd += roll_acc;
  70. if abs(roll_angle) == 60 || roll_angle == 0
  71. {
  72. roll_angle = 0;
  73. y = 916;
  74. var _base_angle = (roll_spd > 0) ? 240 : 300;
  75. pivot_x = x + lengthdir_x(side_len, _base_angle);
  76. pivot_y = y + lengthdir_y(side_len, _base_angle);
  77. }
  78. roll_angle += _roll_spd;
  79. image_angle += _roll_spd;
  80. var _current_angle = point_direction(pivot_x, pivot_y, x, y);
  81. var _new_angle = _current_angle + _roll_spd;
  82. x = pivot_x + lengthdir_x(side_len, _new_angle);
  83. y = pivot_y + lengthdir_y(side_len, _new_angle);
  84. break;
  85. case "SMASH_BEGIN":
  86. x += x_spd;
  87. y += y_spd;
  88. image_angle += 0.4 * spd;
  89. if y < target_y
  90. {
  91. state = "SMASH";
  92. image_angle = round(image_angle / 60) * 60;
  93. y_spd = 20;
  94. y_acc = 1;
  95. break;
  96. }
  97. spd += acc;
  98. x_spd = lengthdir_x(spd, dir);
  99. y_spd = lengthdir_y(spd, dir);
  100. break;
  101. case "SMASH":
  102. y += y_spd;
  103. if collision_line(x, y, x, y + 108 + y_spd, oParentSolid, false, false) != noone
  104. {
  105. while collision_line(x, y, x, y + 108, oParentSolid, false, false) == noone
  106. y++;
  107. hex_var_erase();
  108. screen_shake(20);
  109. if !--cnt
  110. current_attack = hex_pick_attack();
  111. else
  112. smash_init();
  113. }
  114. y_spd += y_acc;
  115. var _x_alter = global.player.x - x
  116. x += max(4, _x_alter / 200) * sign(_x_alter);
  117. break;
  118. case "SPAWN":
  119. image_angle += abs(y_spd);
  120. y += y_spd;
  121. if y_spd == 15
  122. {
  123. image_angle -= abs(y_spd);
  124. hex_var_erase();
  125. screen_shake(20);
  126. icd(oEnemyHex, x, 998, depth + 1);
  127. if !--cnt
  128. current_attack = hex_pick_attack();
  129. else
  130. spawn_init();
  131. }
  132. y_spd += y_acc;
  133. break;
  134. case "BOUNCE":
  135. if collision_line(x, y, x + 144 * sign(x_spd), y, oParentSolid, false, false) != noone
  136. x_spd = 0;
  137. image_angle += facing * 9;
  138. x += x_spd;
  139. y += y_spd;
  140. if y_spd == 20
  141. {
  142. hex_var_erase();
  143. screen_shake(15);
  144. if !--cnt
  145. current_attack = hex_pick_attack();
  146. else
  147. bounce_init();
  148. break;
  149. }
  150. y_spd += y_acc;
  151. break;
  152. }
  153. }
  154. function roll_init()
  155. {
  156. state = "ROLL";
  157. roll_spd = 5 * sign(global.player.x - x);
  158. roll_acc = -0.1 * sign(global.player.x - x);
  159. var _base_angle = (roll_spd > 0) ? 240 : 300;
  160. pivot_x = x + lengthdir_x(side_len, _base_angle);
  161. pivot_y = y + lengthdir_y(side_len, _base_angle);
  162. }
  163. function smash_init()
  164. {
  165. state = "SMASH_BEGIN";
  166. target_x = clamp(global.player.x, 200, 1920 - 200 - 64);
  167. target_y = y - 480;
  168. dir = point_direction(x, y, target_x, target_y);
  169. spd = 15;
  170. acc = 0.3;
  171. x_spd = lengthdir_x(spd, dir);
  172. y_spd = lengthdir_y(spd, dir);
  173. }
  174. function spawn_init()
  175. {
  176. y_spd = -15;
  177. y_acc = 0.6;
  178. state = "SPAWN";
  179. }
  180. function bounce_init()
  181. {
  182. state = "BOUNCE";
  183. y_spd = -20;
  184. y_acc = 1;
  185. facing = sign(global.player.x - x);
  186. x_spd = facing * 9;
  187. }
  188. function hex_pick_attack()
  189. {
  190. hex_var_erase();
  191. cooldown = 6;
  192. state = "WAIT";
  193. // 构建候选池
  194. var pool = [];
  195. var forbidden = [];
  196. // 定义禁止规则
  197. if last_attack != -1
  198. array_push(forbidden, last_attack);
  199. if instance_number(oEnemyHex) >= 2
  200. if array_get_index(forbidden, 3) == -1
  201. array_push(forbidden, 3);
  202. // 将不在forbidden中的技能加入候选池
  203. for(var i = 0; i < 4; i++)
  204. {
  205. if array_get_index(forbidden, i) == -1
  206. array_push(pool, i);
  207. }
  208. // 从候选池随机选一个
  209. var pick = pool[irandom(array_length(pool) - 1)];
  210. last_attack = pick;
  211. return pick;
  212. }
  213. function hex_var_erase()
  214. {
  215. spd = 0;
  216. acc = 0;
  217. dir = 0;
  218. x_spd = 0;
  219. y_spd = 0;
  220. x_acc = 0;
  221. y_acc = 0;
  222. roll_spd = 0;
  223. roll_acc = 0;
  224. roll_angle = 0;
  225. y = base_y;
  226. }