1. package
  2. {
  3. public class Physics
  4. {
  5. public function newTrajectory(currentMoveDirection:int, hitTestResults:Object):int
  6. {
  7. if (currentMoveDirection < 1 || currentMoveDirection > 8)
  8. {
  9. throw new Error("Movement direction must be between one and eight");
  10. return 0;
  11. }
  12.  
  13. if (hitTestResults.next.A_RIGHT_HIT_RIGHT_OF_B || hitTestResults.next.A_RIGHT_HIT_LEFT_OF_B)
  14. {
  15. switch (currentMoveDirection)
  16. {
  17. case 2: return 8;
  18. case 3: return 7;
  19. case 4: return 6;
  20. }
  21. }
  22.  
  23. if (hitTestResults.next.A_LEFT_HIT_RIGHT_OF_B || hitTestResults.next.A_LEFT_HIT_LEFT_OF_B)
  24. {
  25. switch (currentMoveDirection)
  26. {
  27. case 8: return 2;
  28. case 7: return 3;
  29. case 6: return 4;
  30. }
  31. }
  32.  
  33. if (hitTestResults.next.A_TOP_HIT_TOP_OF_B || hitTestResults.next.A_TOP_HIT_BOTTOM_OF_B)
  34. {
  35. switch (currentMoveDirection)
  36. {
  37. case 1: return 5;
  38. case 2: return 4;
  39. case 8: return 6;
  40. }
  41. }
  42.  
  43. if (hitTestResults.next.A_BOTTOM_HIT_TOP_OF_B || hitTestResults.next.A_BOTTOM_HIT_BOTTOM_OF_B)
  44. {
  45. switch (currentMoveDirection)
  46. {
  47. case 5: return 1;
  48. case 4: return 2;
  49. case 6: return 8;
  50. }
  51. }
  52.  
  53. return 1;
  54. }
  55.  
  56. public function hitTest(a:Object, b:Object):Object
  57. {
  58. /*
  59. * Template:
  60. * a.x
  61. * a.y
  62. * a.width
  63. * a.height
  64. *
  65. * Optional:
  66. * a.xSpeed
  67. * a.ySpeed
  68. * */
  69.  
  70. //An object with no width or height cannot properly be hitTested.
  71. //So end the function if any of them are equal to zero.
  72. if (a.width == 0 || a.height == 0 || b.width == 0 || b.height == 0)
  73. {
  74. throw new Error("Objects cannot have zero width or height");
  75. return null;
  76. }
  77.  
  78. a.xMax = a.x + a.width; //The coordinate for the top-right corner of the object.
  79. a.yMax = a.y + a.height; //The coordinate for the bottom-left corner of the object.
  80. a.xSpeed = (a.xSpeed > 0) ? a.xSpeed : 0; //If a.xSpeed is not set, then set it to zero. Otherwise do not change its value.
  81. a.ySpeed = (a.ySpeed > 0) ? a.ySpeed : 0;
  82. a.xNext = a.x + a.xSpeed; //What x will be equal to in the next iteration for this object.
  83. a.yNext = a.y + a.ySpeed;
  84. a.xMaxNext = a.xMax + a.xSpeed;
  85. a.yMaxNext = a.yMax + a.ySpeed;
  86.  
  87. b.xMax = b.x + b.width;
  88. b.yMax = b.y + b.height;
  89. b.xSpeed = (b.xSpeed > 0) ? b.xSpeed : 0;
  90. b.ySpeed = (b.ySpeed > 0) ? b.ySpeed : 0;
  91. b.xNext = b.x + b.xSpeed;
  92. b.yNext = b.y + b.ySpeed;
  93. b.xMaxNext = b.xMax + b.xSpeed;
  94. b.yMaxNext = b.yMax + b.ySpeed;
  95.  
  96. var results:Object = new Object();
  97. results.now = new Object();
  98. results.next = new Object();
  99.  
  100. //State info for the current iteration.
  101. results.now.A_LEFT_OF_B = false;
  102. results.now.A_RIGHT_OF_B = false;
  103. results.now.A_ABOVE_B = false;
  104. results.now.A_BELOW_B = false;
  105. results.now.A_TOUCHING_B = false;
  106. results.now.A_INSIDE_B = false;
  107. results.now.A_RIGHT_HIT_RIGHT_OF_B = false;
  108. results.now.A_RIGHT_HIT_LEFT_OF_B = false;
  109. results.now.A_LEFT_HIT_RIGHT_OF_B = false;
  110. results.now.A_LEFT_HIT_LEFT_OF_B = false;
  111. results.now.A_TOP_HIT_TOP_OF_B = false;
  112. results.now.A_TOP_HIT_BOTTOM_OF_B = false;
  113. results.now.A_BOTTOM_HIT_TOP_OF_B = false;
  114. results.now.A_BOTTOM_HIT_BOTTOM_OF_B = false;
  115. results.now.A_TRCORNER_HIT_TRCORNER_OF_B = false;
  116. results.now.A_TRCORNER_HIT_BLCORNER_OF_B = false;
  117. results.now.A_BLCORNER_HIT_TRCORNER_OF_B = false;
  118. results.now.A_BLCORNER_HIT_BLCORNER_OF_B = false;
  119. results.now.A_TLCORNER_HIT_TLCORNER_OF_B = false;
  120. results.now.A_TLCORNER_HIT_BRCORNER_OF_B = false;
  121. results.now.A_BRCORNER_HIT_TLCORNER_OF_B = false;
  122. results.now.A_BRCORNER_HIT_BRCORNER_OF_B = false;
  123.  
  124. //State info for the very next iteration.
  125. results.next.A_LEFT_OF_B = false;
  126. results.next.A_RIGHT_OF_B = false;
  127. results.next.A_ABOVE_B = false;
  128. results.next.A_BELOW_B = false;
  129. results.next.A_TOUCHING_B = false;
  130. results.next.A_INSIDE_B = false;
  131. results.next.A_RIGHT_HIT_RIGHT_OF_B = false;
  132. results.next.A_RIGHT_HIT_LEFT_OF_B = false;
  133. results.next.A_LEFT_HIT_RIGHT_OF_B = false;
  134. results.next.A_LEFT_HIT_LEFT_OF_B = false;
  135. results.next.A_TOP_HIT_TOP_OF_B = false;
  136. results.next.A_TOP_HIT_BOTTOM_OF_B = false;
  137. results.next.A_BOTTOM_HIT_TOP_OF_B = false;
  138. results.next.A_BOTTOM_HIT_BOTTOM_OF_B = false;
  139. results.next.A_TRCORNER_HIT_TRCORNER_OF_B = false;
  140. results.next.A_TRCORNER_HIT_BLCORNER_OF_B = false;
  141. results.next.A_BLCORNER_HIT_TRCORNER_OF_B = false;
  142. results.next.A_BLCORNER_HIT_BLCORNER_OF_B = false;
  143. results.next.A_TLCORNER_HIT_TLCORNER_OF_B = false;
  144. results.next.A_TLCORNER_HIT_BRCORNER_OF_B = false;
  145. results.next.A_BRCORNER_HIT_TLCORNER_OF_B = false;
  146. results.next.A_BRCORNER_HIT_BRCORNER_OF_B = false;
  147.  
  148. /////////////
  149. // N O W //
  150. ////////////
  151.  
  152. //Is objA to the left of objB?
  153. if ( a.xMax < b.x )
  154. results.now.A_LEFTOF_B = true;
  155.  
  156. //Is objA to the right of objB?
  157. if (a.x > b.xMax)
  158. results.now.A_RIGHTOF_B = true;
  159.  
  160. //Is objA above objB?
  161. if ( a.yMax < b.y)
  162. results.now.A_ABOVE_B = true;
  163.  
  164. //Is objA below objB?
  165. if ( a.y > b.yMax )
  166. results.now.A_BELOW_B = true;
  167.  
  168. //Is any part of objA "inside" of objB? (i.e. are they touching)
  169. if (results.now.A_LEFT_OF_B == false && results.now.A_RIGHT_OF_B == false && results.now.A_ABOVE_B == false && results.now.A_BELOW_B == false)
  170. results.now.A_TOUCHING_B = true;
  171.  
  172. //Did objA just touch the right side of objB, or go past it?
  173. if ( ( a.x <= b.xMax && a.xMax > b.xMax ) && results.now.A_ABOVE_B == false && results.now.A_BELOW_B == false && results.now.A_LEFT_OF_B == false)
  174. results.now.A_LEFT_HIT_RIGHT_OF_B = true;
  175. if ( ( a.x < b.xMax && a.xMax >= b.xMax ) && results.now.A_ABOVE_B == false && results.now.A_BELOW_B == false && results.now.A_LEFT_OF_B == false)
  176. results.now.A_RIGHT_HIT_RIGHT_OF_B = true;
  177.  
  178. //Did objA just touch the left side of objB, or go past it?
  179. if ( ( a.xMax >= b.x && a.x < b.x ) && results.now.A_ABOVE_B == false && results.now.A_BELOW_B == false && results.now.A_LEFT_OF_B == false)
  180. results.now.A_RIGHT_HIT_LEFT_OF_B = true;
  181. if ( ( a.xMax > b.x && a.x <= b.x ) && results.now.A_ABOVE_B == false && results.now.A_BELOW_B == false && results.now.A_LEFT_OF_B == false)
  182. results.now.A_LEFT_HIT_LEFT_OF_B = true;
  183.  
  184. //Did objA just touch the top of objB, or go past it?
  185. if ( ( a.yMax >= b.y && a.y < b.y) && results.now.A_LEFT_OF_B == false && results.now.A_RIGHT_OF_B == false && results.now.A_BELOW_B == false )
  186. results.now.A_BOTTOM_HIT_TOP_OF_B = true;
  187. if ( ( a.yMax > b.y && a.y <= b.y) && results.now.A_LEFT_OF_B == false && results.now.A_RIGHT_OF_B == false && results.now.A_BELOW_B == false )
  188. results.now.A_TOP_HIT_TOP_OF_B = true;
  189.  
  190. //Did objA just touch the top of objB, or go past it?
  191. if ( ( a.y <= b.yMax && a.yMax > b.yMax ) && results.now.A_LEFT_OF_B == false && results.now.A_RIGHT_OF_B == false && results.now.A_BELOW_B == false )
  192. results.now.A_TOP_HIT_BOTTOM_OF_B = true;
  193. if ( ( a.y < b.yMax && a.yMax >= b.yMax ) && results.now.A_LEFT_OF_B == false && results.now.A_RIGHT_OF_B == false && results.now.A_BELOW_B == false )
  194. results.now.A_BOTTOM_HIT_BOTTOM_OF_B = true;
  195.  
  196. //Is objA inside of objB?
  197. if ( results.now.A_TOUCHING_B &&
  198. results.now.A_LEFT_HIT_RIGHT_OF_B == false &&
  199. results.now.A_RIGHT_HIT_RIGHT_OF_B == false &&
  200. results.now.A_RIGHT_HIT_LEFT_OF_B == false &&
  201. results.now.A_LEFT_HIT_LEFT_OF_B == false &&
  202. results.now.A_BOTTOM_HIT_TOP_OF_B == false &&
  203. results.now.A_TOP_HIT_TOP_OF_B == false &&
  204. results.now.A_TOP_HIT_BOTTOM_OF_B == false &&
  205. results.now.A_BOTTOM_HIT_BOTTOM_OF_B == false)
  206. results.now.A_INSIDE_B = true;
  207.  
  208. ///////////////
  209. // N E X T //
  210. //////////////
  211.  
  212. //Will objA be to the right of objB?
  213. if (a.xNext > b.xMaxNext)
  214. results.next.A_RIGHT_OF_B = true;
  215.  
  216. //Will objA be to the left of objB?
  217. if (a.xMaxNext < b.xNext)
  218. results.next.A_LEFT_OF_B = true;
  219.  
  220. //Will objA be above objB?
  221. if (a.yMaxNext < b.yNext)
  222. results.next.A_ABOVE_B = true;
  223.  
  224. //Will objA be below objB?
  225. if (a.yNext > b.yMaxNext)
  226. results.next.A_BELOW_B = true;
  227.  
  228. //Will any part of objA be "inside" of objB? (i.e. will they be touching)
  229. if (results.next.A_LEFT_OF_B == false && results.next.A_RIGHT_OF_B == false && results.next.A_ABOVE_B == false && results.next.A_BELOW_B == false)
  230. results.next.A_TOUCHING_B = true;
  231.  
  232. //Did objA just touch the right side of objB, or go past it?
  233. if ( ( a.xNext <= b.xMaxNext && a.xMaxNext > b.xMaxNext ) && results.next.A_ABOVE_B == false && results.next.A_BELOW_B == false && results.next.A_LEFT_OF_B == false)
  234. results.next.A_LEFT_HIT_RIGHT_OF_B = true;
  235. if ( ( a.x < b.xMaxNext && a.xMaxNext >= b.xMaxNext ) && results.next.A_ABOVE_B == false && results.next.A_BELOW_B == false && results.next.A_LEFT_OF_B == false)
  236. results.next.A_RIGHT_HIT_RIGHT_OF_B = true;
  237.  
  238. //Did objA just touch the left side of objB, or go past it?
  239. if ( ( a.xMaxNext >= b.xNext && a.xNext < b.xNext ) && results.next.A_ABOVE_B == false && results.next.A_BELOW_B == false && results.next.A_LEFT_OF_B == false)
  240. results.next.A_RIGHT_HIT_LEFT_OF_B = true;
  241. if ( ( a.xMaxNext > b.xNext && a.xNext <= b.xNext ) && results.next.A_ABOVE_B == false && results.next.A_BELOW_B == false && results.next.A_LEFT_OF_B == false)
  242. results.next.A_LEFT_HIT_LEFT_OF_B = true;
  243.  
  244. //Did objA just touch the top of objB, or go past it?
  245. if ( ( a.yMaxNext >= b.yNext && a.yNext < b.yNext ) && results.next.A_LEFT_OF_B == false && results.next.A_RIGHT_OF_B == false && results.next.A_BELOW_B == false )
  246. results.next.A_BOTTOM_HIT_TOP_OF_B = true;
  247. if ( ( a.yMaxNext > b.yNext && a.yNext <= b.yNext ) && results.next.A_LEFT_OF_B == false && results.next.A_RIGHT_OF_B == false && results.next.A_BELOW_B == false )
  248. results.next.A_TOP_HIT_TOP_OF_B = true;
  249.  
  250. //Did objA just touch the top of objB, or go past it?
  251. if ( ( a.yNext <= b.yMaxNext && a.yMaxNext > b.yMaxNext ) && results.next.A_LEFT_OF_B == false && results.next.A_RIGHT_OF_B == false && results.next.A_BELOW_B == false )
  252. results.next.A_TOP_HIT_BOTTOM_OF_B = true;
  253. if ( ( a.yNext < b.yMaxNext && a.yMaxNext >= b.yMaxNext ) && results.next.A_LEFT_OF_B == false && results.next.A_RIGHT_OF_B == false && results.next.A_BELOW_B == false )
  254. results.next.A_BOTTOM_HIT_BOTTOM_OF_B = true;
  255.  
  256. //Will objA be inside of objB?
  257. if ( results.next.A_TOUCHING_B &&
  258. results.next.A_LEFT_HIT_RIGHT_OF_B == false &&
  259. results.next.A_RIGHT_HIT_RIGHT_OF_B == false &&
  260. results.next.A_RIGHT_HIT_LEFT_OF_B == false &&
  261. results.next.A_LEFT_HIT_LEFT_OF_B == false &&
  262. results.next.A_BOTTOM_HIT_TOP_OF_B == false &&
  263. results.next.A_TOP_HIT_TOP_OF_B == false &&
  264. results.next.A_TOP_HIT_BOTTOM_OF_B == false &&
  265. results.next.A_BOTTOM_HIT_BOTTOM_OF_B == false)
  266. results.next.A_INSIDE_B = true;
  267.  
  268. return results;
  269. }
  270. }
  271. }