You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TPhysics.js 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import {Trait} from "../Entity.js";
  2. import Vec2 from "../Vec2.js";
  3. let zeroVector = new Vec2(0, 0);
  4. export default class TPhysics extends Trait {
  5. constructor(entity) {
  6. super(entity, "physics");
  7. this.gravity = 40;
  8. this.groundFriction = 6;
  9. this.airFriction = 2;
  10. this.absVelocity = new Vec2();
  11. this.velocity = new Vec2();
  12. this.onGround = false;
  13. this.groundBounds = null;
  14. this.groundVelocity = null;
  15. this.oldGroundBounds = null;
  16. this.timeLastOnGround = 0;
  17. }
  18. collideTop(bounds, absVelocity) {
  19. if (this.onGround || bounds === this.oldGroundBounds)
  20. return;
  21. this.onGround = true;
  22. this.groundBounds = bounds;
  23. this.groundVelocity = absVelocity;
  24. this.velocity.x -= absVelocity.x;
  25. this.velocity.y = 0;
  26. this.entity.bounds.bottom = bounds.top;
  27. }
  28. collideWall(bounds, absVelocity) {
  29. let side = this.entity.bounds.intersectSide(bounds);
  30. if (side === "top")
  31. return this.collideTop(bounds, absVelocity);
  32. }
  33. collidePlatform(bounds, absVelocity) {
  34. let side = this.entity.bounds.intersectSide(bounds);
  35. if (side === "top")
  36. return this.collideTop(bounds, absVelocity);
  37. }
  38. update(dt) {
  39. // Gravity
  40. if (!this.onGround)
  41. this.velocity.y += this.gravity * dt;
  42. if (this.entity.has("collider")) {
  43. // Check if we're still on the same ground
  44. if (this.onGround) {
  45. let stillOnGround =
  46. (this.entity.bounds.intersects(this.groundBounds)) &&
  47. (this.entity.bounds.intersectSide(this.groundBounds) === "top");
  48. if (stillOnGround) {
  49. this.entity.bounds.bottom = this.groundBounds.top;
  50. } else {
  51. this.velocity.x += this.groundVelocity.x;
  52. this.velocity.y += this.groundVelocity.y;
  53. this.onGround = false;
  54. this.oldGroundBounds = this.groundBounds;
  55. this.groundBounds = null;
  56. this.groundVelocity = null;
  57. }
  58. }
  59. // Collide with new stuff
  60. let collider = this.entity.t.collider;
  61. collider.entities.forEach(e => {
  62. let vel;
  63. if (e.has("physics"))
  64. vel = e.t.physics.absVelocity;
  65. else
  66. vel = zeroVector;
  67. if (e.has("wall"))
  68. this.collideWall(e.bounds, vel);
  69. else if (e.has("platform"))
  70. this.collidePlatform(e.bounds, vel);
  71. });
  72. collider.structures.forEach((s, i) => {
  73. let bounds = collider.structureBounds[i];
  74. if (s.attrs.wall)
  75. this.collideWall(bounds, zeroVector);
  76. else if (s.attrs.platform)
  77. this.collidePlatform(bounds, zeroVector);
  78. });
  79. this.oldGroundBounds = null;
  80. }
  81. // Track the last time we were on the ground
  82. if (this.onGround)
  83. this.timeLastOnGround = this.entity.time;
  84. // Apply friction
  85. var fric = this.onGround ? this.groundFriction : this.airFriction;
  86. var xRatio = 1 / (1 + (dt * fric));
  87. this.velocity.x *= xRatio;
  88. }
  89. postUpdate(dt) {
  90. this.jumped = false;
  91. // Update absVelocity
  92. if (this.onGround) {
  93. this.absVelocity.x = this.velocity.x + this.groundVelocity.x;
  94. this.absVelocity.y = this.velocity.y + this.groundVelocity.y;
  95. } else {
  96. this.absVelocity.x = this.velocity.x;
  97. this.absVelocity.y = this.velocity.y;
  98. }
  99. // Move
  100. this.entity.bounds.pos.x += this.absVelocity.x * dt;
  101. this.entity.bounds.pos.y += this.absVelocity.y * dt;
  102. }
  103. }