方块版本

添加绿色的至高点,使用 setTimeout 放慢速度便于观察。

数据可视化(中) - 图1

  1. let GreenHight = 0
  2. function Run() {
  3. let ramdom = 255 * Math.random()
  4. let maxSize = 20 // -> 255
  5. currentSize = Math.ceil((ramdom / 255) * maxSize)
  6. ctx.clearRect(0, 0, width, height)
  7. ctx.fillStyle = 'red'
  8. for (let i = 0; i <= currentSize; i++) {
  9. ctx.fillRect(0, height - (i + 1) * h - margin * i, w, h)
  10. }
  11. ctx.fillStyle = 'green'
  12. currentGreenHight = height - (currentSize + 1) * h - margin * currentSize // 至高点
  13. ctx.fillRect(0, currentGreenHight, w, h)
  14. setTimeout(Run, 500)
  15. }
  16. Run()

我们希望绿色的砖块可以被顶上去,下来的时候做自由落体。让绿色的下降速度为,每帧下降一个小块的高度,当下降超过之高点就停在制高点的位置。

这里要特别注意 y 轴的坐标,0 是左上角,最大是左下角。绿色球越往下落,y 越大,当与至高点的碰撞的时候,让他就等于至高点的位置,测试的时候发现会跌过头了,所以加了个 2 * v 或者 v 都行。

数据可视化(中) - 图2

  1. let GreenHight = height
  2. let v = h + margin // 下降速度
  3. function Run() {
  4. let ramdom = 255 * Math.random()
  5. let maxSize = 20 // -> 255
  6. currentSize = Math.ceil((ramdom / 255) * maxSize)
  7. ctx.clearRect(0, 0, width, height)
  8. ctx.fillStyle = 'red'
  9. for (let i = 0; i <= currentSize; i++) {
  10. ctx.fillRect(0, height - (i + 1) * h - margin * i, w, h)
  11. }
  12. ctx.fillStyle = 'green'
  13. currentGreenHight = height - (currentSize + 1) * h - margin * currentSize // 制高点 y 坐标。
  14. // 大 下面
  15. // 小 上面
  16. console.log(GreenHight)
  17. console.log(currentGreenHight)
  18. if (GreenHight + v > currentGreenHight) {
  19. // 比最高点还大,跌过头了
  20. // 保证等会的 + v 也不过头
  21. GreenHight = currentGreenHight
  22. ctx.fillRect(0, GreenHight, w, h)
  23. } else {
  24. GreenHight += v
  25. ctx.fillRect(0, GreenHight, w, h)
  26. }
  27. setTimeout(Run, 30)
  28. }
  29. Run()

想让下落幅度大一点?

  1. let v = (h + margin) * 3 // 下降速度

接下来实现纵向的逻辑

数据可视化(中) - 图3

  1. function Run() {
  2. ctx.clearRect(0, 0, width, height)
  3. ctx.fillStyle = 'red'
  4. let widthSize = 20 // 横向列数
  5. for (let j = 0; j <= widthSize; j++) {
  6. let ramdom = 255 * Math.random()
  7. let maxSize = 20
  8. currentSize = Math.ceil((ramdom / 255) * maxSize)
  9. for (let i = 0; i <= currentSize; i++) {
  10. ctx.fillRect(j * w + margin * j, height - (i + 1) * h - margin * i, w, h)
  11. }
  12. }
  13. setTimeout(Run, 500)
  14. }

添加绿色方块,oh~ 诶瑞巴蒂,跟我一起 high。把之前的绿块高度用数组保存。因为里面的循环是 <= 所以,应该  new Array 还要加一个。

数据可视化(中) - 图4

  1. let widthSize = 20
  2. let GreenHightArray = new Array(widthSize + 1).fill(height)
  3. let v = (h + margin) * 3 // 下降速度
  4. function Run() {
  5. ctx.clearRect(0, 0, width, height)
  6. for (let j = 0; j <= widthSize; j++) {
  7. let ramdom = 255 * Math.random()
  8. let maxSize = 20 // -> 255
  9. currentSize = Math.ceil((ramdom / 255) * maxSize)
  10. for (let i = 0; i <= currentSize; i++) {
  11. ctx.fillStyle = 'red'
  12. ctx.fillRect(j * w + margin * j, height - (i + 1) * h - margin * i, w, h)
  13. }
  14. // 绿块逻辑
  15. ctx.fillStyle = 'green'
  16. currentGreenHight = height - (currentSize + 1) * h - margin * currentSize // 制高点 y 坐标。
  17. if (GreenHightArray[j] + 2 * v > currentGreenHight) {
  18. GreenHightArray[j] = currentGreenHight
  19. ctx.fillRect(j * w + margin * j, GreenHightArray[j], w, h)
  20. } else {
  21. GreenHightArray[j] += v
  22. ctx.fillRect(j * w + margin * j, GreenHightArray[j], w, h)
  23. }
  24. }
  25. setTimeout(Run, 500)
  26. }
  27. Run()