Je travaille sur un programme de jeu vidéo simple pour l'école et j'ai créé une méthode où le joueur obtient 15 points de vie si cette méthode est appelée. Je dois maintenir la santé à un maximum de 100 et avec ma capacité de programmation limitée à ce stade, je fais quelque chose comme ça.
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
Je comprends que ma syntaxe n'est pas parfaite mais ma question est, quelle peut être une meilleure façon de le faire, car je dois aussi faire une chose similaire avec les points de dégâts et ne pas descendre en dessous de 0.
Cela s'appelle arithmétique de saturation .
Je ferais juste ça. Cela prend fondamentalement le minimum entre 100 (la santé max) et ce que la santé serait avec 15 points supplémentaires. Il garantit que la santé de l'utilisateur ne dépasse pas 100.
public void getHealed() {
health = Math.min(health + 15, 100);
}
Pour vous assurer que les repères ne tombent pas en dessous de zéro, vous pouvez utiliser une fonction similaire: Math.max
.
public void takeDamage(int damage) {
if(damage > 0) {
health = Math.max(health - damage, 0);
}
}
il suffit d'ajouter 15 à la santé, donc:
health += 15;
if(health > 100){
health = 100;
}
Cependant, comme l'a noté fade, parfois avec plusieurs threads (plusieurs blocs de code s'exécutant à la fois) ayant la santé dépasser 100 à n'importe quel point peut causer des problèmes, et changer la propriété de santé plusieurs fois peut également sois méchant. Dans ce cas, vous pouvez le faire, comme mentionné dans d'autres réponses.
if(health + 15 > 100) {
health = 100;
} else {
health += 15;
}
Vous n'avez pas besoin d'un cas distinct pour chaque int
au-dessus de 85
. Il suffit d'en avoir un else
, de sorte que si la santé est déjà 86
ou supérieur, puis définissez-le directement sur 100
.
if(health <= 85)
health += 15;
else
health = 100;
Je pense qu'une façon idiomatique et orientée objet de faire cela est d'avoir un setHealth
sur la classe Character
. L'implémentation de cette méthode ressemblera à ceci:
public void setHealth(int newValue) {
health = Math.max(0, Math.min(100, newValue))
}
Cela empêche la santé de descendre en dessous de 0 ou supérieure à 100, quel que soit le paramètre que vous définissez.
Votre implémentation de getHealed()
peut simplement être la suivante:
public void getHealed() {
setHealth(getHealth() + 15);
}
Qu'il soit logique que la méthode Character
ait une méthode getHealed()
est un exercice laissé au lecteur :)
Je vais juste offrir une tranche de code plus réutilisable, ce n'est pas la plus petite mais vous pouvez l'utiliser avec n'importe quelle quantité, donc ça vaut la peine d'être dit
health += amountToHeal;
if (health >= 100)
{
health = 100;
}
Vous pouvez également changer le 100 en variable maxHealth si vous souhaitez ajouter des statistiques au jeu que vous créez, de sorte que la méthode entière pourrait ressembler à ceci
private int maxHealth = 100;
public void heal(int amountToHeal)
{
health += amountToHeal;
if (health >= maxHealth)
{
health = maxHealth;
}
}
Pour plus d'informations
Vous pouvez faire de même lorsque le joueur est endommagé, mais vous n'aurez pas besoin d'un minHealth car ce serait de toute façon 0. En procédant de cette façon, vous seriez en mesure d'endommager et de guérir n'importe quel montant avec le même code.
health = health < 85 ? health + 15 : 100;
Je ferais une méthode statique dans une classe d'assistance. De cette façon, plutôt que de répéter du code pour chaque valeur qui doit tenir dans certaines limites, vous pouvez avoir une méthode polyvalente. Il accepterait deux valeurs définissant le min et le max, et une troisième valeur à maintenir dans cette plage.
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;
}
}
Pour votre cas, vous déclareriez votre santé minimale et maximale quelque part.
final int HealthMin = 0;
final int HealthMax = 100;
Appelez ensuite la fonction en transmettant votre santé minimale, maximale et ajustée.
health = HelperClass.clamp( HealthMin, HealthMax, health + 15 );
Je sais que c'est un projet d'école, mais si vous souhaitez étendre votre jeu plus tard et pouvoir améliorer votre pouvoir de guérison, écrivez la fonction comme suit:
public void getHealed(healthPWR) {
health = Math.min(health + healthPWR, 100);
}
et appelez la fonction:
getHealed(15);
getHealed(25);
...etc...
De plus, vous pouvez créer votre HP max en créant une variable qui n'est pas locale à la fonction. Étant donné que je ne sais pas quelle langue vous utilisez, je ne montrerai pas d'exemple car il pourrait avoir la mauvaise syntaxe.
Peut être ça?
public void getHealed()
{
if (health <= 85)
{
health += 15;
} else
{
health = 100;
}
}
Si vous voulez être effronté et adapter votre code sur une seule ligne, vous pouvez utiliser un opérateur ternaire :
health += (health <= 85) ? 15 : (100 - health);
Notez que certaines personnes vont désapprouver cette syntaxe en raison (sans doute) d'une mauvaise lisibilité!
La manière la plus simple d'utiliser l'opérateur module.
santé = (santé + 50)% 100;
la santé ne sera jamais égale ou supérieure à 100.
Je crois que cela fera l'affaire
if (health >= 85) health = 100;
else health += 15;
Explication:
Si l'écart pour la guérison est de 15 ou moins, la santé deviendra 100.
Sinon, si l'écart est supérieur à 15, cela ajoutera 15 à la santé.
Ainsi par exemple: si la santé est de 83, elle deviendra 98 mais pas 100.
Si je voulais être thread-safe, je le ferais de cette façon plutôt que d'utiliser un bloc synchronisé.
L'atomic compareAndSet atteint le même résultat que synchronisé sans la surcharge.
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;
}