Advertisement
Guest User

Untitled

a guest
Aug 19th, 2019
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.83 KB | None | 0 0
  1. 'use strict';
  2.  
  3. const getCollision=(objectCommon,obstacleCommon)=>{
  4. let object,obstacle
  5.  
  6. if (objectCommon instanceof Hitbox || StaticHitbox){
  7. object=objectCommon.hitbox
  8. }else if (objectCommon instanceof AABB || CircleHitbox){
  9. object=objectCommon
  10. }
  11.  
  12. if (obstacleCommon instanceof Hitbox || StaticHitbox){
  13. obstacle=obstacleCommon.hitbox
  14. }else if (obstacleCommon instanceof AABB || CircleHitbox){
  15. obstacle=obstacleCommon
  16. }
  17.  
  18. const minMaxProjection = (axis, object) => {
  19. let minPr, maxPr;
  20. minPr = maxPr = object.vertices[0].vectorProjection(axis);
  21. for (let i = 1; i < 4; i++) {
  22. let projection = object.vertices[i].vectorProjection(axis);
  23. if (projection > maxPr) {
  24. maxPr = projection;
  25. } else if (projection < minPr) {
  26. minPr = projection;
  27. }
  28. }
  29. return {
  30. min: minPr,
  31. max: maxPr
  32. };
  33. };
  34.  
  35. const overlap = (pr1, pr2) => {
  36. let max, min;
  37.  
  38. if (pr1.max < pr2.max) {
  39. max = pr1.max;
  40. min = pr2.min;
  41. } else {
  42. max = pr2.max;
  43. min = pr1.min;
  44. }
  45. return min - max;
  46. };
  47.  
  48. const AABBvsAABB=(object,obstacle)=> {
  49. let thisPr1 = minMaxProjection(object.firstAxis, object);
  50. let thisPr2 = minMaxProjection(object.secondAxis, object);
  51. let objPr1 = minMaxProjection(object.firstAxis, obstacle);
  52. let objPr2 = minMaxProjection(object.secondAxis, obstacle);
  53.  
  54. let secThisPr1 = minMaxProjection(obstacle.firstAxis, object);
  55. let secThisPr2 = minMaxProjection(obstacle.secondAxis, object);
  56. let secObjPr1 = minMaxProjection(obstacle.firstAxis, obstacle);
  57. let secObjPr2 = minMaxProjection(obstacle.secondAxis, obstacle);
  58.  
  59. let dx, dy, dX, dY;
  60.  
  61. if ((dx = overlap(thisPr1, objPr1)) < 0 && (dy = overlap(thisPr2, objPr2)) < 0
  62. && (dX = overlap(secThisPr1, secObjPr1)) < 0 && (dY = overlap(secThisPr2, secObjPr2)) < 0) {
  63.  
  64. const getMin = (dx, dy, firstAxis, secondAxis) => {
  65. let depth, axis;
  66. if (dx < dy) {
  67. depth = dy;
  68. axis = new Vector2d(secondAxis);
  69. } else {
  70. depth = dx;
  71. axis = new Vector2d(firstAxis);
  72. }
  73. return {
  74. depth: depth,
  75. axis: axis
  76. };
  77. };
  78.  
  79. let thisMin = getMin(dx, dy, object.firstAxis, object.secondAxis);
  80. let objMin = getMin(dX, dY, obstacle.firstAxis, obstacle.secondAxis);
  81. let res = getMin(thisMin.depth, objMin.depth, thisMin.axis, objMin.axis);
  82.  
  83. let centre_to_centre = obstacle.centre.sub(object.centre, new Vector2d());
  84.  
  85. if (centre_to_centre.vectorProjection(res.axis) < 0) res.axis.mul(-1);
  86.  
  87. return new Collision(res.axis.normalize().mul(res.depth), obstacle);
  88. }
  89. return null
  90. }
  91.  
  92. const AABBvsCircle=(object,obstacle)=> {
  93. let axis = obstacle.centre.sub(object.centre, new Vector2d());
  94. let thisProjection = minMaxProjection(axis, object);
  95.  
  96. let centreProjection = obstacle.centre.vectorProjection(axis);
  97.  
  98. let struct = {
  99. min: centreProjection - obstacle.radius,
  100. max: centreProjection + obstacle.radius
  101. };
  102.  
  103. let depth;
  104.  
  105. if ((depth = overlap(thisProjection, struct)) < 0) {
  106. return new Collision(axis.normalize().mul(depth), obstacle);
  107. }
  108. return null
  109. }
  110. if (object instanceof AABB) {
  111. if (obstacle instanceof AABB) {
  112. return AABBvsAABB(object,obstacle)
  113. }else if (obstacle instanceof CircleHitbox){
  114. return AABBvsCircle(object,obstacle)
  115. }
  116. }else if (object instanceof CircleHitbox){
  117. if (obstacle instanceof AABB){
  118. let collision=AABBvsCircle(obstacle,object)
  119. if (collision){
  120. collision.distance.mul(-1)
  121. collision.obstacle=obstacle
  122. }
  123. return collision
  124. }else if (obstacle instanceof CircleHitbox){
  125. let axis=object.centre.sub(obstacle.centre,new Vector2d());
  126. let dist=axis.length();
  127. if (obstacle.radius+object.radius>dist){
  128. return new Collision(axis.normalize().mul(object.radius+obstacle.radius-dist),obstacle);
  129. }
  130. return null
  131. }
  132. }
  133. return null;
  134. }
  135.  
  136. class AABB {
  137. constructor(centre,vertices,id=Game.getUniqId()){
  138. this.centre=centre;
  139. this.vertices=vertices;
  140. let firstSide=this.vertices[1].sub(this.vertices[0],new Vector2d());
  141. let secondSide=this.vertices[2].sub(this.vertices[1],new Vector2d());
  142. this.firstAxis=firstSide.normal();
  143. this.secondAxis=secondSide.normal();
  144. this.id=id;
  145. }
  146.  
  147. getCollision(object) {
  148. const minMaxProjection = (axis, object) => {
  149. let minPr, maxPr;
  150. minPr = maxPr = object.vertices[0].vectorProjection(axis);
  151. for (let i = 1; i < 4; i++) {
  152. let projection = object.vertices[i].vectorProjection(axis);
  153. if (projection > maxPr) {
  154. maxPr = projection;
  155. } else if (projection < minPr) {
  156. minPr = projection;
  157. }
  158. }
  159. return {
  160. min: minPr,
  161. max: maxPr
  162. };
  163. };
  164.  
  165. const overlap = (pr1, pr2) => {
  166. let max, min;
  167.  
  168. if (pr1.max < pr2.max) {
  169. max = pr1.max;
  170. min = pr2.min;
  171. } else {
  172. max = pr2.max;
  173. min = pr1.min;
  174. }
  175. return min - max;
  176. };
  177.  
  178. if (object instanceof AABB) {
  179.  
  180. let thisPr1 = minMaxProjection(this.firstAxis, this);
  181. let thisPr2 = minMaxProjection(this.secondAxis, this);
  182. let objPr1 = minMaxProjection(this.firstAxis, object);
  183. let objPr2 = minMaxProjection(this.secondAxis, object);
  184.  
  185. let secThisPr1 = minMaxProjection(object.firstAxis, this);
  186. let secThisPr2 = minMaxProjection(object.secondAxis, this);
  187. let secObjPr1 = minMaxProjection(object.firstAxis, object);
  188. let secObjPr2 = minMaxProjection(object.secondAxis, object);
  189.  
  190. let dx, dy,dX,dY;
  191.  
  192. if ((dx = overlap(thisPr1, objPr1)) < 0 && (dy = overlap(thisPr2, objPr2)) < 0
  193. && (dX=overlap(secThisPr1, secObjPr1))< 0 && (dY=overlap(secThisPr2, secObjPr2)) < 0) {
  194.  
  195. const getMin=(dx,dy,firstAxis,secondAxis)=>{
  196. let depth, axis;
  197. if (dx < dy) {
  198. depth = dy;
  199. axis = new Vector2d(secondAxis);
  200. } else {
  201. depth = dx;
  202. axis = new Vector2d(firstAxis);
  203. }
  204. return {
  205. depth:depth,
  206. axis:axis
  207. };
  208. };
  209.  
  210. let thisMin=getMin(dx,dy,this.firstAxis,this.secondAxis);
  211. let objMin=getMin(dX,dY,object.firstAxis,object.secondAxis);
  212. let res=getMin(thisMin.depth,objMin.depth,thisMin.axis,objMin.axis);
  213.  
  214. let centre_to_centre = object.centre.sub(this.centre, new Vector2d());
  215.  
  216. if (centre_to_centre.vectorProjection(res.axis) < 0) res.axis.mul(-1);
  217.  
  218. return new Collision(res.axis.normalize().mul(res.depth),object);
  219. }
  220. }else {
  221. let axis=object.centre.sub(this.centre,new Vector2d());
  222. let thisProjection=minMaxProjection(axis,this);
  223.  
  224. let centreProjection=object.centre.vectorProjection(axis);
  225.  
  226. let struct={
  227. min:centreProjection-object.radius,
  228. max:centreProjection+object.radius
  229. };
  230.  
  231. let depth;
  232.  
  233. if ((depth=overlap(thisProjection,struct))<0){
  234. return new Collision(axis.normalize().mul(depth),object);
  235. }
  236. }
  237. return null;
  238. }
  239.  
  240. changePosition(newCentre){
  241. let delta=newCentre.sub(this.centre,new Vector2d());
  242. this.centre.set(newCentre);
  243. for (let vertex of this.vertices){
  244. vertex.add(delta);
  245. }
  246. }
  247.  
  248. correctPosition(collision){
  249. this.changePosition(this.centre.add(collision.distance,new Vector2d()));
  250. }
  251.  
  252. getMinMax(x_or_y){
  253. let min,max;
  254. min=max=this.vertices[0][x_or_y];
  255. for (let i=1;i<4;i++){
  256. if (this.vertices[i][x_or_y]>max){
  257. max=this.vertices[i][x_or_y]
  258. }
  259. if (this.vertices[i][x_or_y]<min){
  260. min=this.vertices[i][x_or_y];
  261. }
  262. }
  263. return {
  264. max:max,
  265. min:min
  266. }
  267. }
  268.  
  269. /**
  270. * @param {AABB} object
  271. * @return {boolean}
  272. */
  273. equals(object){
  274. return object instanceof AABB && this.id===object.id;
  275. }
  276.  
  277. setId(id){
  278. this.id=id;
  279. return this;
  280. }
  281. }
  282.  
  283. class CircleHitbox {
  284. constructor(centre,radius,id=Game.getUniqId()){
  285. this.radius=radius;
  286. this.centre=centre;
  287. this.id=id;
  288. }
  289.  
  290. getCollision(object){
  291. if (object instanceof AABB){
  292. let collision=object.getCollision(this);
  293. if (collision){
  294. collision.distance.mul(-1);
  295. collision.obstacle=object
  296. return collision;
  297. }
  298. }else {
  299. let axis=this.centre.sub(object.centre,new Vector2d());
  300. let dist=axis.length();
  301. if (this.radius+object.radius>dist){
  302. return new Collision(axis.normalize().mul(object.radius+this.radius-dist),object);
  303. }
  304. }
  305. return null;
  306. }
  307.  
  308. changePosition(newCentre){
  309. this.centre.set(newCentre);
  310. }
  311. correctPosition(collision){
  312. this.changePosition(this.centre.add(collision.distance,new Vector2d()));
  313. }
  314.  
  315. getMinMax(x_or_y){
  316. return {
  317. max:this.centre[x_or_y]+this.radius,
  318. min:this.centre[x_or_y]-this.radius
  319. }
  320. }
  321.  
  322. /**
  323. * @param {CircleHitbox} object
  324. * @return {boolean}
  325. */
  326. equals(object){
  327. return object instanceof CircleHitbox
  328. && this.id===object.id;
  329. }
  330.  
  331. setId(id){
  332. this.id=id;
  333. return this;
  334. }
  335. }
  336.  
  337. class Collision{
  338. constructor(dist,obstacle){
  339. this.distance=dist
  340. this.obstacle=obstacle
  341. }
  342. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement