is it possible to create a sin wave shape for "createRandomPlatform" in: class Platform {
  constructor(x, y, w, h) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
  }
  collidesWith(obj) {
    if (obj.y + obj.h <= this.y) return false;
    if (obj.y >= this.y + this.h) return false;
    if (obj.x + obj.w <= this.x) return false;
    if (obj.x >= this.x + this.w) return false;
    const objAbove = obj.y + obj.h - obj.vy <= this.y;
    const objBelow = obj.y - obj.vy >= this.y + this.h;
    const objLeft = obj.x + obj.w - obj.vx <= this.x;
    const objRight = obj.x - obj.vx >= this.x + this.w;
    if (obj.vy > 0 && objAbove && !objBelow) {
      obj.y = this.y - obj.h;
      obj.vy = 0;
      obj.jumping = false;
      return true;
    }
    if (obj.vy < 0 && !objAbove && objBelow) {
      obj.y = this.y + this.h;
      obj.vy = 0;
      return true;
    }
    if (obj.vx < 0 && objRight) {
      obj.x = this.x + this.w;
      obj.vx = 0;
      return true;
    }
    if (obj.vx > 0 && objLeft) {
      obj.x = this.x - obj.w;
      obj.vx = 0;
      return true;
    }
    return false;
  }
}

class Player {
  constructor(x, y, w, h) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.vx = 0;
    this.vy = 0;
    this.jumping = false;
  }
  move(keys) {
    const friction = 0.9;
    const gty = 1;
    if (keys[87] && !this.jumping) {
      this.vy -= 20;
      this.jumping = true;
    }
    if (keys[68]) {
      this.vx += 5;
    }
    if (keys[65]) {
      this.vx -= 5;
    }
    this.vx *= friction;
    this.vy += gty;
    this.x += this.vx;
    this.y += this.vy;
    if (this.x < 0) {
      this.x = 0;
    }
    if (this.y < 0) {
      this.y = 0;
    }
    if (this.x + this.w > canvas.width) {
      this.x = canvas.width - this.w;
      this.vx = 0;
    }
    if (this.y + this.h > canvas.height) {
      this.y = canvas.height - this.h;
      this.vy = 0;
      this.jumping = false;
    }
  }
}

class Projectile {
  constructor(x, y, vx, vy) {
    this.x = x;
    this.y = y;
    this.vx = vx;
    this.vy = vy;
    this.radius = 2;
    this.color = "royalblue";
  }
  update() {
    this.x += this.vx;
    this.y += this.vy;
  }
  draw(ctx) {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
    ctx.fillStyle = this.color;
    ctx.fill();
  }
}

class Entity {
  constructor() {
    this.x = canvas.width;
    this.y = Math.random() * canvas.height;
    this.w = 10;
    this.h = 20;

    this.vy = 0;
    this.jumping = false;
    this.projectiles = [];
    this.color = "pink";
  }
  jump() {
    if (!this.jumping) {
      this.vy -= 25 - Math.random() * 25;
      this.jumping = true;
    }
  }
  update(platforms) {
    for (let i = 0; i < platforms.length; i++) {
      platforms[i].collidesWith(this);
    }
    const friction = 0.99;
    const gty = 1;
    this.vx = friction;
    this.vy += gty;
    this.x += this.vx;
    this.y += this.vy;
    this.period = Math.PI;
    this.minVx = -2 + Math.sin(Math.random() * 2 * Math.PI) * 2;
    this.maxVx = -10 + Math.cos(Math.random() * 2 * Math.PI) * -20;
    this.vx = this.vxForce = randomRange(this.minVx, this.maxVx);
    const t = performance.now() / 1000;
    const wave = Math.sin((t * Math.PI) / this.period);
    this.vxForce = lerp(this.maxVx, this.minVx, (wave + 8) / 432);
    this.x += this.vxForce;
    if (Math.random() < 0.01) {
      this.projectiles.push(
        new Projectile(
          this.x,
          this.y,
          -2 - Math.random() * 6,
          -2 + Math.random() * 8
        )
      );
    }
    for (let i = 0; i < this.projectiles.length; i++) {
      this.projectiles[i].update();
      if (
        this.projectiles[i].x < 0 ||
        this.projectiles[i].y < 0 ||
        this.projectiles[i].x > canvas.width ||
        this.projectiles[i].y > canvas.height
      ) {
        this.projectiles.splice(i, 1);
        i;
      }
    }
    if (Math.random() < 0.1) {
      this.jump();
    }
  }
  draw(ctx) {
    ctx.fillStyle = this.color = "darkgreen";

    ctx.fillRect(this.x, this.y, this.w, this.h,  this.color = "orange");
    for (let i = 0; i < this.projectiles.length; i++) {
      this.projectiles[i].draw(ctx);
    }
  }
}

function randomRange(min, max) {
  return Math.random() * (max - min) + min;
}

function lerp(a, b, t) {
  return a * (1 - t) + b * t;
}

class Game {
  constructor(canvas) {
    this.canvas = canvas;
    this.ctx = canvas.getContext("2d");
    this.platforms = [];
    this.player = new Player(20, 20, 20, 20);
    this.scrollSpeed = 5;
    this.entities = [];
    this.entitySpawnRate = 1;
    this.entitySpawnTimer = 0;
    this.entityIncreaseFactor = 1;
    this.keys = {};
    this.platforms.push(new Platform(canvas.height));
    for (let i = 0; i < 0; i++) {
      this.createRandomPlatform();
    }
    document.addEventListener("keydown", (evt) => {
      this.keys[evt.keyCode] = true;
    });
    document.addEventListener("keyup", (evt) => {
      delete this.keys[evt.keyCode];
    });
    requestAnimationFrame(this.update.bind(this));
  }
  createRandomPlatform() {
    const x = this.canvas.width;
    const y = Math.random() * this.canvas.height;
    const w = 10 * Math.random() * 20;
    const h = 20 * Math.random() * 10;
    this.platforms.push(new Platform(x, y, w, h));
  }
  update() {
    this.player.move(this.keys);
    for (let i = 0; i < this.platforms.length; i++) {
      this.platforms[i].collidesWith(this.player);
      this.platforms[i].x -= this.scrollSpeed;
    }
    for (let i = 0; i < this.entities.length; i++) {
      if (this.entities[i]) {
        this.entities[i].update(this.platforms);
        if (this.entities[i].x < 0) {
          this.entities.splice(i, 1);
          i;
          for (let j = 0; j < this.entityIncreaseFactor; j++) {
            this.entities.push(new Entity());
          }
        } else {
          for (let j = 0; j < this.entities[i].projectiles.length; j++) {
            if (
              this.entities[i].projectiles[j].x > this.player.x &&
              this.entities[i].projectiles[j].x <
                this.player.x + this.player.w &&
              this.entities[i].projectiles[j].y > this.player.y &&
              this.entities[i].projectiles[j].y < this.player.y + this.player.h
            ) {
              this.player.vy -= 20;
              this.player.jumping = true;
              this.entities[i].projectiles.splice(j, 1);
              j;
            }
          }
          this.entities[i].draw(this.ctx);
        }
      }
    }
    this.player.x -= this.scrollSpeed;
    if (this.platforms[this.platforms.length - 1].x < this.canvas.width - 50) {
      this.createRandomPlatform();
    }
    this.entitySpawnTimer++;
    if (this.entitySpawnTimer >= 60 / this.entitySpawnRate) {
      this.entitySpawnTimer = 0;
      this.entities.push(new Entity());
      this.entitySpawnRate += 0.001;
      this.entityIncreaseFactor = Math.min(
        this.entityIncreaseFactor + 0.001,
        0.001
      );
    }
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    for (let i = 0; i < this.platforms.length; i++) {
      let p = this.platforms[i];
      this.ctx.fillRect(p.x, p.y, p.w, p.h);
    }
    for (let i = 0; i < this.entities.length; i++) {
      this.entities[i].draw(this.ctx);
    }
    this.ctx.fillRect(
      this.player.x,
      this.player.y,
      this.player.w,
      this.player.h
    );
    requestAnimationFrame(this.update.bind(this));
  }
}

let canvas = document.createElement("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
document.body.appendChild(canvas);
new Game(canvas);
