bird.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import {ffnet} from "./ffnet.js";
  2. export const bird = (function() {
  3. const _BIRD_POS_X = 50;
  4. class _FlappyBirdObject {
  5. constructor(scene) {
  6. this._scene = scene;
  7. this._sprite = scene.add.sprite(_BIRD_POS_X, 100, 'bird');
  8. this._spriteTint = scene.add.sprite(_BIRD_POS_X, 100, 'bird-colour');
  9. this._velocity = 0;
  10. this._dead = false;
  11. }
  12. Destroy() {
  13. this._sprite.destroy();
  14. }
  15. Update(params) {
  16. if (this._dead) {
  17. return;
  18. }
  19. this._ApplyGravity(params.timeElapsed)
  20. this._velocity = Math.min(Math.max(
  21. this._velocity, this._config.max_upwards_velocity), this._config.terminal_velocity);
  22. this._sprite.y += this._velocity * params.timeElapsed;
  23. this._spriteTint.y += this._velocity * params.timeElapsed;
  24. const v = new Phaser.Math.Vector2(
  25. -1 * this._config.treadmill_speed * params.timeElapsed, 0);
  26. v.add(new Phaser.Math.Vector2(0, this._velocity));
  27. v.normalize();
  28. const rad = Math.atan2(v.y, v.x);
  29. const deg = (180.0 / Math.PI) * rad;
  30. this._sprite.angle = deg * 0.75;
  31. this._spriteTint.angle = deg * 0.75;
  32. }
  33. get Dead() {
  34. return this._dead;
  35. }
  36. set Dead(d) {
  37. this._dead = d;
  38. this._scene.tweens.add({
  39. targets: this._sprite,
  40. props: {
  41. alpha: { value: 0.0, duration: 500, ease: 'Sine.easeInOut' },
  42. },
  43. });
  44. this._scene.tweens.add({
  45. targets: this._spriteTint,
  46. props: {
  47. alpha: { value: 0.0, duration: 500, ease: 'Sine.easeInOut' },
  48. },
  49. });
  50. }
  51. set Alpha(a) {
  52. this._sprite.alpha = a;
  53. this._spriteTint.alpha = a;
  54. }
  55. get Bounds() {
  56. return this._sprite.getBounds();
  57. }
  58. _ApplyGravity(timeElapsed) {
  59. this._velocity += this._config.gravity * timeElapsed;
  60. }
  61. }
  62. class FlappyBird_Manual extends _FlappyBirdObject {
  63. constructor(scene) {
  64. super(scene);
  65. this._frameInputs = [];
  66. }
  67. Update(params) {
  68. this._HandleInput(params);
  69. super.Update(params);
  70. }
  71. _HandleInput(params) {
  72. if (!params.keys.up) {
  73. return;
  74. }
  75. this._velocity += _UPWARDS_ACCELERATION;
  76. }
  77. }
  78. class FlappyBird_NeuralNet extends _FlappyBirdObject {
  79. constructor(config) {
  80. super(config.scene);
  81. this._model = new ffnet.FFNeuralNetwork(config.pop_params.shapes);
  82. this._model.fromArray(config.pop_entity.genotype);
  83. this._populationEntity = config.pop_entity;
  84. this._spriteTint.setTint(config.pop_params.tint);
  85. this._config = config;
  86. }
  87. Update(params) {
  88. function _PipeParams(bird, pipe) {
  89. const distToPipe = (
  90. (pipe.X + pipe.Width) - bird.Bounds.left) / bird._config.config_width;
  91. const distToPipeB = (
  92. (pipe._sprite1.y - bird.Bounds.bottom) / bird._config.config_height) * 0.5 + 0.5;
  93. const distToPipeT = (
  94. (pipe._sprite2.y - bird.Bounds.top) / bird._config.config_height) * 0.5 + 0.5;
  95. return [distToPipe, distToPipeB, distToPipeT];
  96. }
  97. function _Params(bird, pipes) {
  98. const inputs = pipes.map(p => _PipeParams(bird, p)).flat();
  99. inputs.push((bird._velocity / bird._config.gravity) * 0.5 + 0.5);
  100. return inputs;
  101. }
  102. const inputs = _Params(this, params.nearestPipes);
  103. const decision = this._model.predict(inputs);
  104. if (decision > 0.5) {
  105. this._velocity += this._config.acceleration;
  106. }
  107. super.Update(params);
  108. if (!this.Dead) {
  109. this._populationEntity.fitness += params.timeElapsed;
  110. }
  111. }
  112. }
  113. return {
  114. FlappyBird_Manual: FlappyBird_Manual,
  115. FlappyBird_NeuralNet: FlappyBird_NeuralNet
  116. };
  117. })();