如何在不超过最大值的情况下增加变量?

Ste*_*Eck 89 java if-statement switch-statement saturation-arithmetic

我正在为学校制作一个简单的视频游戏程序,我已经创建了一种方法,如果调用该方法,玩家将获得15个健康点.我必须保持最高100的健康状态,并且我现在有限的编程能力,我正在做这样的事情.

public void getHealed(){
    if(health <= 85)
        health += 15;
    else if(health == 86)
        health += 14;
    else if(health == 87)
    health += 13; 
}// this would continue so that I would never go over 100
Run Code Online (Sandbox Code Playgroud)

我理解我的语法并不完美,但我的问题是,这可能是一个更好的方法,因为我还必须对损伤点做类似的事情,而不是低于0.

这称为饱和算术.

Chr*_*nce 222

我会这样做的.它基本上需要在100(最大生命值)和15点额外健康之间的最小值.它确保用户的健康不超过100.

public void getHealed() {
    health = Math.min(health + 15, 100);
}
Run Code Online (Sandbox Code Playgroud)

为确保生命值不低于零,您可以使用类似的功能:Math.max.

public void takeDamage(int damage) {
    if(damage > 0) {
        health = Math.max(health - damage, 0);
    }
}
Run Code Online (Sandbox Code Playgroud)


Jor*_*dan 71

只需为健康添加15,所以:

health += 15;
if(health > 100){
    health = 100;
}
Run Code Online (Sandbox Code Playgroud)

然而,正如bland所指出的,有时多线程(多个代码块同时执行),健康状况在任何时候都超过100 可能会导致问题,并且多次更改健康属性也可能很糟糕.在这种情况下,您可以这样做,如其他答案中所述.

if(health + 15 > 100) {
    health = 100;
} else {
    health += 15;
}
Run Code Online (Sandbox Code Playgroud)

  • @bland:竞争条件仅在多线程时相关.如果他正在进行多线程*(我非常怀疑)*,解决方案是锁定对`health`的所有访问,或者确保只从一个线程访问`health`.约束*"永远不应该允许健康超过100"*是不现实的. (13认同)
  • 永远不应该允许它过去,这可能会引入新的问题,例如竞争条件,其中假定角色健康最多是定义的健康最大值(100).对于这个级别的项目我不太可能,但我应该尽早执行好的做法. (9认同)
  • @bland如果要使用这种方法,避免这种竞争条件的方法是使用临时变量来存储新的健康值,然后在一个地方将健康值设置为这个新的健康值,必要时进行同步. (6认同)

rge*_*man 45

int上面的每一个都不需要单独的案例85.只有一个else,所以如果健康已经86或更高,那么只需将其直接设置为100.

if(health <= 85)
    health += 15;
else
    health = 100;
Run Code Online (Sandbox Code Playgroud)

  • 对我来说有点太多魔术数字(即使考虑到100允许) - 当改变15到16时,需要调整85.不会改变85到至少'100 - 15`(或'100 -HEALED_HEALTH`)是一种改进吗? (25认同)

Dan*_*lan 37

我认为这种惯用的,面向对象的方式是setHealthCharacter课堂上有一个.该方法的实现如下所示:

public void setHealth(int newValue) {
    health = Math.max(0, Math.min(100, newValue))
}
Run Code Online (Sandbox Code Playgroud)

无论您将其设置为什么,这都可以防止健康状况低于0或高于100.


您的getHealed()实现可以是这样的:

public void getHealed() {
    setHealth(getHealth() + 15);
}
Run Code Online (Sandbox Code Playgroud)

Character对于有一个getHealed()方法是否有意义是一个练习留给读者:)

  • 调用库函数有什么问题?作为命名函数,它们比一堆条件逻辑更清楚地表达意图. (18认同)
  • +1:这是以面向对象的方式执行此操作的好方法!我唯一可能建议的(这可能留给读者)可能有两个方法(`heal(int hp)`和`damage(int hp)`),每个方法调用你的`setHealth(int newValue) `方法. (5认同)
  • 此外,许多库函数(很可能是这些函数)都是内置的,根本不会执行任何调用. (2认同)
  • @Matteo错误答案 - 很可能库函数在内部做了完全相同的事情,所以为什么要重复自己并污染你的代码?不使用库函数不遵循DRY的基本原则. (2认同)
  • @Matteo这不是为了避免`if`.这是为了防止自己在脚下射击自己.如果它太冗长,只需使用静态导入.然后它看起来像这样:`health = max(0,min(100,newValue))`如果你仍然无法读取它,将它提取到一个名为`clamp`的方法,所以这行看起来像这样:`health = clamp(0 ,100,newValue)` (2认同)

5ta*_*ter 14

我只是提供一个更可重复的代码片段,它不是最小的但你可以使用任何数量的它,所以它仍然值得说

health += amountToHeal;
if (health >= 100) 
{ 
    health = 100;
}
Run Code Online (Sandbox Code Playgroud)

如果你想为你制作的游戏添加统计数据,你也可以将100改为maxHealth变量,所以整个方法可能是这样的

private int maxHealth = 100;
public void heal(int amountToHeal)
{
    health += amountToHeal;
    if (health >= maxHealth) 
    { 
        health = maxHealth;
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑

有关其他信息

你可以做同样的事情,当玩家受到损害,但你不需要minHealth,因为无论如何这将是0.通过这种方式,您可以使用相同的代码损坏和治愈任何金额.


小智 10

health = health < 85 ? health + 15 : 100;
Run Code Online (Sandbox Code Playgroud)