Pracuję nad prostym programem do gier wideo dla szkoły i stworzyłem metodę, w której gracz otrzymuje 15 punktów zdrowia, jeśli ta metoda zostanie wywołana. Muszę utrzymywać zdrowie na maksymalnym poziomie 100 i przy mojej ograniczonej zdolności programowania w tym momencie robię coś takiego.
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
Rozumiem, że moja składnia nie jest idealna, ale moje pytanie brzmi: jaki może być lepszy sposób na zrobienie tego, ponieważ muszę zrobić podobnie z punktami obrażeń i nie zejść poniżej 0.
Nazywa się to arytmetyką nasycenia .
java
if-statement
switch-statement
saturation-arithmetic
Steven Eck
źródło
źródło
Odpowiedzi:
Po prostu bym to zrobił. Zasadniczo zajmuje minimum od 100 (maksymalne zdrowie) do tego, jakie byłoby zdrowie z 15 dodatkowymi punktami. Zapewnia, że zdrowie użytkownika nie przekracza 100.
public void getHealed() { health = Math.min(health + 15, 100); }
Aby upewnić się, że hitpoints nie spadają poniżej zera, można zastosować podobną funkcję:
Math.max
.public void takeDamage(int damage) { if(damage > 0) { health = Math.max(health - damage, 0); } }
źródło
po prostu dodaj 15 do zdrowia, więc:
health += 15; if(health > 100){ health = 100; }
Jednak, jak zauważyłem nijakie, czasami w przypadku wielowątkowości (wielu bloków kodu wykonywanych jednocześnie) stan zdrowia przekraczający 100 w dowolnym momencie może powodować problemy, a wielokrotna zmiana właściwości kondycji może być również zła. W takim przypadku możesz to zrobić, jak wspomniano w innych odpowiedziach.
if(health + 15 > 100) { health = 100; } else { health += 15; }
źródło
health
lub upewnienie się, żehealth
dostęp do nich jest możliwy tylko z jednego wątku. Ograniczenie „nigdy nie powinno pozwolić, aby zdrowie przekroczyło 100” nie jest realistyczne.Nie potrzebujesz osobnego przypadku dla każdego z
int
powyższych85
. Wystarczy mieć jednąelse
, więc jeśli zdrowie jest już86
lub wyższe, po prostu ustaw je bezpośrednio na100
.if(health <= 85) health += 15; else health = 100;
źródło
100 - 15
(lub100 -HEALED_HEALTH
) nie byłaby poprawą?Myślę, że idiomatycznym, zorientowanym obiektowo sposobem na zrobienie tego jest posiadanie
setHealth
wCharacter
klasie. Implementacja tej metody będzie wyglądać następująco:public void setHealth(int newValue) { health = Math.max(0, Math.min(100, newValue)) }
Zapobiega to spadkowi zdrowia poniżej 0 lub wyższym niż 100, niezależnie od tego, co ustawisz.
Twoja
getHealed()
implementacja może wyglądać tak:public void getHealed() { setHealth(getHealth() + 15); }
To, czy metoda ma
Character
mieć sens, to zadaniegetHealed()
pozostawione czytelnikowi :)źródło
heal(int hp)
idamage(int hp)
), z których każda wywołuje twojąsetHealth(int newValue)
metodę.if
. Ma to na celu uniknięcie możliwości strzelenia sobie w stopę. Jeśli jest zbyt rozwlekły, po prostu użyj importu statycznego. Wtedy wygląda to tak:health = max(0, min(100, newValue))
Jeśli to nadal jest dla Ciebie nieczytelne, wyodrębnij je do metody o nazwie,clamp
aby wiersz wyglądał następująco:health = clamp(0, 100, newValue)
Mam zamiar zaoferować fragment kodu wielokrotnego użytku, nie jest to najmniejszy, ale można go używać z dowolną ilością, więc nadal warto go powiedzieć
health += amountToHeal; if (health >= 100) { health = 100; }
Możesz także zmienić 100 na zmienną maxHealth, jeśli chcesz dodać statystyki do gry, którą tworzysz, więc cała metoda może wyglądać mniej więcej tak
private int maxHealth = 100; public void heal(int amountToHeal) { health += amountToHeal; if (health >= maxHealth) { health = maxHealth; } }
EDYTOWAĆ
Dodatkowe informacje
Możesz zrobić to samo, gdy gracz zostanie uszkodzony, ale nie potrzebujesz minHealth, ponieważ i tak byłoby to 0. Robiąc to w ten sposób, będziesz w stanie uszkodzić i leczyć dowolne ilości za pomocą tego samego kodu.
źródło
minHealth
może być negatywne, powiedzmy, w D&D ... :)health = health < 85 ? health + 15 : 100;
źródło
Zrobiłbym metodę statyczną w klasie pomocniczej. W ten sposób zamiast powtarzać kod dla każdej wartości, która musi mieścić się w pewnych granicach, możesz mieć jedną uniwersalną metodę. Przyjąłby dwie wartości określające min i maks, oraz trzecią wartość do ustalenia w tym zakresie.
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; } }
W twoim przypadku zadeklarowałbyś gdzieś swoje minimalne i maksymalne zdrowie.
final int HealthMin = 0; final int HealthMax = 100;
Następnie wywołaj funkcję przekazującą twoje minimalne, maksymalne i dostosowane zdrowie.
health = HelperClass.clamp( HealthMin, HealthMax, health + 15 );
źródło
Wiem, że to projekt szkolny, ale jeśli chciałbyś później rozszerzyć swoją grę i móc ulepszyć swoją moc leczniczą, napisz następującą funkcję:
public void getHealed(healthPWR) { health = Math.min(health + healthPWR, 100); }
i wywołaj funkcję:
getHealed(15); getHealed(25);
...itp...
Ponadto możesz stworzyć swoje maksymalne HP, tworząc zmienną, która nie jest lokalna dla funkcji. Ponieważ nie wiem, jakiego języka używasz, nie pokażę przykładu, ponieważ może on mieć niewłaściwą składnię.
źródło
Może to?
public void getHealed() { if (health <= 85) { health += 15; } else { health = 100; } }
źródło
Jeśli chcesz być bezczelny i zmieścić swój kod w jednej linii, możesz użyć operatora trójskładnikowego :
health += (health <= 85) ? 15 : (100 - health);
Zauważ, że niektórzy ludzie będą krzywo patrzeć na tę składnię z powodu (prawdopodobnie) złej czytelności!
źródło
health = (health <= 85)?(health+15):100
bardziej czytelny (jeśli naprawdę chcesz użyć operatora trójskładnikowego)Wierzę, że to wystarczy
if (health >= 85) health = 100; else health += 15;
Wyjaśnienie:
Jeśli przerwa na leczenie wynosi 15 lub mniej, zdrowie osiągnie 100.
W przeciwnym razie, jeśli różnica jest większa niż 15, doda 15 do zdrowia.
Na przykład: jeśli zdrowie wyniesie 83, wyniesie 98, ale nie 100.
źródło
&& health < 100
Warunek jest niepotrzebna. Jeśli jest to 100, zostanie ustawione na 100, bez zmian. Jedynym powodem, dla którego by to było potrzebne, jest to, że w jakiś sposób można uzyskać> 100 i nie chcemy, aby uzdrowienie zmniejszyło cię z powrotem do 100.Gdybym chciał być bezpieczny wątkowo, zrobiłbym to w ten sposób, zamiast używać zsynchronizowanego bloku.
Atomowa metoda compareAndSet daje taki sam wynik, jak zsynchronizowana bez narzutu.
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)); }
źródło
Najprostszy sposób przy użyciu operatora modułu.
zdrowie = (zdrowie + 50)% 100;
zdrowie nigdy nie osiągnie ani nie przekroczy 100.
źródło
health
osiągniesz 100, skończysz z 50 punktami zdrowia.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; }
źródło