1

我正在制作游戏并使用 JavaScript/jQuery 来花费角色属性点。我有六个像这样的输入,每个代表一个属性:

<input class="attributeVal" type="number" min="1" max="36" step="1" value="1">

像这样的一个输入(“池”):

<input id="pool" type="number" min="0" max="36" step="1" value="36" readonly>

最后一个输入用作“池”,这意味着它是要花费在六个输入组上的剩余点的总和。我想要以下内容:

  • 更改任何“attributeVal”输入会减去或恢复池中的点,该点不能大于 36 且小于 0。
  • “attributeVal”的每个输入不能小于 1 且大于 36。
  • “attributeVal”和“pool”不能为负数。

我尝试了不同的方法,但无法阻止玩家超过池最大值,主要是因为我不知道如何防止更改事件。

这是我迄今为止尝试过的:

<script>
    let attributeVal = $(".attributeVal");

    attributeVal.on("change paste keyup", function (e) {
        let prev = $(this).data('val');
        let maxPointsOverall = 42;
        let spentPoints = 0;
        let poolInput = $('#poolInput');

        $(".attributeVal").each(function () {
            spentPoints += +$(this).val();
        });

        if ((maxPointsOverall - spentPoints) < 0) {
            $(this).val(prev);
            poolInput.val(0);
        } else {
            poolInput.val(42 - spentPoints);
        }
    });

    attributeVal.on("cut copy paste", function (e) {
        e.preventDefault();
    });
</script>

你能给我任何提示吗,我怎样才能使这个工作?

let attributeVal = $(".attributeVal");

attributeVal.on("change paste keyup", function(e) {
  let prev = $(this).data('val');
  let maxPointsOverall = 42;
  let spentPoints = 0;
  let poolInput = $('#poolInput');

  $(".attributeVal").each(function() {
    spentPoints += +$(this).val();
  });

  if ((maxPointsOverall - spentPoints) < 0) {
    $(this).val(prev);
    poolInput.val(0);
  } else {
    poolInput.val(42 - spentPoints);
  }
});

attributeVal.on("cut copy paste", function(e) {
  e.preventDefault();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label class="font-weight-bold unselectable mb-3">Points available
  <input id="poolInput" type="number" min="0" max="36" step="1" value="36" readonly>
</label>

<div class="form-group">
  <label>Strength
    <input class="attributeVal" type="number" min="1" max="36" step="1" value="1">
  </label>
</div>
<div class="form-group">
  <label>Endurance
    <input class="attributeVal" type="number" min="1" max="36" step="1" value="1">
  </label>
</div>
<div class="form-group">
  <label>Dexterity
    <input class="attributeVal" type="number" min="1" max="36" step="1" value="1">
  </label>
</div>
<div class="form-group">
  <label>Perception
    <input class="attributeVal" type="number" min="1" max="36" step="1" value="1">
  </label>
</div>
<div class="form-group">
  <label>Intelligence
    <input class="attributeVal" type="number" min="1" max="36" step="1" value="1">
  </label>
</div>
<div class="form-group">
  <label>Charisma
    <input class="attributeVal" type="number" min="1" max="36" step="1" value="1">
  </label>
</div>

这是 JSFiddle 来说明问题

4

1 回答 1

1

一个问题是,一旦输入事件被触发,如果不将每个输入的状态保存在某处,就无法将其重置为以前的数字,这有点混乱。您可能会考虑首先验证该值:

  • 确保它是 0 到 36 之间的整数
  • 计算在其他属性上花费的点数。确保当前值添加到该值后不超过maxPointsOverall. (如果溢出,将当前值减小到这样的点pointsSpentOnOtherAttribs + newVal === maxPointsOverall

然后将当前值设置为已验证newVal,并计算/填充#poolInput.

为确保输入立即得到修复,而不是短暂延迟,请添加一个input侦听器(它将在按键周围触发,而不是在按键时触发):

const attributeVal = $(".attributeVal");

attributeVal.on("change paste keyup input", function(e) {
  let newVal = Math.floor($(this).val());
  newVal = Math.max(1, newVal);
  newVal = Math.min(36, newVal);
  const maxPointsOverall = 42;
  let pointsSpentOnOtherAttribs = 0;
  $(".attributeVal").not(this).each(function() {
    pointsSpentOnOtherAttribs += +$(this).val();
  });
  if (newVal + pointsSpentOnOtherAttribs > maxPointsOverall) {
    // Invalid, reset these points to the maximum allowable:
    newVal = maxPointsOverall - pointsSpentOnOtherAttribs;
  }
  // New value has been validated, put it into the DOM:
  $(this).val(newVal);
  const pointsLeft = maxPointsOverall - (pointsSpentOnOtherAttribs + newVal);
  $('#poolInput').val(pointsLeft);
});

attributeVal.on("cut copy paste", function(e) {
  e.preventDefault();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label class="font-weight-bold unselectable mb-3">Points available
  <input id="poolInput" type="number" min="0" max="36" step="1" value="36" readonly>
</label>

<div class="form-group">
  <label>Strength
    <input class="attributeVal" type="number" min="1" max="36" step="1" value="1">
  </label>
</div>
<div class="form-group">
  <label>Endurance
    <input class="attributeVal" type="number" min="1" max="36" step="1" value="1">
  </label>
</div>
<div class="form-group">
  <label>Dexterity
    <input class="attributeVal" type="number" min="1" max="36" step="1" value="1">
  </label>
</div>
<div class="form-group">
  <label>Perception
    <input class="attributeVal" type="number" min="1" max="36" step="1" value="1">
  </label>
</div>
<div class="form-group">
  <label>Intelligence
    <input class="attributeVal" type="number" min="1" max="36" step="1" value="1">
  </label>
</div>
<div class="form-group">
  <label>Charisma
    <input class="attributeVal" type="number" min="1" max="36" step="1" value="1">
  </label>
</div>

于 2019-11-02T04:07:14.780 回答