Bladeren bron

日常开发

林旭祥 1 week geleden
bovenliggende
commit
057665f5d4
3 gewijzigde bestanden met toevoegingen van 1668 en 484 verwijderingen
  1. 855 0
      src/components/SquareGame/index copy.vue
  2. 810 484
      src/components/SquareGame/index.vue
  3. 3 0
      src/types/components.d.ts

+ 855 - 0
src/components/SquareGame/index copy.vue

@@ -0,0 +1,855 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8" />
+    <title>Square Jump</title>
+    <style type="text/css">
+      * {
+        padding: 0px;
+        margin: 0px;
+      }
+      a {
+        text-decoration: none;
+        list-style: none;
+        color: rgb(0, 0, 0);
+      }
+      #main_box {
+        margin: 0px auto;
+        width: 420px;
+        height: 580px;
+        background: skyblue;
+        position: relative;
+        overflow: hidden;
+      }
+      .can {
+        position: absolute;
+        top: 0px;
+        left: 0px;
+      }
+      #score {
+        width: auto;
+        height: 40px;
+        font-size: 22px;
+        color: #7fffd4;
+        position: absolute;
+        top: 10px;
+        left: 10px;
+        display: none;
+      }
+      #game_title {
+        display: none;
+        position: absolute;
+        width: 240px;
+        height: 80px;
+        line-height: 80px;
+        text-align: center;
+        top: 35%;
+        left: 50%;
+        margin-left: -120px;
+        font-size: 42px;
+        font-family: "century gothic";
+        font-weight: bolder;
+        text-shadow: 4px 3px 2px black;
+        color: #fff;
+      }
+      #login_btn {
+        display: none;
+        position: absolute;
+        bottom: 100px;
+        left: 50%;
+        width: 100px;
+        height: 40px;
+        margin-left: -50px;
+        line-height: 40px;
+        text-align: center;
+        border-radius: 12px;
+        border: 2px solid #ffffff;
+        font-size: 18px;
+        color: #000000;
+        font-weight: normal;
+        background: peachpuff;
+      }
+      #login_btn:hover {
+        color: #fff;
+      }
+      #login_btn:active {
+        background: #ffffff;
+        color: #000000;
+      }
+      #square_main {
+        width: 40px;
+        height: 40px;
+        position: absolute;
+        top: 0px;
+        left: 0px;
+        border: 2px solid #ffffff;
+        display: none;
+        background: #ff6688;
+      }
+      #state {
+        width: 280px;
+        height: 60px;
+        font-size: 18px;
+        font-weight: bolder;
+        text-shadow: #fdf5e6;
+        color: blueviolet;
+        font-family: "arial narrow";
+        position: absolute;
+        top: 45%;
+        left: 50%;
+        line-height: 60px;
+        text-align: center;
+        margin-left: -140px;
+        display: none;
+      }
+      #colorChangeTime_div {
+        width: 200px;
+        height: 50px;
+        line-height: 50px;
+        position: absolute;
+        text-align: center;
+        top: 3%;
+        left: 50%;
+        display: none;
+        color: #ffffff;
+        font-size: 40px;
+      }
+    </style>
+  </head>
+  <body>
+    <div id="main_box">
+      <canvas id="myCanvas1" class="can"></canvas>
+      <canvas id="myCanvas2" class="can"></canvas>
+      <a href="javascript:loginGame()" id="login_btn">开始游戏</a>
+      <div id="score"></div>
+      <div id="game_title">方&nbsp;块&nbsp;跳&nbsp;跃</div>
+      <div id="state"></div>
+      <span id="square_main"></span>
+      <div id="colorChangeTime_div">10</div>
+    </div>
+    <script>
+      var can1;
+      var can2;
+      var ctx1;
+      var ctx2;
+      var canWidth = 820;
+      var canHeight = 640;
+      var maxHeight = window.innerHeight;
+      var maxWidth = window.innerWidth;
+
+      var beginGame;
+      var gameOver;
+
+      var backrgound;
+      var squares;
+      var mySquare;
+
+      var beginAnim; //开始界面动画
+
+      var lastTime;
+      var changeColorTime;
+      var changeTimeArrays = [
+        "10",
+        "9",
+        "8",
+        "7",
+        "6",
+        "5",
+        "4",
+        "3",
+        "2",
+        "1",
+        "color change!",
+      ];
+      var changeColorindex = 0;
+      var totalSpeed = 3;
+
+      var isStep;
+
+      var colorChangeTimeW = 0;
+
+      var score;
+
+      let AnimPX = [];
+      let AnimPY = [];
+      let jump_count = 0;
+
+      const squareColor = [
+        "#FF6688",
+        "#00FF00",
+        "#3399FF",
+        "#FFDAB9",
+        "blueviolet",
+      ];
+      document.body.onload = game;
+
+
+      function init() {
+        score = 0;
+        beginGame = false;
+        gameOver = false;
+        isStep = false;
+
+        lastTime = Date.now();
+
+        can1 = document.getElementById("myCanvas1");
+        ctx1 = can1.getContext("2d");
+        can2 = document.getElementById("myCanvas2");
+        ctx2 = can2.getContext("2d");
+
+        if (maxWidth != canWidth) {
+          canWidth = maxWidth;
+        }
+        if (maxHeight != canHeight) {
+          canHeight = maxHeight;
+        }
+
+        const mainBox = document.getElementById("main_box");
+        mainBox.style.width = canWidth + "px";
+        mainBox.style.height = canHeight + "px";
+
+        can1.width = canWidth;
+        can2.width = canWidth;
+        can1.height = canHeight;
+        can2.height = canHeight;
+
+        // 模拟 slideDown 效果
+        const gameTitle = document.getElementById("game_title");
+        gameTitle.style.display = "block";
+        gameTitle.style.height = "0";
+        gameTitle.style.overflow = "hidden";
+        setTimeout(() => {
+          gameTitle.style.height = "auto";
+        }, 0);
+
+        // 模拟 delay 和 slideToggle 效果
+        const loginBtn = document.getElementById("login_btn");
+        setTimeout(() => {
+          loginBtn.style.display = "block";
+          loginBtn.style.height = "0";
+          loginBtn.style.overflow = "hidden";
+          setTimeout(() => {
+            loginBtn.style.height = "auto";
+          }, 10);
+        }, 500);
+
+        colorChangeTimeW = (canHeight > canWidth ? canWidth : canHeight) * 0.5;
+        const colorChangeTimeDiv = document.getElementById(
+          "colorChangeTime_div"
+        );
+        colorChangeTimeDiv.style.width = colorChangeTimeW * 1.6 + "px";
+        colorChangeTimeDiv.style.height = colorChangeTimeW * 0.5 + "px";
+        colorChangeTimeDiv.style.marginLeft = -colorChangeTimeW * 0.8 + "px";
+        colorChangeTimeDiv.style.lineHeight = colorChangeTimeW * 0.5 + "px";
+        colorChangeTimeDiv.style.fontSize = colorChangeTimeW * 0.3 + "px";
+
+        backrgound = new backgroundObj();
+        backrgound.init();
+
+        squares = new squareObj();
+        squares.init();
+
+        mySquare = new mySquareObj();
+        mySquare.init();
+
+        beginAnim = new beginAnimObj();
+        beginAnim.init();
+      }
+
+      function restartInit() {
+        AnimPX = new Array();
+        AnimPY = new Array();
+        changeColorindex = 0;
+        jump_count = 0;
+
+        // 隐藏元素
+        document.getElementById("colorChangeTime_div").style.display = "none";
+        document.getElementById("score").style.display = "none";
+
+        // 初始化动画
+        beginAnim.init();
+
+        // 设置游戏状态
+        beginGame = false;
+        gameOver = true;
+        lastTime = Date.now();
+
+        // 设置游戏标题
+        const gameTitle = document.getElementById("game_title");
+        gameTitle.innerHTML = "方&nbsp;块&nbsp;跳&nbsp;跃";
+
+        // 显示游戏标题(模拟slideDown效果)
+        gameTitle.style.display = "block";
+        gameTitle.style.height = "0";
+        gameTitle.style.overflow = "hidden";
+        setTimeout(() => {
+          gameTitle.style.height = "auto";
+        }, 0);
+
+        // 延迟显示登录按钮(模拟delay和slideToggle效果)
+        const loginBtn = document.getElementById("login_btn");
+        setTimeout(() => {
+          loginBtn.style.display = "block";
+          loginBtn.style.height = "0";
+          loginBtn.style.overflow = "hidden";
+          setTimeout(() => {
+            loginBtn.style.height = "auto";
+          }, 10);
+        }, 500);
+
+        // 设置登录按钮文本
+        loginBtn.innerHTML = "再来一次";
+
+        // 显示状态(模拟slideDown效果)
+        const state = document.getElementById("state");
+        state.style.display = "block";
+        state.style.height = "0";
+        state.style.overflow = "hidden";
+        setTimeout(() => {
+          state.style.height = "auto";
+        }, 500);
+
+        // 设置状态文本
+        state.innerHTML = "游戏结束,得分:" + Math.floor(score);
+      }
+
+      function game() {
+        init();
+        loop = setInterval(gameloop, 20);
+      }
+      function restart() {
+        // 调用初始化方法
+        backrgound.init();
+        squares.init();
+        mySquare.init();
+
+        // 更新时间戳
+        lastTime = Date.now();
+
+        // 隐藏元素
+        document.getElementById("state").style.display = "none";
+        document.getElementById("game_title").style.display = "none";
+        document.getElementById("login_btn").style.display = "none";
+
+        // 显示分数
+        document.getElementById("score").style.display = "block";
+
+        // 重置分数和速度
+        score = 0;
+        totalSpeed = 3;
+      }
+      function gameloop() {
+        backrgound.draw();
+        ctx2.clearRect(0, 0, canWidth, canHeight);
+        ctx2.save();
+
+        if (beginAnim.isLive && Date.now() - lastTime > 1000) {
+          beginAnim.draw();
+        }
+
+        if (beginGame && !gameOver) {
+          document.getElementById("score").innerHTML =
+            "得分:" + Math.floor(score);
+          addSpeed();
+          squares.draw();
+          mySquare.draw();
+          squaresToMy();
+
+          // 添加点击事件监听器
+          const mainBox = document.getElementById("main_box");
+          mainBox.addEventListener("click", function () {
+            mySquare.jump();
+          });
+        } else if (gameOver && !beginGame) {
+          // 这里可以添加游戏结束时的逻辑
+        }
+
+        ctx2.restore();
+      }
+      function loginGame() {
+        changeColorTime = Date.now();
+
+        // 显示颜色变化时间div
+        const colorChangeTimeDiv = document.getElementById(
+          "colorChangeTime_div"
+        );
+        colorChangeTimeDiv.style.display = "block";
+
+        // 随机设置颜色
+        const randomColor =
+          squareColor[Math.floor(Math.random() * squareColor.length)];
+        colorChangeTimeDiv.style.color = randomColor;
+
+        // 设置颜色变化时间div的内容
+        colorChangeTimeDiv.innerHTML = "" + changeTimeArrays[changeColorindex];
+
+        if (!gameOver && !beginGame) {
+          // 显示分数,隐藏游戏标题和方块
+          document.getElementById("score").style.display = "block";
+          document.getElementById("game_title").style.display = "none";
+          document.getElementById("square_main").style.display = "none";
+
+          // 设置游戏状态
+          beginGame = true;
+
+          // 隐藏登录按钮
+          document.getElementById("login_btn").style.display = "none";
+        } else if (gameOver && !beginGame) {
+          // 重新开始游戏
+          restart();
+
+          // 更新游戏状态
+          gameOver = false;
+          beginGame = true;
+        }
+
+        // 设置动画状态
+        beginAnim.isLive = false;
+
+        // 隐藏方块
+        document.getElementById("square_main").style.display = "none";
+      }
+      function addSpeed() {
+        totalSpeed += 0.04 * 0.05;
+        score += 0.04;
+      }
+      function squaresToMy() {
+        for (var i = 0; i < squares.num; i++) {
+          if (squares.isLive[i]) {
+            if (squares.color[i] != mySquare.color) {
+              if (mySquare.isLive) {
+                if (
+                  ((mySquare.x + mySquare.l - 1 > squares.x[i] &&
+                    mySquare.x + mySquare.l - 1 < squares.x[i] + squares.w[i] &&
+                    mySquare.x + mySquare.l - 30 > squares.x[i] &&
+                    mySquare.x + mySquare.l - 30 <
+                      squares.x[i] + squares.w[i]) ||
+                    (mySquare.x > squares.x[i] &&
+                      mySquare.x + 10 < squares.x[i] + squares.w[i] &&
+                      mySquare.x + 10 > squares.x[i] &&
+                      mySquare.x + 10 < squares.x[i] + squares.w[i])) &&
+                  mySquare.y + mySquare.l > squares.y[i] &&
+                  mySquare.y + mySquare.l < squares.y[i] + squares.h[i]
+                ) {
+                  mySquare.y = squares.y[i] - mySquare.l;
+                  mySquare.toVSpeed = -totalSpeed * 0.2;
+                  mySquare.toDownSpeed = 0;
+                  jump_count = 0;
+                }
+                if (
+                  mySquare.x + mySquare.l > squares.x[i] &&
+                  mySquare.x + mySquare.l < squares.x[i] + squares.w[i] &&
+                  mySquare.y + mySquare.l > squares.y[i] &&
+                  mySquare.y + mySquare.l < squares.y[i] + squares.h[i]
+                ) {
+                  mySquare.x = squares.x[i] - mySquare.l;
+                }
+              }
+            }
+          }
+        }
+      }
+
+      class backgroundObj {
+        constructor() {
+          this.x = [];
+          this.y = [];
+          this.w = [];
+          this.h = [];
+          this.isLive = [];
+          this.num = 3;
+        }
+
+        init() {
+          for (let i = 0; i < this.num; i++) {
+            this.x[i] =
+              i === 0
+                ? canWidth * 0.1 * Math.random()
+                : this.x[i - 1] +
+                  this.w[i - 1] +
+                  canWidth * 0.2 * i * Math.random();
+
+            this.w[i] = canWidth * 0.08 + canHeight * Math.random() * 0.3;
+            this.h[i] = canHeight * 0.08 + canWidth * Math.random() * 0.3;
+            this.y[i] = canHeight * 0.2 * Math.random();
+            this.isLive[i] = true;
+          }
+        }
+
+        cloudBorn() {
+          for (let i = 0; i < this.num; i++) {
+            if (!this.isLive[i]) {
+              this.w[i] = canWidth * 0.08 + canWidth * Math.random() * 0.3;
+              this.h[i] = canHeight * 0.08 + canHeight * Math.random() * 0.3;
+              this.y[i] = canHeight * 0.2 * Math.random();
+
+              this.x[i] = i === 0 ? canWidth : canWidth + i * this.w[i - 1];
+
+              this.isLive[i] = true;
+            }
+          }
+        }
+
+        draw() {
+          ctx1.clearRect(0, 0, canWidth, canHeight);
+          ctx1.save();
+
+          for (let i = 0; i < this.num; i++) {
+            if (!this.isLive[i]) continue;
+
+            this.x[i] -= 0.1 * totalSpeed;
+            const maxSize = Math.max(this.h[i], this.w[i]) * 0.15;
+            const smallSize = Math.max(this.h[i], this.w[i]) * 0.1;
+
+            // 绘制云朵的各个部分
+            const cloudParts = [
+              { x: 0.4, y: 0.1, size: maxSize },
+              { x: 0.1, y: 0.2, size: maxSize },
+              { x: 0.6, y: 0.25, size: maxSize },
+              { x: 0.5, y: 0.3, size: maxSize },
+              { x: 0.65, y: 0.22, size: maxSize },
+              { x: 0.2, y: 0.35, size: maxSize },
+              { x: 0.35, y: 0.35, size: smallSize },
+              { x: 0.3, y: 0.1, size: maxSize },
+            ];
+
+            ctx1.fillStyle = "#ffffff";
+            cloudParts.forEach((part) => {
+              ctx1.beginPath();
+              ctx1.arc(
+                this.x[i] + this.w[i] * part.x,
+                this.y[i] + this.h[i] * part.y,
+                part.size,
+                0,
+                Math.PI * 2
+              );
+              ctx1.fill();
+              ctx1.closePath();
+            });
+
+            if (this.x[i] + this.w[i] < 0) {
+              this.isLive[i] = false;
+            }
+          }
+
+          ctx1.restore();
+          this.cloudBorn();
+        }
+      }
+
+      class squareObj {
+        constructor() {
+          this.num = 12;
+          this.x = [];
+          this.y = [];
+          this.w = [];
+          this.h = [];
+          this.color = [];
+          this.isLive = [];
+        }
+
+        init() {
+          let repeatColorCount = 0;
+
+          for (let i = 0; i < this.num; i++) {
+            // Random color selection with constraints
+            this.color[i] = this.getRandomColor(i, repeatColorCount);
+
+            // Position and size initialization
+            if (i === 0) {
+              this.x[i] = 0;
+            } else {
+              this.x[i] = this.x[i - 1] + this.w[i - 1] + 1;
+            }
+
+            this.h[i] = canHeight * 0.3 + canHeight * 0.25 * Math.random();
+            this.w[i] = canWidth * 0.15 + canWidth * 0.06 * Math.random();
+            this.y[i] = canHeight - this.h[i];
+            this.isLive[i] = true;
+
+            // Update repeat color count
+            repeatColorCount =
+              this.color[i] === this.color[i - 1] ? repeatColorCount + 1 : 0;
+
+            // Handle consecutive colors
+            if (repeatColorCount > 1) {
+              this.adjustColor(i);
+            }
+          }
+        }
+
+        getRandomColor(i, repeatColorCount) {
+          const randomIndex = Math.floor(Math.random() * squareColor.length);
+          let color = squareColor[randomIndex];
+
+          // For the first element, check against last element
+          if (i === 0 && color === this.color[this.num - 1]) {
+            const lastColorIndex = squareColor.indexOf(
+              this.color[this.num - 1]
+            );
+            color =
+              squareColor[
+                (lastColorIndex - 1 + squareColor.length) % squareColor.length
+              ];
+          }
+          // For other elements, check against previous element
+          else if (
+            i > 0 &&
+            color === this.color[i - 1] &&
+            repeatColorCount > 1
+          ) {
+            const currentColorIndex = squareColor.indexOf(color);
+            color = squareColor[(currentColorIndex + 1) % squareColor.length];
+          }
+
+          return color;
+        }
+
+        adjustColor(i) {
+          if (i === 0) {
+            const lastColorIndex = squareColor.indexOf(
+              this.color[this.num - 1]
+            );
+            this.color[i] =
+              squareColor[
+                (lastColorIndex - 1 + squareColor.length) % squareColor.length
+              ];
+          } else {
+            const currentColorIndex = squareColor.indexOf(this.color[i]);
+            this.color[i] =
+              squareColor[(currentColorIndex + 1) % squareColor.length];
+          }
+        }
+
+        squareBorn() {
+          const maxX = Math.max(
+            ...this.x.map((val, idx) => val + (this.w[idx] || 0))
+          );
+          const maxI = this.x.indexOf(
+            maxX - (this.w[this.x.indexOf(maxX)] || 0)
+          );
+
+          for (let i = 0; i < this.num; i++) {
+            if (!this.isLive[i]) {
+              this.x[i] = maxX + 1;
+              this.h[i] = canHeight * 0.25 + canHeight * 0.35 * Math.random();
+              this.w[i] = canWidth * 0.14 + canWidth * 0.1 * Math.random();
+              this.y[i] = canHeight - this.h[i];
+
+              let repeatColorCount = 0;
+              if (i === 0 && this.isLive[this.num - 1]) {
+                this.color[i] = this.getRandomColorForBorn(
+                  this.num - 1,
+                  repeatColorCount
+                );
+              } else if (i > 0 && this.isLive[i - 1]) {
+                this.color[i] = this.getRandomColorForBorn(
+                  i - 1,
+                  repeatColorCount
+                );
+              }
+
+              this.isLive[i] = true;
+              return;
+            }
+          }
+        }
+
+        getRandomColorForBorn(prevIndex, repeatColorCount) {
+          const randomIndex = Math.floor(Math.random() * 3);
+          let color = squareColor[randomIndex];
+
+          if (color === this.color[prevIndex] && repeatColorCount > 1) {
+            const currentColorIndex = squareColor.indexOf(color);
+            color = squareColor[(currentColorIndex + 1) % squareColor.length];
+          }
+
+          return color;
+        }
+
+        draw() {
+          for (let i = 0; i < this.num; i++) {
+            if (this.isLive[i]) {
+              ctx2.fillStyle = this.color[i];
+              ctx2.beginPath();
+              ctx2.fillRect(this.x[i], this.y[i], this.w[i], this.h[i]);
+              ctx2.fill();
+              ctx2.closePath();
+              this.x[i] -= totalSpeed;
+            }
+
+            if (this.x[i] + this.w[i] < 0) {
+              this.isLive[i] = false;
+            }
+          }
+
+          this.squareBorn();
+        }
+      }
+
+      class mySquareObj {
+        constructor() {
+          this.x;
+          this.y;
+          this.isLive; // 生命状态
+          this.l = 40; // 正方形边长
+          this.color;
+          this.toDownSpeed = 0; // 垂直方向速度
+          this.toVSpeed = 0; // 水平方向速度
+        }
+
+        init() {
+          this.isLive = true;
+          this.x = 0;
+          this.y = 0;
+          this.l = 40;
+          this.toDownSpeed = 0;
+          this.toVSpeed = 0;
+          this.color = squareColor[0];
+        }
+
+        jump() {
+          if (this.isLive) {
+            this.toDownSpeed = -15;
+            this.toVSpeed = 2;
+            jump_count++;
+            if (this.x + this.l > canWidth) {
+              this.x = canWidth - this.l;
+            }
+          }
+        }
+
+        toDown() {
+          if (this.isLive) {
+            this.toDownSpeed += 9.8 * 1 * 0.06;
+            this.y += this.toDownSpeed;
+            this.x += this.toVSpeed;
+            if (this.y + this.l > canHeight) {
+              this.isLive = false;
+            }
+          }
+        }
+
+        draw() {
+          if (this.isLive) {
+            const now = Date.now();
+            if (now - changeColorTime > 1000) {
+              changeColorindex = ++changeColorindex % changeTimeArrays.length;
+              const strColor =
+                "" +
+                squareColor[Math.floor(Math.random() * squareColor.length)];
+
+              // 获取元素
+              const colorChangeTimeDiv = document.getElementById(
+                "colorChangeTime_div"
+              );
+
+              // 设置颜色和内容
+              colorChangeTimeDiv.style.color = strColor;
+              colorChangeTimeDiv.textContent =
+                "" + changeTimeArrays[changeColorindex];
+
+              if (changeColorindex === 10) {
+                colorChangeTimeDiv.style.fontSize =
+                  colorChangeTimeW * 0.15 + "px";
+                this.color = strColor;
+              } else {
+                colorChangeTimeDiv.style.fontSize =
+                  colorChangeTimeW * 0.3 + "px";
+              }
+
+              changeColorTime = now;
+            }
+            ctx2.fillStyle = this.color + "";
+            ctx2.rect(this.x, this.y, this.l, this.l);
+            ctx2.fill();
+            ctx2.lineWidth = 3;
+            ctx2.radiusX = 3;
+
+            ctx2.strokeStyle = "#ffffff";
+            ctx2.stroke();
+            if (this.x < -100) {
+              this.isLive = false;
+            }
+          } else {
+            restartInit();
+          }
+          this.toDown();
+        }
+      }
+
+      class beginAnimObj {
+        constructor() {
+          this.x;
+          this.y;
+          this.isLive;
+          this.l = 40; // 正方形边长
+          this.color;
+          this.toDownSpeed = 0; // 垂直方向速度
+          this.toVSpeed = canWidth * 0.021; // 水平方向速度
+        }
+
+        init() {
+          this.isLive = true;
+          this.x = 0;
+          this.y = 0;
+          this.toDownSpeed = 0;
+          this.toVSpeed = canWidth * 0.021;
+          this.color = squareColor[0];
+        }
+
+        jump() {
+          if (this.isLive) {
+            this.toDownSpeed = -this.toDownSpeed;
+            this.toVSpeed = canWidth * 0.021 * 0.5;
+            jump_count++;
+            if (this.x + this.l > canWidth) {
+              this.x = canWidth - this.l;
+            }
+            this.x += this.toVSpeed;
+            if (this.toVSpeed + 2 < 3) {
+              this.toVSpeed += 1;
+            }
+          }
+        }
+
+        toDown() {
+          if (this.isLive) {
+            this.toDownSpeed += 9.8 * 1 * 0.06;
+            this.y += this.toDownSpeed;
+            this.x += this.toVSpeed;
+            if (this.y > canHeight) {
+              this.isLive = false;
+            }
+          }
+        }
+
+        draw() {
+          if (this.isLive) {
+            const squareMain = document.getElementById("square_main");
+            const gameTitle = document.getElementById("game_title");
+
+            squareMain.style.display = "block";
+            squareMain.style.left = this.x + "px";
+            squareMain.style.top = this.y + "px";
+
+            if (
+              this.y + this.l > canHeight * 0.35 &&
+              this.x + this.l * 0.5 < canWidth * 0.5 + 120 &&
+              this.x + this.l * 0.5 > canWidth * 0.5 - 120
+            ) {
+              this.jump();
+              gameTitle.innerHTML =
+                "方&nbsp;块&nbsp;<i style='font-size: 46px;color:#FF6688;'>跳&nbsp;</i>跃";
+            }
+
+            ctx2.restore();
+            this.toDown();
+          } else {
+            document.getElementById("square_main").style.display = "none";
+          }
+        }
+      }
+    </script>
+  </body>
+</html>

+ 810 - 484
src/components/SquareGame/index.vue

@@ -1,511 +1,837 @@
 <template>
-    <div id="main_box">
-      <canvas ref="can1" id="myCanvas1" class="can"></canvas>
-      <canvas ref="can2" id="myCanvas2" class="can"></canvas>
-      <button id="login_btn" @click="loginGame" v-if="!beginGame && !gameOver">开始游戏</button>
-      <div id="score" v-if="beginGame && !gameOver">得分: {{ Math.floor(score) }}</div>
-      <div id="game_title" v-if="!beginGame && !gameOver">方&nbsp;块&nbsp;跳&nbsp;跃</div>
-      <div id="state" v-if="gameOver">游戏结束,得分:{{ Math.floor(score) }}</div>
-      <span
-        id="square_main"
-        v-if="mySquare && mySquare.isLive"
-        :style="{ left: mySquare.x + 'px', top: mySquare.y + 'px', background: mySquare.color }"
-      ></span>
-      <div id="colorChangeTime_div" v-if="showColorChange">{{ changeTimeArrays[changeColorIndex] }}</div>
-    </div>
-  </template>
-  
-  <script setup lang="ts">
-  import { ref, onMounted, onBeforeUnmount } from 'vue';
-  
-  interface BackgroundObj {
-    x: number[];
-    y: number[];
-    w: number[];
-    h: number[];
-    isLive: boolean[];
-    num: number;
-    init: () => void;
-    draw: () => void;
-    cloudBorn: () => void;
+  <div id="main_box" ref="main_box">
+    <canvas id="myCanvas1" class="can" ref="can1"></canvas>
+    <canvas id="myCanvas2" class="can" ref="can2"></canvas>
+    <a href="javascript:void(0)" @click="loginGame" id="login_btn" ref="login_btn">开始游戏</a>
+    <div id="score" ref="score_div">{{ scoreText }}</div>
+    <div id="game_title" ref="game_title">方&nbsp;块&nbsp;跳&nbsp;跃</div>
+    <div id="state" ref="state_div">{{ stateText }}</div>
+    <span id="square_main" ref="square_main"></span>
+    <div id="colorChangeTime_div" ref="colorChangeTime_div">{{ colorChangeTimeText }}</div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted, onBeforeUnmount } from 'vue';
+const changeTimeArrays: any = ["10", "9", "8", "7", "6", "5", "4", "3", "2", "1", "color change!"];
+const squareColor: any = ["#FF6688", "#00FF00", "#3399FF", "#FFDAB9", "blueviolet"];
+
+const can1: any = ref(null);
+const can2: any = ref(null);
+const ctx1: any = ref(null);
+const ctx2: any = ref(null);
+const canWidth: any = ref(820);
+const canHeight: any = ref(640);
+const maxWidth: any = ref(820);
+const maxHeight: any = ref(640);
+const beginGame: any = ref(false);
+const gameOver: any = ref(true);
+const score: any = ref(0);
+const scoreText: any = ref('得分:0');
+const stateText: any = ref('');
+const colorChangeTimeText: any = ref();
+let backrgound: any = ref(null);
+let squares: any = ref(null);
+let mySquare: any = ref(null);
+let beginAnim: any = ref(null);
+let lastTime: any = ref(null);
+let changeColorTime: any = ref(null);
+let loop: any = ref(null);
+
+const changeColorindex: any = ref(0);
+const totalSpeed: any = ref(3);
+const isStep: any = ref(false);
+const colorChangeTimeW: any = ref(0);
+const AnimPX: any = ref([]);
+const AnimPY: any = ref([]);
+const jump_count: any = ref(0);
+let square_main: any = ref(null);
+let game_title: any = ref(null);
+let main_box: any = ref(null);
+let login_btn: any = ref(null);
+let colorChangeTime_div: any = ref(null);
+let state_div: any = ref(null);
+let score_div: any = ref(null);
+
+function init() {
+  score.value = 0;
+  beginGame.value = false;
+  gameOver.value = false;
+  isStep.value = false;
+
+  lastTime.value = Date.now();
+  ctx1.value = can1.value.getContext("2d");
+  ctx2.value = can2.value.getContext("2d");
+  if (maxWidth.value != canWidth.value) {
+    canWidth.value = maxWidth.value;
   }
-  
-  interface SquareObj {
-    x: number[];
-    y: number[];
-    w: number[];
-    h: number[];
-    color: string[];
-    isLive: boolean[];
-    num: number;
-    init: () => void;
-    draw: () => void;
-    squareBorn: () => void;
+  if (maxHeight.value != canHeight.value) {
+    canHeight.value = maxHeight.value;
   }
-  
-  interface MySquareObj {
-    x: number;
-    y: number;
-    isLive: boolean;
-    l: number;
-    color: string;
-    toDownSpeed: number;
-    toVSpeed: number;
-    init: () => void;
-    jump: () => void;
-    toDown: () => void;
-    draw: () => void;
+
+
+  main_box.value.style.width = canWidth.value + "px";
+  main_box.value.style.height = canHeight.value + "px";
+
+  can1.value.width = canWidth.value;
+  can2.value.width = canWidth.value;
+  can1.value.height = canHeight.value;
+  can2.value.height = canHeight.value;
+
+  // 模拟 slideDown 效果
+  game_title.value.style.display = "block";
+  game_title.value.style.height = "0";
+  game_title.value.style.overflow = "hidden";
+  setTimeout(() => {
+    game_title.value.style.height = "auto";
+  }, 0);
+
+  // 模拟 delay 和 slideToggle 效果
+  setTimeout(() => {
+    login_btn.value.style.display = "block";
+    login_btn.value.style.height = "0";
+    login_btn.value.style.overflow = "hidden";
+    setTimeout(() => {
+      login_btn.value.style.height = "auto";
+    }, 10);
+  }, 500);
+
+  colorChangeTimeW.value = (canHeight.value > canWidth.value ? canWidth.value : canHeight.value) * 0.5;
+  colorChangeTime_div.value.style.width = colorChangeTimeW * 1.6 + "px";
+  colorChangeTime_div.value.style.height = colorChangeTimeW * 0.5 + "px";
+  colorChangeTime_div.value.style.marginLeft = -colorChangeTimeW * 0.8 + "px";
+  colorChangeTime_div.value.style.lineHeight = colorChangeTimeW * 0.5 + "px";
+  colorChangeTime_div.value.style.fontSize = colorChangeTimeW * 0.3 + "px";
+
+  backrgound.value = new backgroundObj();
+  backrgound.value.init();
+
+  squares.value = new squareObj();
+  squares.value.init();
+
+  mySquare.value = new mySquareObj();
+  mySquare.value.init();
+
+  beginAnim.value = new beginAnimObj();
+  beginAnim.value.init();
+}
+
+function restartInit() {
+  AnimPX.value = new Array();
+  AnimPY.value = new Array();
+  changeColorindex.value = 0;
+  jump_count.value = 0;
+
+  // 隐藏元素
+  colorChangeTime_div.value.style.display = "none";
+  score_div.value.style.display = "none";
+
+  // 初始化动画
+  beginAnim.value.init();
+
+  // 设置游戏状态
+  beginGame.value = false;
+  gameOver.value = true;
+  lastTime.value = Date.now();
+
+  // 设置游戏标题
+  game_title.value.innerHTML = "方&nbsp;块&nbsp;跳&nbsp;跃";
+
+  // 显示游戏标题(模拟slideDown效果)
+  game_title.value.style.display = "block";
+  game_title.value.style.height = "0";
+  game_title.value.style.overflow = "hidden";
+  setTimeout(() => {
+    game_title.value.style.height = "auto";
+  }, 0);
+
+  // 延迟显示登录按钮(模拟delay和slideToggle效果)
+  setTimeout(() => {
+    login_btn.value.style.display = "block";
+    login_btn.value.style.height = "0";
+    login_btn.value.style.overflow = "hidden";
+    setTimeout(() => {
+      login_btn.value.style.height = "auto";
+    }, 10);
+  }, 500);
+
+  // 设置登录按钮文本
+  login_btn.value.innerHTML = "再来一次";
+
+  // 显示状态(模拟slideDown效果)
+  state_div.value.style.display = "block";
+  state_div.value.style.height = "0";
+  state_div.value.style.overflow = "hidden";
+  setTimeout(() => {
+    state_div.value.style.height = "auto";
+  }, 500);
+
+  // 设置状态文本
+  state_div.value.innerHTML = "游戏结束,得分:" + Math.floor(score.value);
+}
+
+function game() {
+  init();
+  loop.value = setInterval(gameloop, 20);
+}
+function restart() {
+  // 调用初始化方法
+  backrgound.value.init();
+  squares.value.init();
+  mySquare.value.init();
+
+  // 更新时间戳
+  lastTime.value = Date.now();
+
+  // 隐藏元素
+  state_div.value.style.display = "none";
+  game_title.value.style.display = "none";
+  login_btn.value.style.display = "none";
+
+  // 显示分数
+  score_div.value.style.display = "block";
+
+  // 重置分数和速度
+  score.value = 0;
+  totalSpeed.value = 3;
+}
+function gameloop() {
+  backrgound.value.draw();
+  ctx2.value.clearRect(0, 0, canWidth.value, canHeight.value);
+  ctx2.value.save();
+
+  if (beginAnim.value.isLive && Date.now() - lastTime.value > 1000) {
+    beginAnim.value.draw();
   }
-  
-  interface BeginAnimObj {
-    x: number;
-    y: number;
-    isLive: boolean;
-    l: number;
-    color: string;
-    toDownSpeed: number;
-    toVSpeed: number;
-    init: () => void;
-    jump: () => void;
-    toDown: () => void;
-    draw: () => void;
+
+  if (beginGame.value && !gameOver.value) {
+    scoreText.value = `得分:${Math.floor(score.value)}`;
+    addSpeed();
+    squares.value.draw();
+    mySquare.value.draw();
+    squaresToMy();
+
+    // 添加点击事件监听器
+    main_box.value.addEventListener("click", function () {
+      mySquare.value.jump();
+    });
+  } else if (gameOver.value && !beginGame.value) {
+    // 这里可以添加游戏结束时的逻辑
   }
-  
-  const can1 = ref<HTMLCanvasElement | null>(null);
-  const can2 = ref<HTMLCanvasElement | null>(null);
-  const ctx1 = ref<CanvasRenderingContext2D | null>(null);
-  const ctx2 = ref<CanvasRenderingContext2D | null>(null);
-  const canWidth = ref(820);
-  const canHeight = ref(640);
-  const maxHeight = ref(window.innerHeight);
-  const maxWidth = ref(window.innerWidth);
-  
-  const beginGame = ref(false);
-  const gameOver = ref(false);
-  const backrgound = ref<BackgroundObj | null>(null);
-  const squares = ref<SquareObj | null>(null);
-  const mySquare = ref<MySquareObj | null>(null);
-  const beginAnim = ref<BeginAnimObj | null>(null);
-  const lastTime = ref(Date.now());
-  const changeColorTime = ref(Date.now());
-  const changeTimeArrays = ["10", "9", "8", "7", "6", "5", "4", "3", "2", "1", "颜色变化!"];
-  const changeColorIndex = ref(0);
-  const totalSpeed = ref(3);
-  const isStep = ref(false);
-  const colorChangeTimeW = ref(0);
-  const score = ref(0);
-  const showColorChange = ref(false);
-  
-  const squareColor = ["#FF6688", "#00FF00", "#3399FF", "#FFDAB9", "blueviolet"];
-  
-  const init = () => {
-    score.value = 0;
-    beginGame.value = false;
+
+  ctx2.value.restore();
+}
+function loginGame() {
+  changeColorTime.value = Date.now();
+
+  // 显示颜色变化时间div
+  colorChangeTime_div.value.style.display = "block";
+
+  // 随机设置颜色
+  const randomColor =
+    squareColor[Math.floor(Math.random() * squareColor.length)];
+  colorChangeTime_div.value.style.color = randomColor;
+
+  // 设置颜色变化时间div的内容
+  colorChangeTime_div.value.innerHTML = "" + changeTimeArrays[changeColorindex.value];
+
+  if (!gameOver.value && !beginGame.value) {
+    // 显示分数,隐藏游戏标题和方块
+    score_div.value.style.display = "block";
+    game_title.value.style.display = "none";
+    square_main.value.style.display = "none";
+
+    // 设置游戏状态
+    beginGame.value = true;
+
+    // 隐藏登录按钮
+    login_btn.value.style.display = "none";
+  } else if (gameOver.value && !beginGame.value) {
+    // 重新开始游戏
+    restart();
+
+    // 更新游戏状态
     gameOver.value = false;
-    isStep.value = false;
-    lastTime.value = Date.now();
-  
-    canWidth.value = maxWidth.value !== canWidth.value ? maxWidth.value : canWidth.value;
-    canHeight.value = maxHeight.value !== canHeight.value ? maxHeight.value : canHeight.value;
-  
-    can1.value!.width = canWidth.value;
-    can2.value!.width = canWidth.value;
-    can1.value!.height = canHeight.value;
-    can2.value!.height = canHeight.value;
-  
-    colorChangeTimeW.value = (canHeight.value > canWidth.value ? canWidth.value : canHeight.value) * 0.5;
-  
-    backrgound.value = {
-      x: [],
-      y: [],
-      w: [],
-      h: [],
-      isLive: [],
-      num: 3,
-      init() {
-        for (let i = 0; i < this.num; i++) {
-          if (i === 0) {
-            this.x[i] = canWidth.value * 0.1 * Math.random();
-          } else {
-            this.x[i] = this.x[i - 1] + this.w[i - 1] + canWidth.value * 0.2 * i * Math.random();
-          }
-          this.w[i] = canWidth.value * 0.08 + canHeight.value * Math.random() * 0.3;
-          this.h[i] = canHeight.value * 0.08 + canWidth.value * Math.random() * 0.3;
-          this.y[i] = canHeight.value * 0.2 * Math.random();
-          this.isLive[i] = true;
-        }
-      },
-      draw() {
-        ctx1.value!.clearRect(0, 0, canWidth.value, canHeight.value);
-        ctx1.value!.save();
-        for (let i = 0; i < this.num; i++) {
-          if (this.isLive[i]) {
-            this.x[i] -= 0.1 * totalSpeed.value;
-            ctx1.value!.fillStyle = "#ffffff";
-            // Draw cloud logic (simplified)
-            // ... (original cloud drawing logic here)
+    beginGame.value = true;
+  }
+
+  // 设置动画状态
+  beginAnim.value.isLive = false;
+
+  // 隐藏方块
+  square_main.value.style.display = "none";
+}
+function addSpeed() {
+  totalSpeed.value += 0.04 * 0.05;
+  score.value += 0.04;
+}
+function squaresToMy() {
+  for (var i = 0; i < squares.value.num; i++) {
+    if (squares.value.isLive[i]) {
+      if (squares.value.color[i] != mySquare.value.color) {
+        if (mySquare.value.isLive) {
+          if (
+            ((mySquare.value.x + mySquare.value.l - 1 > squares.value.x[i] &&
+              mySquare.value.x + mySquare.value.l - 1 < squares.value.x[i] + squares.value.w[i] &&
+              mySquare.value.x + mySquare.value.l - 30 > squares.value.x[i] &&
+              mySquare.value.x + mySquare.value.l - 30 <
+              squares.value.x[i] + squares.value.w[i]) ||
+              (mySquare.value.x > squares.value.x[i] &&
+                mySquare.value.x + 10 < squares.value.x[i] + squares.value.w[i] &&
+                mySquare.value.x + 10 > squares.value.x[i] &&
+                mySquare.value.x + 10 < squares.value.x[i] + squares.value.w[i])) &&
+            mySquare.value.y + mySquare.value.l > squares.value.y[i] &&
+            mySquare.value.y + mySquare.value.l < squares.value.y[i] + squares.value.h[i]
+          ) {
+            mySquare.value.y = squares.value.y[i] - mySquare.value.l;
+            mySquare.value.toVSpeed = -totalSpeed.value * 0.2;
+            mySquare.value.toDownSpeed = 0;
+            jump_count.value = 0;
           }
-          if (this.x[i] + this.w[i] < 0) {
-            this.isLive[i] = false;
+          if (
+            mySquare.value.x + mySquare.value.l > squares.value.x[i] &&
+            mySquare.value.x + mySquare.value.l < squares.value.x[i] + squares.value.w[i] &&
+            mySquare.value.y + mySquare.value.l > squares.value.y[i] &&
+            mySquare.value.y + mySquare.value.l < squares.value.y[i] + squares.value.h[i]
+          ) {
+            mySquare.value.x = squares.value.x[i] - mySquare.value.l;
           }
         }
-        ctx1.value!.restore();
-        this.cloudBorn();
-      },
-      cloudBorn() {
-        // Cloud reborn logic (simplified)
-        // ... (original cloud reborn logic here)
       }
-    };
-  
-    squares.value = {
-      x: [],
-      y: [],
-      w: [],
-      h: [],
-      color: [],
-      isLive: [],
-      num: 12,
-      init() {
-        for (let i = 0; i < this.num; i++) {
-          this.color[i] = squareColor[Math.floor(Math.random() * squareColor.length)];
-          if (i === 0) {
-            this.x[i] = 0;
-          } else {
-            this.x[i] = this.x[i - 1] + this.w[i - 1] + 1;
-          }
-          this.h[i] = canHeight.value * 0.3 + canHeight.value * 0.25 * Math.random();
-          this.w[i] = canWidth.value * 0.15 + canWidth.value * 0.06 * Math.random();
-          this.y[i] = canHeight.value - this.h[i];
-          this.isLive[i] = true;
-        }
-      },
-      draw() {
-        for (let i = 0; i < this.num; i++) {
-          if (this.isLive[i]) {
-            ctx2.value!.fillStyle = this.color[i];
-            ctx2.value!.fillRect(this.x[i], this.y[i], this.w[i], this.h[i]);
-            this.x[i] -= totalSpeed.value;
-          }
-          if (this.x[i] + this.w[i] < 0) {
-            this.isLive[i] = false;
-          }
-        }
-        this.squareBorn();
-      },
-      squareBorn() {
-        // Square reborn logic (simplified)
-        // ... (original square reborn logic here)
+    }
+  }
+}
+
+//背景
+class backgroundObj {
+  constructor() {
+    this.x = [];
+    this.y = [];
+    this.w = [];
+    this.h = [];
+    this.isLive = [];
+    this.num = 3;
+  }
+
+  init() {
+    for (let i = 0; i < this.num; i++) {
+      this.x[i] =
+        i === 0
+          ? canWidth.value * 0.1 * Math.random()
+          : this.x[i - 1] +
+          this.w[i - 1] +
+          canWidth.value * 0.2 * i * Math.random();
+
+      this.w[i] = canWidth.value * 0.08 + canHeight.value * Math.random() * 0.3;
+      this.h[i] = canHeight.value * 0.08 + canWidth.value * Math.random() * 0.3;
+      this.y[i] = canHeight.value * 0.2 * Math.random();
+      this.isLive[i] = true;
+    }
+  }
+
+  cloudBorn() {
+    for (let i = 0; i < this.num; i++) {
+      if (!this.isLive[i]) {
+        this.w[i] = canWidth.value * 0.08 + canWidth.value * Math.random() * 0.3;
+        this.h[i] = canHeight.value * 0.08 + canHeight.value * Math.random() * 0.3;
+        this.y[i] = canHeight.value * 0.2 * Math.random();
+
+        this.x[i] = i === 0 ? canWidth.value : canWidth.value + i * this.w[i - 1];
+
+        this.isLive[i] = true;
       }
-    };
-  
-    mySquare.value = {
-      x: 0,
-      y: 0,
-      isLive: true,
-      l: 40,
-      color: squareColor[0],
-      toDownSpeed: 0,
-      toVSpeed: 0,
-      init() {
-        this.x = 0;
-        this.y = 0;
-        this.isLive = true;
-        this.l = 40;
-        this.toDownSpeed = 0;
-        this.toVSpeed = 0;
-        this.color = squareColor[0];
-      },
-      jump() {
-        if (this.isLive) {
-          this.toDownSpeed = -15;
-          this.toVSpeed = 2;
-        }
-      },
-      toDown() {
-        if (this.isLive) {
-          this.toDownSpeed += 9.8 * 1 * 0.06;
-          this.y += this.toDownSpeed;
-          this.x += this.toVSpeed;
-          if (this.y + this.l > canHeight.value) {
-            this.isLive = false;
-          }
-        }
-      },
-      draw() {
-        if (this.isLive) {
-          const now = Date.now();
-          if (now - changeColorTime.value > 1000) {
-            changeColorIndex.value = ++changeColorIndex.value % changeTimeArrays.length;
-            const strColor = squareColor[Math.floor(Math.random() * squareColor.length)];
-            document.getElementById("colorChangeTime_div")!.style.color = strColor;
-            document.getElementById("colorChangeTime_div")!.innerHTML = changeTimeArrays[changeColorIndex.value];
-            if (changeColorIndex.value === 10) {
-              document.getElementById("colorChangeTime_div")!.style.fontSize = colorChangeTimeW.value * 0.15 + "px";
-              this.color = strColor;
-            } else {
-              document.getElementById("colorChangeTime_div")!.style.fontSize = colorChangeTimeW.value * 0.3 + "px";
-            }
-            changeColorTime.value = now;
-          }
-          ctx2.value!.fillStyle = this.color;
-          ctx2.value!.fillRect(this.x, this.y, this.l, this.l);
-          ctx2.value!.strokeStyle = "#ffffff";
-          ctx2.value!.strokeRect(this.x, this.y, this.l, this.l);
-          if (this.x < -100) {
-            this.isLive = false;
-          }
-        } else {
-          restartInit();
-        }
-        this.toDown();
+    }
+  }
+
+  draw() {
+    ctx1.value.clearRect(0, 0, canWidth.value, canHeight.value);
+    ctx1.value.save();
+
+    for (let i = 0; i < this.num; i++) {
+      if (!this.isLive[i]) continue;
+
+      this.x[i] -= 0.1 * totalSpeed.value;
+      const maxSize = Math.max(this.h[i], this.w[i]) * 0.15;
+      const smallSize = Math.max(this.h[i], this.w[i]) * 0.1;
+
+      // 绘制云朵的各个部分
+      const cloudParts = [
+        { x: 0.4, y: 0.1, size: maxSize },
+        { x: 0.1, y: 0.2, size: maxSize },
+        { x: 0.6, y: 0.25, size: maxSize },
+        { x: 0.5, y: 0.3, size: maxSize },
+        { x: 0.65, y: 0.22, size: maxSize },
+        { x: 0.2, y: 0.35, size: maxSize },
+        { x: 0.35, y: 0.35, size: smallSize },
+        { x: 0.3, y: 0.1, size: maxSize },
+      ];
+
+      ctx1.value.fillStyle = "#ffffff";
+      cloudParts.forEach((part) => {
+        ctx1.value.beginPath();
+        ctx1.value.arc(
+          this.x[i] + this.w[i] * part.x,
+          this.y[i] + this.h[i] * part.y,
+          part.size,
+          0,
+          Math.PI * 2
+        );
+        ctx1.value.fill();
+        ctx1.value.closePath();
+      });
+
+      if (this.x[i] + this.w[i] < 0) {
+        this.isLive[i] = false;
       }
-    };
-  
-    beginAnim.value = {
-      x: 0,
-      y: 0,
-      isLive: true,
-      l: 40,
-      color: squareColor[0],
-      toDownSpeed: 0,
-      toVSpeed: canWidth.value * 0.021,
-      init() {
-        this.isLive = true;
-        this.x = 0;
-        this.y = 0;
-        this.l = 40;
-        this.toDownSpeed = 0;
-        this.toVSpeed = canWidth.value * 0.021;
-        this.color = squareColor[0];
-      },
-      jump() {
-        if (this.isLive) {
-          this.toDownSpeed = -this.toDownSpeed;
-          this.toVSpeed = canWidth.value * 0.021 * 0.5;
-          this.x += this.toVSpeed;
-          if (this.toVSpeed + 2 < 3) {
-            this.toVSpeed += 1;
-          }
-        }
-      },
-      toDown() {
-        if (this.isLive) {
-          this.toDownSpeed += 9.8 * 1 * 0.06;
-          this.y += this.toDownSpeed;
-          this.x += this.toVSpeed;
-          if (this.y > canHeight.value) {
-            this.isLive = false;
-          }
-        }
-      },
-      draw() {
-        if (this.isLive) {
-          const squareMain = document.getElementById("square_main")!;
-          squareMain.style.left = this.x + "px";
-          squareMain.style.top = this.y + "px";
-          if (
-            this.y + this.l > canHeight.value * 0.35 &&
-            this.x + this.l * 0.5 < canWidth.value * 0.5 + 120 &&
-            this.x + this.l * 0.5 > canWidth.value * 0.5 - 120
-          ) {
-            this.jump();
-            document.getElementById("game_title")!.innerHTML = "方&nbsp;块&nbsp;<i style='font-size: 46px;color:#FF6688;'>跳&nbsp;</i>跃";
-          }
-          this.toDown();
-        } else {
-          const squareMain = document.getElementById("square_main")!;
-          squareMain.style.display = "none";
+    }
+
+    ctx1.value.restore();
+    this.cloudBorn();
+  }
+}
+
+//底下方块
+class squareObj {
+  constructor() {
+    this.num = 12;
+    this.x = [];
+    this.y = [];
+    this.w = [];
+    this.h = [];
+    this.color = [];
+    this.isLive = [];
+  }
+
+  init() {
+    let repeatColorCount = 0;
+
+    for (let i = 0; i < this.num; i++) {
+      // Random color selection with constraints
+      this.color[i] = this.getRandomColor(i, repeatColorCount);
+
+      // Position and size initialization
+      if (i === 0) {
+        this.x[i] = 0;
+      } else {
+        this.x[i] = this.x[i - 1] + this.w[i - 1] + 1;
+      }
+
+      this.h[i] = canHeight.value * 0.3 + canHeight.value * 0.25 * Math.random();
+      this.w[i] = canWidth.value * 0.15 + canWidth.value * 0.06 * Math.random();
+      this.y[i] = canHeight.value - this.h[i];
+      this.isLive[i] = true;
+
+      // Update repeat color count
+      repeatColorCount =
+        this.color[i] === this.color[i - 1] ? repeatColorCount + 1 : 0;
+
+      // Handle consecutive colors
+      if (repeatColorCount > 1) {
+        this.adjustColor(i);
+      }
+    }
+  }
+
+  getRandomColor(i: any, repeatColorCount: any) {
+    const randomIndex = Math.floor(Math.random() * squareColor.length);
+    let color = squareColor[randomIndex];
+
+    // For the first element, check against last element
+    if (i === 0 && color === this.color[this.num - 1]) {
+      const lastColorIndex = squareColor.indexOf(
+        this.color[this.num - 1]
+      );
+      color =
+        squareColor[
+        (lastColorIndex - 1 + squareColor.length) % squareColor.length
+        ];
+    }
+    // For other elements, check against previous element
+    else if (
+      i > 0 &&
+      color === this.color[i - 1] &&
+      repeatColorCount > 1
+    ) {
+      const currentColorIndex = squareColor.indexOf(color);
+      color = squareColor[(currentColorIndex + 1) % squareColor.length];
+    }
+
+    return color;
+  }
+
+  adjustColor(i: any) {
+    if (i === 0) {
+      const lastColorIndex = squareColor.indexOf(
+        this.color[this.num - 1]
+      );
+      this.color[i] =
+        squareColor[
+        (lastColorIndex - 1 + squareColor.length) % squareColor.length
+        ];
+    } else {
+      const currentColorIndex = squareColor.indexOf(this.color[i]);
+      this.color[i] =
+        squareColor[(currentColorIndex + 1) % squareColor.length];
+    }
+  }
+
+  squareBorn() {
+    const maxX = Math.max(
+      ...this.x.map((val, idx) => val + (this.w[idx] || 0))
+    );
+    const maxI = this.x.indexOf(
+      maxX - (this.w[this.x.indexOf(maxX)] || 0)
+    );
+
+    for (let i = 0; i < this.num; i++) {
+      if (!this.isLive[i]) {
+        this.x[i] = maxX + 1;
+        this.h[i] = canHeight.value * 0.25 + canHeight.value * 0.35 * Math.random();
+        this.w[i] = canWidth.value * 0.14 + canWidth.value * 0.1 * Math.random();
+        this.y[i] = canHeight - this.h[i];
+
+        let repeatColorCount = 0;
+        if (i === 0 && this.isLive[this.num - 1]) {
+          this.color[i] = this.getRandomColorForBorn(
+            this.num - 1,
+            repeatColorCount
+          );
+        } else if (i > 0 && this.isLive[i - 1]) {
+          this.color[i] = this.getRandomColorForBorn(
+            i - 1,
+            repeatColorCount
+          );
         }
+
+        this.isLive[i] = true;
+        return;
       }
-    };
-  
-    backrgound.value.init();
-    squares.value.init();
-    mySquare.value.init();
-    beginAnim.value.init();
-  };
-  
-  const restart = () => {
-    backrgound.value!.init();
-    squares.value!.init();
-    mySquare.value!.init();
-    lastTime.value = Date.now();
-    document.getElementById("state")!.style.display = "none";
-    document.getElementById("game_title")!.style.display = "none";
-    document.getElementById("login_btn")!.style.display = "none";
-    document.getElementById("score")!.style.display = "block";
-    score.value = 0;
-    totalSpeed.value = 3;
-  };
-  
-  const gameloop = () => {
-    backrgound.value!.draw();
-    ctx2.value!.clearRect(0, 0, canWidth.value, canHeight.value);
-    ctx2.value!.save();
-    if (beginAnim.value!.isLive && Date.now() - lastTime.value > 1000) {
-      beginAnim.value!.draw();
     }
-  
-    if (beginGame.value && !gameOver.value) {
-      document.getElementById("score")!.innerHTML = "得分:" + Math.floor(score.value);
-      addSpeed();
-      squares.value!.draw();
-      mySquare.value!.draw();
-      // squaresToMy(); // Collision detection logic needs to be adapted for Vue
+  }
+
+  getRandomColorForBorn(prevIndex: any, repeatColorCount: any) {
+    const randomIndex = Math.floor(Math.random() * 3);
+    let color = squareColor[randomIndex];
+
+    if (color === this.color[prevIndex] && repeatColorCount > 1) {
+      const currentColorIndex = squareColor.indexOf(color);
+      color = squareColor[(currentColorIndex + 1) % squareColor.length];
     }
-    ctx2.value!.restore();
-  };
-  
-  const loginGame = () => {
-    changeColorTime.value = Date.now();
-    document.getElementById("colorChangeTime_div")!.style.display = "block";
-    document.getElementById("colorChangeTime_div")!.style.color = squareColor[Math.floor(Math.random() * squareColor.length)];
-    document.getElementById("colorChangeTime_div")!.innerHTML = changeTimeArrays[changeColorIndex.value];
-    if (!gameOver.value && !beginGame.value) {
-      document.getElementById("score")!.style.display = "block";
-      document.getElementById("game_title")!.style.display = "none";
-      document.getElementById("square_main")!.style.display = "none";
-      beginGame.value = true;
-      document.getElementById("login_btn")!.style.display = "none";
-    } else if (gameOver.value && !beginGame.value) {
-      restart();
-      gameOver.value = false;
-      beginGame.value = true;
+
+    return color;
+  }
+
+  draw() {
+    for (let i = 0; i < this.num; i++) {
+      if (this.isLive[i]) {
+        ctx2.value.fillStyle = this.color[i];
+        ctx2.value.beginPath();
+        ctx2.value.fillRect(this.x[i], this.y[i], this.w[i], this.h[i]);
+        ctx2.value.fill();
+        ctx2.value.closePath();
+        this.x[i] -= totalSpeed.value;
+      }
+
+      if (this.x[i] + this.w[i] < 0) {
+        this.isLive[i] = false;
+      }
     }
-    beginAnim.value!.isLive = false;
-    document.getElementById("square_main")!.style.display = "none";
-  };
-  
-  const addSpeed = () => {
-    totalSpeed.value += 0.04 * 0.05;
-    score.value += 0.04;
-  };
-  
-  const restartInit = () => {
-    changeColorIndex.value = 0;
-    document.getElementById("colorChangeTime_div")!.style.display = "none";
-    beginAnim.value!.init();
-    beginGame.value = false;
-    gameOver.value = true;
-    lastTime.value = Date.now();
-    document.getElementById("game_title")!.innerHTML = "方&nbsp;块&nbsp;跳&nbsp;跃";
-    document.getElementById("score")!.style.display = "none";
-    document.getElementById("game_title")!.style.display = "block";
-    document.getElementById("login_btn")!.style.display = "block";
-    document.getElementById("login_btn")!.innerHTML = "再来一次";
-    document.getElementById("state")!.style.display = "block";
-    document.getElementById("state")!.innerHTML = "游戏结束,得分:" + Math.floor(score.value);
-  };
-  
-  onMounted(() => {
-    ctx1.value = can1.value!.getContext("2d");
-    ctx2.value = can2.value!.getContext("2d");
-    init();
-    const loop = setInterval(gameloop, 20);
-    onBeforeUnmount(() => clearInterval(loop));
-  });
-  </script>
-  
-  <style scoped>
-  /* CSS styles from the original HTML */
-  #main_box {
-    margin: 0px auto;
-    width: 420px;
-    height: 580px;
-    background: skyblue;
-    position: relative;
-    overflow: hidden;
-    z-index: 9999;
+
+    this.squareBorn();
   }
-  .can {
-    position: absolute;
-    top: 0px;
-    left: 0px;
+}
+
+//我的方块
+class mySquareObj {
+  constructor() {
+    this.x;
+    this.y;
+    this.isLive; // 生命状态
+    this.l = 40; // 正方形边长
+    this.color;
+    this.toDownSpeed = 0; // 垂直方向速度
+    this.toVSpeed = 0; // 水平方向速度
   }
-  #score {
-    width: auto;
-    height: 40px;
-    font-size: 22px;
-    color: #7fffd4;
-    position: absolute;
-    top: 10px;
-    left: 10px;
+
+  init() {
+    this.isLive = true;
+    this.x = 0;
+    this.y = 0;
+    this.l = 40;
+    this.toDownSpeed = 0;
+    this.toVSpeed = 0;
+    this.color = squareColor[0];
   }
-  #game_title {
-    display: none;
-    position: absolute;
-    width: 240px;
-    height: 80px;
-    line-height: 80px;
-    text-align: center;
-    top: 35%;
-    left: 50%;
-    margin-left: -120px;
-    font-size: 42px;
-    font-family: "century gothic";
-    font-weight: bolder;
-    text-shadow: 4px 3px 2px black;
-    color: #fff;
+
+  jump() {
+    if (this.isLive) {
+      this.toDownSpeed = -15;
+      this.toVSpeed = 2;
+      jump_count.value++;
+      if (this.x + this.l > canWidth.value) {
+        this.x = canWidth.value - this.l;
+      }
+    }
+  }
+
+  toDown() {
+    if (this.isLive) {
+      this.toDownSpeed += 9.8 * 1 * 0.06;
+      this.y += this.toDownSpeed;
+      this.x += this.toVSpeed;
+      if (this.y + this.l > canHeight.value) {
+        this.isLive = false;
+      }
+    }
   }
-  #login_btn {
-    display: none;
-    position: absolute;
-    bottom: 100px;
-    left: 50%;
-    width: 100px;
-    height: 40px;
-    margin-left: -50px;
-    line-height: 40px;
-    text-align: center;
-    border-radius: 12px;
-    border: 2px solid #ffffff;
-    font-size: 18px;
-    color: #000000;
-    font-weight: normal;
-    background: peachpuff;
+
+  draw() {
+    if (this.isLive) {
+      const now = Date.now();
+      if (now - changeColorTime.value > 1000) {
+        changeColorindex.value = ++changeColorindex.value % changeTimeArrays.length;
+        const strColor =
+          "" +
+          squareColor[Math.floor(Math.random() * squareColor.length)];
+
+
+        // 设置颜色和内容
+        colorChangeTime_div.value.style.color = strColor;
+        colorChangeTime_div.value.textContent =
+          "" + changeTimeArrays[changeColorindex.value];
+
+        if (changeColorindex.value === 10) {
+          colorChangeTime_div.value.style.fontSize =
+            colorChangeTimeW * 0.15 + "px";
+          this.color = strColor;
+        } else {
+          colorChangeTime_div.value.style.fontSize =
+            colorChangeTimeW * 0.3 + "px";
+        }
+
+        changeColorTime.value = now;
+      }
+      ctx2.value.fillStyle = this.color + "";
+      ctx2.value.rect(this.x, this.y, this.l, this.l);
+      ctx2.value.fill();
+      ctx2.value.lineWidth = 3;
+      ctx2.value.radiusX = 3;
+
+      ctx2.value.strokeStyle = "#ffffff";
+      ctx2.value.stroke();
+      if (this.x < -100) {
+        this.isLive = false;
+      }
+    } else {
+      restartInit();
+    }
+    this.toDown();
   }
-  #login_btn:hover {
-    color: #fff;
+}
+
+//动画
+class beginAnimObj {
+  constructor() {
+    this.x;
+    this.y;
+    this.isLive;
+    this.l = 40; // 正方形边长
+    this.color;
+    this.toDownSpeed = 0; // 垂直方向速度
+    this.toVSpeed = canWidth.value * 0.021; // 水平方向速度
   }
-  #login_btn:active {
-    background: #ffffff;
-    color: #000000;
+
+  init() {
+    this.isLive = true;
+    this.x = 0;
+    this.y = 0;
+    this.toDownSpeed = 0;
+    this.toVSpeed = canWidth.value * 0.021;
+    this.color = squareColor[0];
   }
-  #square_main {
-    width: 40px;
-    height: 40px;
-    position: absolute;
-    border: 2px solid #ffffff;
-    display: none;
-    background: #ff6688;
+
+  jump() {
+    if (this.isLive) {
+      this.toDownSpeed = -this.toDownSpeed;
+      this.toVSpeed = canWidth.value * 0.021 * 0.5;
+      jump_count.value++;
+      if (this.x + this.l > canWidth.value) {
+        this.x = canWidth.value - this.l;
+      }
+      this.x += this.toVSpeed;
+      if (this.toVSpeed + 2 < 3) {
+        this.toVSpeed += 1;
+      }
+    }
   }
-  #state {
-    width: 280px;
-    height: 60px;
-    font-size: 18px;
-    font-weight: bolder;
-    text-shadow: #fdf5e6;
-    color: blueviolet;
-    font-family: "arial narrow";
-    position: absolute;
-    top: 45%;
-    left: 50%;
-    line-height: 60px;
-    text-align: center;
-    margin-left: -140px;
-    display: none;
+
+  toDown() {
+    if (this.isLive) {
+      this.toDownSpeed += 9.8 * 1 * 0.06;
+      this.y += this.toDownSpeed;
+      this.x += this.toVSpeed;
+      if (this.y > canHeight.value) {
+        this.isLive = false;
+      }
+    }
   }
-  #colorChangeTime_div {
-    width: 200px;
-    height: 50px;
-    line-height: 50px;
-    position: absolute;
-    text-align: center;
-    top: 3%;
-    left: 50%;
-    display: none;
-    color: #ffffff;
-    font-size: 40px;
+
+  draw() {
+    if (this.isLive) {
+
+      square_main.value.style.display = "block";
+      square_main.value.style.left = this.x + "px";
+      square_main.value.style.top = this.y + "px";
+
+      if (
+        this.y + this.l > canHeight.value * 0.35 &&
+        this.x + this.l * 0.5 < canWidth.value * 0.5 + 120 &&
+        this.x + this.l * 0.5 > canWidth.value * 0.5 - 120
+      ) {
+        this.jump();
+        game_title.value.innerHTML =
+          "方&nbsp;块&nbsp;<i style='font-size: 46px;color:#FF6688;'>跳&nbsp;</i>跃";
+      }
+
+      ctx2.value.restore();
+      this.toDown();
+    } else {
+      square_main.value.style.display = "none";
+    }
   }
-  </style>
+}
+
+
+
+onMounted(() => {
+  game();
+});
+
+onBeforeUnmount(() => {
+  clearInterval(loop.value);
+});
+</script>
+
+<style scoped>
+* {
+  padding: 0px;
+  margin: 0px;
+}
+
+a {
+  text-decoration: none;
+  list-style: none;
+  color: rgb(0, 0, 0);
+}
+
+#main_box {
+  margin: 0px auto;
+  width: 420px;
+  height: 580px;
+  background: skyblue;
+  position: relative;
+  overflow: hidden;
+}
+
+.can {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+}
+
+#score {
+  width: auto;
+  height: 40px;
+  font-size: 22px;
+  color: #7fffd4;
+  position: absolute;
+  top: 10px;
+  left: 10px;
+  display: none;
+}
+
+#game_title {
+  display: none;
+  position: absolute;
+  width: 240px;
+  height: 80px;
+  line-height: 80px;
+  text-align: center;
+  top: 35%;
+  left: 50%;
+  margin-left: -120px;
+  font-size: 42px;
+  font-family: "century gothic";
+  font-weight: bolder;
+  text-shadow: 4px 3px 2px black;
+  color: #fff;
+}
+
+#login_btn {
+  display: none;
+  position: absolute;
+  bottom: 100px;
+  left: 50%;
+  width: 100px;
+  height: 40px;
+  margin-left: -50px;
+  line-height: 40px;
+  text-align: center;
+  border-radius: 12px;
+  border: 2px solid #ffffff;
+  font-size: 18px;
+  color: #000000;
+  font-weight: normal;
+  background: peachpuff;
+}
+
+#login_btn:hover {
+  color: #fff;
+}
+
+#login_btn:active {
+  background: #ffffff;
+  color: #000000;
+}
+
+#square_main {
+  width: 40px;
+  height: 40px;
+  position: absolute;
+  top: 0px;
+  left: 0px;
+  border: 2px solid #ffffff;
+  display: none;
+  background: #ff6688;
+}
+
+#state {
+  width: 280px;
+  height: 60px;
+  font-size: 18px;
+  font-weight: bolder;
+  text-shadow: #fdf5e6;
+  color: blueviolet;
+  font-family: "arial narrow";
+  position: absolute;
+  top: 45%;
+  left: 50%;
+  line-height: 60px;
+  text-align: center;
+  margin-left: -140px;
+  display: none;
+}
+
+#colorChangeTime_div {
+  width: 200px;
+  height: 50px;
+  line-height: 50px;
+  position: absolute;
+  text-align: center;
+  top: 3%;
+  left: 50%;
+  display: none;
+  color: #ffffff;
+  font-size: 40px;
+}
+</style>

+ 3 - 0
src/types/components.d.ts

@@ -8,6 +8,7 @@ export {}
 declare module 'vue' {
   export interface GlobalComponents {
     ChooseStudent: typeof import('./../components/ChooseStudent/index.vue')['default']
+    copy: typeof import('./../components/SquareGame/index copy.vue')['default']
     ElIcon: typeof import('element-plus/es')['ElIcon']
     ElInput: typeof import('element-plus/es')['ElInput']
     ElOption: typeof import('element-plus/es')['ElOption']
@@ -15,6 +16,8 @@ declare module 'vue' {
     ElSwitch: typeof import('element-plus/es')['ElSwitch']
     FaceWindow: typeof import('./../components/FaceWindow/index.vue')['default']
     Header: typeof import('./../components/Header/index.vue')['default']
+    'Index copy': typeof import('./../components/SquareGame/index copy.vue')['default']
+    Index2: typeof import('./../components/SquareGame/index2.vue')['default']
     JumpRopeGame: typeof import('./../components/JumpRopeGame/index.vue')['default']
     MultipleItem: typeof import('./../components/MultipleItem/index.vue')['default']
     MultipleItemRanking: typeof import('./../components/MultipleItemRanking/index.vue')['default']