钓鱼咯🎣

Published on
/
/趣玩前端
<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <title>钓鱼咯🎣</title>
    <style>
      html,
      body {
        margin: 0;
        overflow: hidden;
      }
      canvas {
        background: url('https://www.fecoder.cn/code-fun/images/oceanBackdrop.jpg')
          no-repeat top left;
        background-size: 100% 100%;
      }
    </style>
  </head>
  <body>
    <canvas>你的浏览器不支持 HTML5 Canvas</canvas>
    <script>
      (function setup(window) {
        var document = window.document;
        Object.prototype.on = function (a, b) {
          this.addEventListener(a, b);
          return this;
        };
        window.can = document.querySelector('canvas');
        window.ctx = window.can.getContext('2d');
        window.can.width = window.innerWidth;
        window.can.height = window.innerHeight;
        window.randInt = function (a, b) {
          if (a === void 0) return Math.round(Math.random());
          else if (b === void 0) return Math.floor(Math.random() * a);
          else return Math.floor(Math.random() * (b - a + 1) + a);
        };
        window.randFloat = function (a, b) {
          if (a === void 0) return Math.random();
          else if (b === void 0) return Math.random() * a;
          else return Math.random() * (b - a) + a;
        };
        window.rand = function (a, b) {
          return Array.isArray(a)
            ? a[Math.floor(Math.random() * a.length)]
            : window.randInt(a, b);
        };
      })(window);

      (function () {
        var mouse = {};
        var draw_fish = function (fish) {
          ctx.lineWidth = fish.s / 10;
          ctx.moveTo(fish.x, fish.y - fish.s);
          ctx.quadraticCurveTo(
            fish.x + fish.s * fish.pos,
            fish.y - fish.s,
            fish.x + fish.s * 2 * fish.pos,
            fish.y
          );
          ctx.quadraticCurveTo(
            fish.x + fish.s * fish.pos,
            fish.y + fish.s,
            fish.x,
            fish.y + fish.s
          );
          ctx.quadraticCurveTo(
            fish.x - (fish.s / 2) * fish.pos,
            fish.y + fish.s,
            fish.x - fish.s * 1.5 * fish.pos,
            fish.y + fish.s / 3
          );
          ctx.quadraticCurveTo(
            fish.x - fish.s * 2 * fish.pos,
            fish.y + fish.s / 2.5,
            fish.x - fish.s * 2.5 * fish.pos,
            fish.y + fish.s / 1.5
          );
          ctx.quadraticCurveTo(
            fish.x - fish.s * 2 * fish.pos,
            fish.y,
            fish.x - fish.s * 2.5 * fish.pos,
            fish.y - fish.s / 1.5
          );
          ctx.quadraticCurveTo(
            fish.x - fish.s * 2 * fish.pos,
            fish.y - fish.s / 2.5,
            fish.x - fish.s * 1.5 * fish.pos,
            fish.y - fish.s / 3
          );
          ctx.quadraticCurveTo(
            fish.x - (fish.s / 2) * fish.pos,
            fish.y - fish.s,
            fish.x,
            fish.y - fish.s
          );
          ctx.closePath();
          ctx.fill();
          ctx.stroke();
          ctx.beginPath();
          ctx.fillStyle = 'white';
          ctx.arc(
            fish.x + fish.s * fish.pos,
            fish.y,
            fish.s / 2.5,
            0,
            2 * Math.PI
          );
          ctx.fill();
          ctx.beginPath();
          ctx.fillStyle = 'black';
          ctx.arc(
            fish.x + (fish.s + fish.s / 6) * fish.pos,
            fish.y,
            fish.s / 4,
            0,
            2 * Math.PI
          );
          ctx.fill();
        };
        var Fish = function () {
          var s = rand(10, 30);
          return {
            x: rand(s * 3, can.width - s * 3),
            y: rand(s, can.height - s),
            s: s,
            c: [rand(100, 200), rand(100, 200), rand(50)],
            px: rand([-1, 1]) * randFloat(1, 3),
            py: rand([-1, 1]) * randFloat(),
            pos: rand([-1, 1]),
            speed: 5,
            caught: false,
            caughtBy: null,
          };
        };
        var fish = [];
        for (let i = 0; i < 20; i++) fish.push(new Fish());
        var Line = function (x) {
          return {
            x: x,
            y: 0,
            speed: 3,
            released: false,
          };
        };
        var lines = [];
        var fishCaught = 0;
        var secs = 0;
        (function update() {
          ctx.beginPath();
          ctx.clearRect(0, 0, can.width, can.height);
          ctx.fillStyle = 'white';
          ctx.font = '20px eagle lake';
          ctx.textAlign = 'left';
          ctx.textBaseline = 'top';
          let dig = function (n) {
            return n < 10 ? '0' + n : n;
          };
          ctx.fillText('数量: ' + fishCaught, 10, 10);
          ctx.fillText(
            [dig(Math.floor(secs / 60)), dig(secs % 60)].join(':'),
            10,
            30
          );
          for (let i in fish) {
            let p = fish[i];
            ctx.beginPath();
            ctx.shadowBlur = 0;
            ctx.strokeStyle = 'black';
            ctx.fillStyle = 'rgb(' + p.c + ')';
            draw_fish(p);
            if (p.caught) {
              p.y = lines[p.caughtBy].y;
              if (p.y + p.s < -p.s) {
                fish[i] = new Fish();
                fish[i].y = can.height + fish[i].s;
                lines[p.caughtBy].released = true;
                fishCaught++;
              }
            } else {
              p.x += p.px;
              p.y += p.py;
              p.pos = Math.sign(p.px);
              if (p.x + p.s * 2.5 < 0) p.x = can.width + p.s * 2.5;
              else if (p.x - p.s * 2.5 > can.width) p.x = -p.s * 2.5;
              if (p.y + p.s < 0) p.y = can.height + p.s;
              else if (p.y - p.s > can.height) p.y = -p.s;
            }
          }
          let n = 0;
          for (let i in lines) {
            let p = lines[i];
            ctx.beginPath();
            ctx.lineWidth = 2;
            ctx.strokeStyle = 'black';
            ctx.moveTo(p.x, 0);
            ctx.lineTo(p.x, p.y);
            ctx.stroke();
            ctx.beginPath();
            ctx.strokeStyle = 'rgb(50, 50, 50)';
            ctx.moveTo(p.x - 10, p.y);
            ctx.quadraticCurveTo(p.x - 10, p.y + 10, p.x - 5, p.y + 10);
            ctx.quadraticCurveTo(p.x, p.y + 10, p.x, p.y);
            ctx.quadraticCurveTo(p.x, p.y + 10, p.x + 5, p.y + 10);
            ctx.quadraticCurveTo(p.x + 10, p.y + 10, p.x + 10, p.y);
            ctx.stroke();
            p.y += p.speed;
            var caught = false;
            for (let x in fish) {
              if (
                p.y > fish[x].y - fish[x].s &&
                p.y < fish[x].y + fish[x].s &&
                p.x < fish[x].x + fish[x].s * 2 &&
                p.x > fish[x].x - fish[x].s * 2 &&
                Math.sign(p.speed) == 1 &&
                !fish[x].caught
              ) {
                fish[x].caught = caught = true;
                fish[x].caughtBy = i;
                break;
              }
            }
            if (caught) p.speed = -Math.abs(p.speed);
            else if (p.y > can.height) {
              p.speed = -2 * Math.abs(p.speed);
              p.released = true;
            }
            if (p.y < 0 && p.released) n++;
          }
          if (lines.length > 0 && n == lines.length) lines = [];
          requestAnimationFrame(update);
        })();
        (function count() {
          secs++;
          setTimeout(function () {
            requestAnimationFrame(count);
          }, 1000);
        })();
        can
          .on('click', function (e) {
            lines.push(new Line(e.offsetX));
          })
          .on('mousemove', function (e) {
            mouse.x = e.offsetX;
            mouse.y = e.offsetY;
          });
        window
          .on('resize', function () {
            can.width = this.innerWidth;
            can.height = this.innerHeight;
          })
          .on('keydown', function (e) {
            switch (e.which || e.keyCode) {
              case 37:
              case 65:
                fish.mx = -1;
                break;
              case 39:
              case 68:
                fish.mx = 1;
                break;
              case 38:
              case 87:
                fish.my = -1;
                break;
              case 40:
              case 83:
                fish.my = 1;
            }
          })
          .on('keyup', function (e) {
            switch (e.which || e.keyCode) {
              case 37:
              case 65:
              case 39:
              case 68:
                fish.mx = 0;
                break;
              case 38:
              case 83:
              case 40:
              case 87:
                fish.my = 0;
            }
          });
      })();
    </script>
  </body>
</html>