【问题标题】:Unable to update and display the correct final scores after a player has won a Ping Pong match球员赢得乒乓球比赛后无法更新和显示正确的最终比分
【发布时间】:2017-09-22 21:26:42
【问题描述】:

我使用 JavaScript 构建了一个乒乓球游戏,并试图在每场比赛后更新“记分牌”上的分数。目前,计分板上两名球员的得分都在某种计数器循环上,并且不会停止。我希望在每场比赛后将获胜球员的统计数据添加到记分牌中。我如何才能在记分板上反映每个玩家的正确总胜数。您的帮助将不胜感激!

Link to Fiddle

<body>
  <h1>Ping Pong</h1>
  <canvas id="gameCanvas" width="800" height="600"></canvas>
  <div id="sb">
    <h1>SCOREBOARD</h1>
    <ul>
      <li>Player 1: <span id="player_1">0</span></li>
      <li> Player 2: <span id="player_2">0</span></li>
    </ul>
  </div>



  <script>
var count1_final = 0;
var count2_final = 0;

var canvas;
var canvasContext;
var ballX = 50;
var ballY = 50;
var ballSpeedX = 10;
var ballSpeedY = 4;

var player1Score = 0;
var player2Score = 0;
const WINNING_SCORE = 2;

var showingWinScreen = false;

var paddle1Y = 250;
var paddle2Y = 250;
const PADDLE_THICKNESS = 10;
const PADDLE_HEIGHT = 100;

function calculateMousePos(evt) {
  var rect = canvas.getBoundingClientRect();
  var root = document.documentElement;
  var mouseX = evt.clientX - rect.left - root.scrollLeft;
  var mouseY = evt.clientY - rect.top - root.scrollTop;
  return {
    x:mouseX,
    y:mouseY
  };
}

function handleMouseClick(evt) {
  if(showingWinScreen) {
    player1Score = 0;
    player2Score = 0;
    showingWinScreen = false;
  }
}

window.onload = function() {
  canvas = document.getElementById('gameCanvas');
  canvasContext = canvas.getContext('2d');

  var framesPerSecond = 30;
  setInterval(function() {
      moveEverything();
      drawEverything();
    }, 1000/framesPerSecond);

  canvas.addEventListener('mousedown', handleMouseClick);

  canvas.addEventListener('mousemove',
    function(evt) {
      var mousePos = calculateMousePos(evt);
      paddle1Y = mousePos.y - (PADDLE_HEIGHT/2);
    });
}

function ballReset() {
  var count1_final = 0;
  var count2_final = 0;
  if(player1Score >= WINNING_SCORE ||
    player2Score >= WINNING_SCORE) {

    showingWinScreen = true;

  }

  ballSpeedX = -ballSpeedX;
  ballX = canvas.width/2;
  ballY = canvas.height/2;
}

function computerMovement() {
  var paddle2YCenter = paddle2Y + (PADDLE_HEIGHT/2);
  if(paddle2YCenter < ballY - 35) {
    paddle2Y = paddle2Y + 6;
  } else if(paddle2YCenter > ballY + 35) {
    paddle2Y = paddle2Y - 6;
  }
}

function moveEverything() {
  if(showingWinScreen) {
    return;
  }

  computerMovement();

  ballX = ballX + ballSpeedX;
  ballY = ballY + ballSpeedY;

  if(ballX < 0) {
    if(ballY > paddle1Y &&
      ballY < paddle1Y+PADDLE_HEIGHT) {
      ballSpeedX = -ballSpeedX;

      var deltaY = ballY
          -(paddle1Y+PADDLE_HEIGHT/2);
      ballSpeedY = deltaY * 0.35;
    } else {
      player2Score++; // must be BEFORE ballReset()
      ballReset();
    }
  }
  if(ballX > canvas.width) {
    if(ballY > paddle2Y &&
      ballY < paddle2Y+PADDLE_HEIGHT) {
      ballSpeedX = -ballSpeedX;

      var deltaY = ballY
          -(paddle2Y+PADDLE_HEIGHT/2);
      ballSpeedY = deltaY * 0.35;
    } else {
      player1Score++; // must be BEFORE ballReset()
      ballReset();
    }
  }
  if(ballY < 0) {
    ballSpeedY = -ballSpeedY;
  }
  if(ballY > canvas.height) {
    ballSpeedY = -ballSpeedY;
  }
}

function drawNet() {
  for(var i=0;i<canvas.height;i+=40) {
    colorRect(canvas.width/2-1,i,2,20,'white');
  }
}


function drawEverything() {
  // next line blanks out the screen with black
  colorRect(0,0,canvas.width,canvas.height,'black');

  if(showingWinScreen) {
    canvasContext.fillStyle = 'white';

    if(player1Score >= WINNING_SCORE) {
      canvasContext.fillText("Player 1 Won", 350, 200);
      // var count1 = 0;
      // var count1_final = count1 + 1;
      // player1final_score++;
      count1_final++;
      document.getElementById("player_1").innerHTML = count1_final;
      console.log(count1_final)

    } else if(player2Score >= WINNING_SCORE) {
      canvasContext.fillText("Player 2 Won", 350, 200);
      // var count2 = 0;
      // var count2_final = count2 + 1;
      // player2final_score++;
      count2_final++;
      // console.log(player2final_score)
      document.getElementById("player_2").innerHTML = count2_final;
      console.log(count2_final)

    }

    canvasContext.fillText("Play Again", 350, 500);
    return;
  }

  drawNet();

  // this is left player paddle
  colorRect(0,paddle1Y,PADDLE_THICKNESS,PADDLE_HEIGHT,'white');

  // this is right computer paddle
  colorRect(canvas.width-PADDLE_THICKNESS,paddle2Y,PADDLE_THICKNESS,PADDLE_HEIGHT,'white');

  // next line draws the ball
  colorCircle(ballX, ballY, 10, 'white');

  canvasContext.fillText(player1Score, 100, 100);
  canvasContext.fillText(player2Score, canvas.width-100, 100);
}

function colorCircle(centerX, centerY, radius, drawColor) {
  canvasContext.fillStyle = drawColor;
  canvasContext.beginPath();
  canvasContext.arc(centerX, centerY, radius, 0,Math.PI*2,true);
  canvasContext.fill();
}

function colorRect(leftX,topY, width,height, drawColor) {
  canvasContext.fillStyle = drawColor;
  canvasContext.fillRect(leftX,topY, width,height);
}
</script>
</head>
</body>

body {
  background: #283048;  /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #859398, #283048);  /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #859398, #283048); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */

}

h1 {
  color: white;
  text-align: center;
}

#gc {
  float: left;
}

#sb {
  float: right;
  margin-right: 50px;
  border: 2px solid;
  padding: 20px;
}

【问题讨论】:

    标签: javascript html css loops counter


    【解决方案1】:

    这两行将始终将count1 设置为零,然后将count1_final 设置为0 + 1 == 1,以下几行对于count2_final 也是如此。

    if(player1Score >= WINNING_SCORE) {
        canvasContext.fillText("Player 1 Won", 350, 200);
        var count1 = 0;                    // <---------
        var count1_final = count1 + 1;     // <---------
        // player1final_score++;
        console.log(player1final_score)
        document.getElementById("player_1").innerHTML = count1_final;
    }
    

    您需要检索 count1_final 并在that 中添加一个,这意味着您需要将 count1_final 和 count2_final 存储在@之外的某个位置 987654327@ 功能。用var 在其中声明它们会使它们成为该函数的局部变量,并且每次调用该函数时它们都会重新初始化为零。

    您可能可以在 ballReset 中执行此操作 -- 在检查分数时 &gt;= WINNING_SCORE 您还可以检查谁获胜并在他们的获胜次数中加一:count1_final++

    function ballReset() {
        if (player1Score >= WINNING_SCORE ||
            player2Score >= WINNING_SCORE)
        {
            showingWinScreen = true;
            if (player1Score > player2Score) {
                count1_final++;
            }
            else {
                count2_final++;
            }
        }
    }
    

    【讨论】:

    • 感谢您的输入,计分板上的球员总分仍然不会超过1。这是我添加的内容:function ballReset() { if(player1Score >= WINNING_SCORE || player2Score > = WINNING_SCORE) { 显示WinScreen = true; if (player1Score > player2Score) { count1_final++; document.getElementById("player_1").innerHTML = count1_final; } 其他 { count2_final++; document.getElementById("player_2").innerHTML = count2_final; } } }
    • 我在回答您有player1Score player1final_scorecount1count1_final 后注意到,我不清楚这四个是什么意思(每个玩家)。在我的脑海中,我认为每个玩家只需要 2 个变量:玩家在当前游戏中的当前得分,以及玩家赢得的游戏数。如果您想进行统计,您可以添加第三个玩家在所有游戏中的总得分。在不知道这些变量的确切用途(例如,进行彻底的分析,可能运行您的程序)的情况下,我无法更具体。要点是不要将变量归零。
    • 是的。我注意到 player1final_score 和 player2final_score 变量不是必需的并将它们取出。我必须保留 player1Score 和 player2Score bc,这是黑色画布上实时游戏的当前分数。使用我更新的代码,我在获胜后玩家的记分牌上的游戏最终游戏得分在某种计数器循环上,数字不会停止上升。我只是希望他们每赢一场就加 1 分。
    • 我在下面列出了我的游戏最新版本的小提琴链接。此外,我很想在游戏中加入第三位玩家!我不知道该怎么做,但如果我能在记分板上有更多的球员和统计数据,那就太棒了。 jsfiddle.net/1nm4554L@Stephen P
    • 您的建议对我很有帮助,如果您有任何其他建议,请告诉我 - 谢谢!
    【解决方案2】:

    相关代码:

    if(player1Score >= WINNING_SCORE) {
          canvasContext.fillText("Player 1 Won", 350, 200);
          var count1 = 0;
          var count1_final = count1 + 1;
          // player1final_score++;
          console.log(player1final_score)
          document.getElementById("player_1").innerHTML = count1_final;
    
        } else if(player2Score >= WINNING_SCORE) {
          canvasContext.fillText("Player 2 Won", 350, 200);
          var count2 = 0;
          var count2_final = count2 + 1;
          console.log(player2final_score)
          document.getElementById("player_2").innerHTML = count2_final;
    
        }
    

    有问题的文字在这里:

    var count1 = 0;
    var count1_final = count1 + 1;
    

    您是说将计数设置回零,然后将其增加 1,因此分数不会超过 1。

    作为一种解决方案,这些表示玩家获胜次数的变量应该在全局范围内定义,然后只在“win”函数中递增它们——在递增之前不要将它们设置为零。

    编辑:您现在更改了代码,您的问题已经完全不同,但我将再次向您展示错误的来源。它与程序的逻辑流程有关。你有:

    var framesPerSecond = 30;
      setInterval(function() {
          moveEverything();
          drawEverything();
        }, 1000/framesPerSecond);
    

    在整个程序中不断触发。但是,即使玩家获胜,您仍然会不断调用drawEverything(),并且在您的drawEverything() 函数中是您的获胜计数器:

    function drawEverything() {
      // next line blanks out the screen with black
      colorRect(0,0,canvas.width,canvas.height,'black');
    
      if(showingWinScreen) {
        canvasContext.fillStyle = 'white';
    
        if(player1Score >= WINNING_SCORE) {
          canvasContext.fillText("Player 1 Won", 350, 200);
          count1_final++; // <-- here
          document.getElementById("player_1").innerHTML = count1_final;
          console.log(count1_final) <-- evidence here, count goes up constantly in the console
    
        }
    ... 
    }
    

    换句话说,您需要重新考虑程序的流程。你怎么能让玩家只“赢”一次?

    【讨论】:

    • 感谢您的反馈。你是对的,我取出了你在上面的消息中陈述的那些变量,并在页面顶部添加了 count1_final 和 count2_final 作为全局变量设置为“0”。在对我的代码进行修改后,玩家获胜后我的最终分数处于某种奇怪的循环中,并且数字不会停止上升。如果您对如何在记分板上获得正确的获胜次数有任何其他建议,我将不胜感激。我更新了上面的小提琴以供参考。
    • 显然您已经用一个错误替换了另一个错误。我能给你的最好建议是熟悉浏览器的开发工具(IE、Chrome 等 > 按 F12),在代码中设置断点(例如,如果你遇到问题,可能在分数增加的地方增加太多),运行导致问题的行为,并准确观察代码中发生的情况。尝试阅读这样的内容:developers.google.com/web/tools/chrome-devtools/javascript
    • @MissyBur 我已更新我的答案以回应您的新问题。我没有看到您在编辑中包含了 jsFiddle,因为它嵌入在您的代码块中。我也建议对您的帖子进行编辑。
    【解决方案3】:

    我能够找出问题所在。我添加了一个新函数 addFinalScore 并在 ballReset 函数中调用该函数。现在记分牌正在正确更新分数。

    JSFiddle

    <body>
      <h1>Ping Pong</h1>
      <canvas id="gameCanvas" width="800" height="600"></canvas>
      <div id="sb">
        <h1>SCOREBOARD</h1>
        <ul>
          <li>Player 1: <span id="player_1">0</span></li>
          <li> Player 2: <span id="player_2">0</span></li>
        </ul>
      </div>
    
    
    
      <script>
    var count1_final = 0;
    var count2_final = 0;
    
    var canvas;
    var canvasContext;
    var ballX = 50;
    var ballY = 50;
    var ballSpeedX = 10;
    var ballSpeedY = 4;
    
    var player1Score = 0;
    var player2Score = 0;
    const WINNING_SCORE = 2;
    
    var showingWinScreen = false;
    
    var paddle1Y = 250;
    var paddle2Y = 250;
    const PADDLE_THICKNESS = 10;
    const PADDLE_HEIGHT = 100;
    
    function calculateMousePos(evt) {
      var rect = canvas.getBoundingClientRect();
      var root = document.documentElement;
      var mouseX = evt.clientX - rect.left - root.scrollLeft;
      var mouseY = evt.clientY - rect.top - root.scrollTop;
      return {
        x:mouseX,
        y:mouseY
      };
    }
    
    function handleMouseClick(evt) {
      if(showingWinScreen) {
        player1Score = 0;
        player2Score = 0;
        showingWinScreen = false;
      }
    }
    
    window.onload = function() {
      canvas = document.getElementById('gameCanvas');
      canvasContext = canvas.getContext('2d');
    
      var framesPerSecond = 30;
      setInterval(function() {
          moveEverything();
          drawEverything();
        }, 1000/framesPerSecond);
    
      canvas.addEventListener('mousedown', handleMouseClick);
    
      canvas.addEventListener('mousemove',
        function(evt) {
          var mousePos = calculateMousePos(evt);
          paddle1Y = mousePos.y - (PADDLE_HEIGHT/2);
        });
    }
    
    function ballReset() {
      if(player1Score >= WINNING_SCORE ||
        player2Score >= WINNING_SCORE) {
    
        showingWinScreen = true;
        addFinalScore()
      }
    
    
      ballSpeedX = -ballSpeedX;
      ballX = canvas.width/2;
      ballY = canvas.height/2;
    }
    
    function computerMovement() {
      var paddle2YCenter = paddle2Y + (PADDLE_HEIGHT/2);
      if(paddle2YCenter < ballY - 35) {
        paddle2Y = paddle2Y + 6;
      } else if(paddle2YCenter > ballY + 35) {
        paddle2Y = paddle2Y - 6;
      }
    }
    
    function moveEverything() {
      if(showingWinScreen) {
        return;
      }
    
      computerMovement();
    
      ballX = ballX + ballSpeedX;
      ballY = ballY + ballSpeedY;
    
      if(ballX < 0) {
        if(ballY > paddle1Y &&
          ballY < paddle1Y+PADDLE_HEIGHT) {
          ballSpeedX = -ballSpeedX;
    
          var deltaY = ballY
              -(paddle1Y+PADDLE_HEIGHT/2);
          ballSpeedY = deltaY * 0.35;
        } else {
          player2Score++; // must be BEFORE ballReset()
          ballReset();
        }
      }
      if(ballX > canvas.width) {
        if(ballY > paddle2Y &&
          ballY < paddle2Y+PADDLE_HEIGHT) {
          ballSpeedX = -ballSpeedX;
    
          var deltaY = ballY
              -(paddle2Y+PADDLE_HEIGHT/2);
          ballSpeedY = deltaY * 0.35;
        } else {
          player1Score++; // must be BEFORE ballReset()
          ballReset();
        }
      }
      if(ballY < 0) {
        ballSpeedY = -ballSpeedY;
      }
      if(ballY > canvas.height) {
        ballSpeedY = -ballSpeedY;
      }
    }
    
    function drawNet() {
      for(var i=0;i<canvas.height;i+=40) {
        colorRect(canvas.width/2-1,i,2,20,'white');
      }
    }
    
    
    function addFinalScore() {
      if(player1Score >= WINNING_SCORE) {
        count1_final++;
        document.getElementById("player_1").innerHTML = count1_final;
    
      } else {
        count2_final++;
        document.getElementById("player_2").innerHTML = count2_final;
      }
    }
    
    function drawEverything() {
      // next line blanks out the screen with black
      colorRect(0,0,canvas.width,canvas.height,'black');
    
      if(showingWinScreen) {
        canvasContext.fillStyle = 'white';
    
        if(player1Score >= WINNING_SCORE) {
          canvasContext.fillText("Player 1 Won", 350, 200);
          // count1_final++;
          // document.getElementById("player_1").innerHTML = count1_final;
          console.log(count1_final)
    
        } else if(player2Score >= WINNING_SCORE) {
          canvasContext.fillText("Player 2 Won", 350, 200);
          // count2_final++;
          // console.log(player2final_score)
          // document.getElementById("player_2").innerHTML = count2_final;
          console.log(count2_final)
    
        }
    
        canvasContext.fillText("Play Again", 350, 500);
        return;
      }
    
      drawNet();
    
      // this is left player paddle
      colorRect(0,paddle1Y,PADDLE_THICKNESS,PADDLE_HEIGHT,'white');
    
      // this is right computer paddle
      colorRect(canvas.width-PADDLE_THICKNESS,paddle2Y,PADDLE_THICKNESS,PADDLE_HEIGHT,'white');
    
      // next line draws the ball
      colorCircle(ballX, ballY, 10, 'white');
    
      canvasContext.fillText(player1Score, 100, 100);
      canvasContext.fillText(player2Score, canvas.width-100, 100);
    }
    
    function colorCircle(centerX, centerY, radius, drawColor) {
      canvasContext.fillStyle = drawColor;
      canvasContext.beginPath();
      canvasContext.arc(centerX, centerY, radius, 0,Math.PI*2,true);
      canvasContext.fill();
    }
    
    function colorRect(leftX,topY, width,height, drawColor) {
      canvasContext.fillStyle = drawColor;
      canvasContext.fillRect(leftX,topY, width,height);
    }
    </script>
    </head>
    </body>
    
    body {
      background: #283048;  /* fallback for old browsers */
    background: -webkit-linear-gradient(to right, #859398, #283048);  /* Chrome 10-25, Safari 5.1-6 */
    background: linear-gradient(to right, #859398, #283048); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
    
    }
    
    h1 {
      color: white;
      text-align: center;
    }
    
    #gc {
      float: left;
    }
    
    #sb {
      float: right;
      margin-right: 50px;
      border: 2px solid;
      padding: 20px;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-07
      • 1970-01-01
      相关资源
      最近更新 更多