BossHexAI.gml 4.8 KB

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