Как сделать радномное изменение X

Я создал class Butterfly, который создаёт бабочку в body. Реализовал простое движение бабочки наверх, но не понимаю как сделать так, чтобы бабочка летала влево-вправо случайно. Cделал функцию:

moveRandomLeftOrRight() {
    const hundred = parseInt(this.x/100);

    if (hundred % 2) {
        const randInt = getRandomInt(0, 1);
        if (randInt) {
            this.moveRight();
        } else {
            this.moveLeft();
        }
    } else {
        this.moveRight();
    }
}

Я не понимаю как написать функцию так, чтобы бабочка рандомно летала по x, как будто это настоящая бабочка.
Я думаю это сделать так: каждый 100 пикселей по X выбирать, случайно куда пойти, влево или вправо и идти эти 100 пикселей, и при достижении сотни пикселей рандомно выбирать, влево или вправо пойти

class Butterfly {
  constructor(srcButterfly) {
    const that = this;
    window.addEventListener('resize', () => {
      calcTraectory();
    });

    function calcTraectory() {
      that.widthWindow = window.innerWidth;
      that.heightWindow = window.innerHeight;
      const randomX = getRandomInt(0, that.widthWindow - 150);
      const randomY = getRandomInt(400, that.heightWindow - 150);
      const randomWidth = getRandomInt(50, 200);
      that.x = randomX;
      that.y = randomY;
      that.lastX = that.x;
      that.width = randomWidth;
      that.srcButterfly = srcButterfly;
    }
    calcTraectory();
    that.draw();
  }

  randomGenerator(time) {
    const randomX = getRandomInt(0, this.widthWindow - 150);
    const randomY = getRandomInt(400, this.heightWindow - 150);
    const randomWidth = getRandomInt(50, 100);
    this.x = randomX;
    this.y = randomY;
    this.width = randomWidth;
    this.move(time);
  }

  draw() {
    const butterflyHtml = document.createElement('img');
    butterflyHtml.src = this.srcButterfly;
    this.node = butterflyHtml;
    this.node.style.position = 'absolute';
    this.node.style.width = this.width + 'px';
    this.node.style.left = this.x + 'px';
    this.node.style.top = this.y + 'px';
    body.prepend(this.node);
  }

  moveUp() {
    this.y--;
    this.node.style.left = this.x + 'px';
    this.node.style.top = this.y + 'px';
  }

  moveRight() {
    console.log(true)
    this.x++;
    this.node.style.left = this.x + 'px';
  }

  moveLeft() {
    console.log(false)
    this.x--;
    this.node.style.left = this.x + 'px';
  }

  moveRandomLeftOrRight() {
    const hundred = parseInt(this.x / 100);

    if (hundred % 2) {
      const randInt = getRandomInt(0, 1);
      if (randInt) {
        this.moveRight();
      } else {
        this.moveLeft();
      }
    } else {
      this.moveRight();
    }
  }


  move(time = 30) {
    const that = this;
    let timer = setInterval(function() {
      if (that.y + that.node.scrollHeight < 0 ||
        that.x == 0) {
        that.randomGenerator(time);
        clearInterval(timer);
      }
      that.moveRandomLeftOrRight();
      that.moveUp();
    }, time);
  }
}

function getRandomInt(min, max) {
  const rand = min + Math.random() * (max + 1 - min);
  return Math.floor(rand);
}

const srcBlueButterfly = "https://aidanwalshblog.files.wordpress.com/2018/02/butterfly_blue.gif";
const srcBrownButterfly = "https://s8.hostingkartinok.com/uploads/images/2019/08/f55cda56fa8caa3f141c43f79af058d1.gif";

const body = document.querySelector('body');

const brown = new Butterfly(srcBrownButterfly);
brown.move(100);

// const brown1 = new Butterfly(srcBrownButterfly);
// brown1.move(10);


Ответы (2 шт):

Автор решения: OPTIMUS PRIME

Если решать проблему локально, не трогая внешний код, можно например так:
(изменил только функцию moveRandomLeftOrRight)

class Butterfly {
  constructor(srcButterfly) {    
    const that = this;
    window.addEventListener('resize', () => {
      calcTraectory();
    });

    function calcTraectory() {
      that.widthWindow = window.innerWidth;
      that.heightWindow = window.innerHeight;
      const randomX = getRandomInt(0, that.widthWindow - 150);
      const randomY = getRandomInt(400, that.heightWindow - 150);
      const randomWidth = getRandomInt(50, 200);
      that.x = randomX;
      that.y = randomY;
      that.lastX = that.x;
      that.width = randomWidth;
      that.srcButterfly = srcButterfly;
    }
    calcTraectory();
    that.draw();
  }

  randomGenerator(time) {
    const randomX = getRandomInt(0, this.widthWindow - 150);
    const randomY = getRandomInt(400, this.heightWindow - 150);
    const randomWidth = getRandomInt(50, 100);
    this.x = randomX;
    this.y = randomY;
    this.width = randomWidth;
    this.move(time);
  }

  draw() {
    const butterflyHtml = document.createElement('img');
    butterflyHtml.src = this.srcButterfly;
    this.node = butterflyHtml;
    this.node.style.position = 'absolute';
    this.node.style.width = this.width + 'px';
    this.node.style.left = this.x + 'px';
    this.node.style.top = this.y + 'px';
    body.prepend(this.node);
  }

  moveUp() {
    this.y--;
    this.node.style.left = this.x + 'px';
    this.node.style.top = this.y + 'px';
  }

  moveRight() {
    this.x++;
    this.node.style.left = this.x + 'px';
  }

  moveLeft() {
    this.x--;
    this.node.style.left = this.x + 'px';
  }

  moveRandomLeftOrRight() {
    let f = this.moveRandomLeftOrRight;
    
    if( !f.callCount ) f.callCount = 0;
    if( !f.direction ) f.direction = "Right";
    // Конечно же, обе переменные можно хранить в конструкторе...
    // Но там сложнее будет подобрать понятные названиия)

    if( ++f.callCount >= 100 ) {
      f.direction = (f.direction === "Right") ? "Left" : "Right";
      f.callCount = 0;
    }
    
    this[ "move" + f.direction ]();
  }


  move(time = 30) {
    const that = this;
    let timer = setInterval(function() {
      if (that.y + that.node.scrollHeight < 0 ||
        that.x == 0) {
        that.randomGenerator(time);
        clearInterval(timer);
      }
      that.moveRandomLeftOrRight();
      that.moveUp();
    }, time);
  }
}

function getRandomInt(min, max) {
  const rand = min + Math.random() * (max + 1 - min);
  return Math.floor(rand);
}

const srcBlueButterfly = "https://aidanwalshblog.files.wordpress.com/2018/02/butterfly_blue.gif";
const srcBrownButterfly = "https://s8.hostingkartinok.com/uploads/images/2019/08/f55cda56fa8caa3f141c43f79af058d1.gif";

const body = document.querySelector('body');

const brown = new Butterfly(srcBrownButterfly);
brown.move(100);

// const brown1 = new Butterfly(srcBrownButterfly);
// brown1.move(10);

→ Ссылка
Автор решения: Михаил Камахин

Я попытался сделать проверку на то, есть ли место идти направо или налево, но что-то пошло не так

class Butterfly {
  constructor(srcButterfly) {
    const calcTraectory = () => {
      this.widthWindow = window.innerWidth;
      this.heightWindow = window.innerHeight;
      const randomX = getRandomInt(0, this.widthWindow - 150);
      const randomY = getRandomInt(400, this.heightWindow - 150);
      const randomWidth = getRandomInt(50, 200);
      this.x = randomX;
      this.y = randomY;
      this.lastX = this.x;
      this.width = randomWidth;
      this.srcButterfly = srcButterfly;
    }
    window.addEventListener('resize', calcTraectory);
    calcTraectory();
    this.draw();
  }

  randomGenerator(time) {
    const randomX = getRandomInt(0, this.widthWindow - 150);
    const randomY = getRandomInt(400, this.heightWindow - 150);
    const randomWidth = getRandomInt(50, 100);
    this.x = randomX;
    this.y = randomY;
    this.width = randomWidth;
    this.move(time);
  }

  draw() {
    const butterflyHtml = document.createElement('img');
    butterflyHtml.src = this.srcButterfly;
    this.node = butterflyHtml;
    this.node.style.position = 'absolute';
    this.node.style.width = this.width + 'px';
    this.node.style.left = this.x + 'px';
    this.node.style.top = this.y + 'px';
    body.prepend(this.node);
  }

  moveUp() {
    this.y--;
    this.node.style.left = this.x + 'px';
    this.node.style.top = this.y + 'px';
  }

  moveRight() {
    this.x++;
    this.node.style.left = this.x + 'px';
  }

  moveLeft() {
    this.x--;
    this.node.style.left = this.x + 'px';
  }

  moveRandomLeftOrRight() {
    let f = this.moveRandomLeftOrRight;

    if (!f.callCount) f.callCount = 0;
    if (!f.maxCount) f.maxCount = getRandomInt(50, 150);
    if ((this.widthWindow - this.x - this.width > f.maxCount) && this.x > f.maxCount && !f.direction) {
      f.direction = getRandomInt(0, 1) ? 'Right' : 'Left';
    } else if (this.widthWindow - this.x - this.width > f.maxCount && !f.direction) {
      f.direction = "Right";
    } else if (this.x > f.maxCount && !f.direction) {
      f.direction = "Left";
    }


    if (++f.callCount >= f.maxCount) {
      f.maxCount = getRandomInt(50, 150);
      if ((this.widthWindow - this.x - this.width) > f.maxCount && this.x > f.maxCount) {
        // Если налево и направо есть место, то случайно можно пойти налево и направо
        f.direction = getRandomInt(0, 1) ? 'Right' : 'Left';
      } else if (this.widthWindow - this.x - this.width > f.maxCount) {
        // Иначе если есть место идти направо, то направо
        f.direction = "Right";
      } else if (this.x > f.maxCount) {
        // Иначе если есть место идти налево, то налево
        f.direction = "Left";
      }
      f.callCount = null;
    }

    this["move" + f.direction]();
  }

  move(time = 30) {
    let timer = setInterval(() => {
      if (this.y + this.node.scrollHeight < 0) {
        this.randomGenerator(time);
        clearInterval(timer);
      }
      this.moveRandomLeftOrRight();
      this.moveUp();
    }, time);
  }
}

function getRandomInt(min, max) {
  const rand = min + Math.random() * (max + 1 - min);
  return Math.floor(rand);
}

const srcBlueButterfly = "https://aidanwalshblog.files.wordpress.com/2018/02/butterfly_blue.gif";
const srcBrownButterfly = "https://s8.hostingkartinok.com/uploads/images/2019/08/f55cda56fa8caa3f141c43f79af058d1.gif";


const body = document.querySelector('body');

const brown = new Butterfly(srcBrownButterfly);
brown.move(10);

→ Ссылка