私は学校向けのシンプルなビデオゲームプログラムに取り組んでおり、そのメソッドが呼び出された場合にプレーヤーが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
私の構文は完全ではないことを理解していますが、私の質問は、それを行うためのより良い方法は何ですか?.
これは 飽和演算 と呼ばれます。
私はこれをするだけです。基本的には、100(最大ヘルス)の間の最小値と、15ポイントを追加した場合のヘルスが必要です。ユーザーの健康が100を超えないようにします。
public void getHealed() {
health = Math.min(health + 15, 100);
}
ヒットポイントがゼロを下回らないようにするには、同様の関数を使用できます:Math.max
。
public void takeDamage(int damage) {
if(damage > 0) {
health = Math.max(health - damage, 0);
}
}
ヘルスに15を追加するだけです。
health += 15;
if(health > 100){
health = 100;
}
しかし、当たり障りのないように、マルチスレッド(一度に実行される複数のコードブロック)でanyポイントでヘルスが100を超えると問題が発生することがあり、ヘルスプロパティを複数回変更することもできます悪くなる。その場合、他の回答で述べたように、これを行うことができます。
if(health + 15 > 100) {
health = 100;
} else {
health += 15;
}
上記のint
ごとに個別のケースを必要としない85
。 else
が1つだけなので、ヘルスが既に86
以上の場合は、100
。
if(health <= 85)
health += 15;
else
health = 100;
これを行うための慣用的なオブジェクト指向の方法は、setHealth
クラスにCharacter
を持たせることだと思います。そのメソッドの実装は次のようになります。
_public void setHealth(int newValue) {
health = Math.max(0, Math.min(100, newValue))
}
_
これにより、設定に関係なく、ヘルスが0未満または100を超えないようになります。
getHealed()
実装は次のようになります。
_public void getHealed() {
setHealth(getHealth() + 15);
}
_
Character
がgetHealed()
メソッドを持っていることが理にかなっているかどうかは、読者に任せた演習です:)
私はもっと再利用可能なコードのスライスを提供するつもりです、それは最小ではありませんが、あなたはそれがまだ言うに値するので、あなたはそれをどんな量でも使うことができます
health += amountToHeal;
if (health >= 100)
{
health = 100;
}
ゲームに統計を追加する場合は、100をmaxHealth変数に変更することもできます。そのため、メソッド全体は次のようになります。
private int maxHealth = 100;
public void heal(int amountToHeal)
{
health += amountToHeal;
if (health >= maxHealth)
{
health = maxHealth;
}
}
追加情報について
プレーヤーが破損した場合にも同じことができますが、minHealthは0になるため、必要ありません。この方法でそれを行うと、同じコードを使用してあらゆる金額を損傷および回復できます。
health = health < 85 ? health + 15 : 100;
ヘルパークラスで静的メソッドを作成します。この方法では、境界内に収まる必要があるすべての値に対してコードを繰り返すのではなく、1つの汎用メソッドを使用できます。最小値と最大値を定義する2つの値と、その範囲内でクランプされる3つ目の値を受け入れます。
class HelperClass
{
// Some other methods
public static int clamp( int min, int max, int value )
{
if( value > max )
return max;
else if( value < min )
return min;
else
return value;
}
}
あなたの場合、どこかで最低と最高の健康状態を宣言します。
final int HealthMin = 0;
final int HealthMax = 100;
次に、最小、最大、および調整されたヘルスを渡す関数を呼び出します。
health = HelperClass.clamp( HealthMin, HealthMax, health + 15 );
これは学校のプロジェクトであることは知っていますが、後でゲームを拡張してヒーリングパワーをアップグレードしたい場合は、次のように関数を記述します。
public void getHealed(healthPWR) {
health = Math.min(health + healthPWR, 100);
}
そして、関数を呼び出します:
getHealed(15);
getHealed(25);
...等...
さらに、関数に対してローカルではない変数を作成することにより、最大HPを作成できます。使用している言語がわからないので、構文が間違っている可能性があるため、例を示しません。
たぶんこれ?
public void getHealed()
{
if (health <= 85)
{
health += 15;
} else
{
health = 100;
}
}
生意気でコードを1行に収めたい場合は、 三項演算子 を使用できます。
health += (health <= 85) ? 15 : (100 - health);
(おそらく)可読性が悪いため、一部の人々はこの構文に眉をひそめることに注意してください!
モジュラス演算子を使用した最も簡単な方法。
健康=(健康+ 50)%100;
ヘルスが100以上になることはありません。
これでいいと思う
if (health >= 85) health = 100;
else health += 15;
説明:
ヒーリングのギャップが15以下の場合、ヘルスは100になります。
それ以外の場合、ギャップが15より大きい場合、ヘルスが15増加します。
たとえば、ヘルスが83の場合、100ではなく98になります。
スレッドセーフにしたい場合は、同期ブロックを使用するのではなく、この方法で行います。
アトミックcompareAndSetは、オーバーヘッドなしで同期と同じ結果を達成します。
AtomicInteger health = new AtomicInteger();
public void addHealth(int value)
{
int original = 0;
int newValue = 0;
do
{
original = health.get();
newValue = Math.min(100, original + value);
}
while (!health.compareAndSet(original, newValue));
}
private int health;
public void Heal()
{
if (health > 85)
health = 100;
else
health += 15;
}
public void Damage()
{
if (health < 15)
health = 0;
else
health -= 15;
}