Estou trabalhando em um programa de videogame simples para a escola e criei um método em que o jogador ganha 15 pontos de saúde se esse método for chamado. Eu tenho que manter a saúde em um máximo de 100 e com minha capacidade de programação limitada neste ponto, estou fazendo algo assim.
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
Eu entendo que minha sintaxe sobre não é perfeita, mas minha dúvida é, qual pode ser a melhor maneira de fazer isso, porque eu também tenho que fazer algo semelhante com os pontos de dano e não ficar abaixo de 0.
Isso é chamado de aritmética de saturação .
java
if-statement
switch-statement
saturation-arithmetic
Steven Eck
fonte
fonte
Respostas:
Eu simplesmente faria isso. Basicamente, leva o mínimo entre 100 (a saúde máxima) e o que seria a saúde com 15 pontos extras. Isso garante que a saúde do usuário não exceda 100.
Para garantir que hitpoints não cair abaixo de zero, você pode usar uma função semelhante:
Math.max
.fonte
basta adicionar 15 à saúde, então:
No entanto, como observou sem graça, às vezes com multi-threading (vários blocos de código em execução ao mesmo tempo), ter a integridade acima de 100 em qualquer ponto pode causar problemas, e alterar a propriedade de integridade várias vezes também pode ser ruim. Nesse caso, você poderia fazer isso, conforme mencionado em outras respostas.
fonte
health
ou ter certeza de quehealth
é acessado apenas de um thread. A restrição "Nunca deve permitir que a saúde ultrapasse 100" não é realista.Você não precisa de um caso separado para cada
int
acima85
. Basta ter umelse
, de modo que se a saúde já for86
ou superior, defina-o diretamente para100
.fonte
100 - 15
(ou100 -HEALED_HEALTH
) não seria uma melhoria?Acho que uma forma idiomática e orientada a objetos de fazer isso é ter um
setHealth
naCharacter
classe. A implementação desse método será semelhante a esta:Isso evita que a saúde fique abaixo de 0 ou acima de 100, independentemente de como você definiu.
Sua
getHealed()
implementação pode ser apenas esta:Se faz sentido para o método
Character
ter-umgetHealed()
é um exercício deixado para o leitor :)fonte
heal(int hp)
edamage(int hp)
), cada um deles chamando seusetHealth(int newValue)
método.if
. Isso evita que você seja capaz de atirar no próprio pé. Se for muito detalhado, apenas use importações estáticas. Em seguida,health = max(0, min(100, newValue))
terá a seguinte aparência: Se ainda estiver ilegível para você, extraia-o para um método chamado declamp
forma que a linha fique assim:health = clamp(0, 100, newValue)
Vou apenas oferecer uma parte de código mais reutilizável, não é a menor, mas você pode usá-la com qualquer quantidade, então ainda vale a pena ser dito
Você também pode alterar o 100 para uma variável maxHealth se quiser adicionar estatísticas ao jogo que você está criando, então todo o método pode ser algo assim
EDITAR
Para informações extras
Você poderia fazer o mesmo quando o player for danificado, mas não precisaria de um minHealth porque seria 0 de qualquer maneira. Fazendo desta forma, você seria capaz de danificar e curar qualquer quantia com o mesmo código.
fonte
minHealth
pode ser negativo, digamos, por exemplo, em D&D ... :)fonte
Eu faria um método estático em uma classe auxiliar. Dessa forma, em vez de repetir o código para cada valor que precisa se ajustar a alguns limites, você pode ter um método para todos os fins. Aceitaria dois valores que definem o mínimo e o máximo, e um terceiro valor a ser fixado nessa faixa.
Para o seu caso, você declararia sua saúde mínima e máxima em algum lugar.
Em seguida, chame a função transmitindo sua saúde mínima, máxima e ajustada.
fonte
Eu sei que este é um projeto escolar, mas se você quiser expandir seu jogo mais tarde e ser capaz de atualizar seu poder de cura, escreva a função assim:
e chamar a função:
... etc ...
Além disso, você pode criar seu HP máximo criando uma variável que não é local para a função. Como não sei qual linguagem você está usando, não vou mostrar um exemplo porque pode ter a sintaxe errada.
fonte
Talvez isto?
fonte
Se você quiser ser atrevido e colocar seu código em uma linha, pode usar um operador ternário :
Observe que algumas pessoas irão desaprovar essa sintaxe devido à (possivelmente) má legibilidade!
fonte
health = (health <= 85)?(health+15):100
mais legível (se você realmente quiser usar um operador ternário)Eu acredito que isso vai servir
Explicação:
Se a lacuna de cura for 15 ou menos, a saúde passará a 100.
Caso contrário, se a lacuna for maior que 15, isso adicionará 15 à saúde.
Por exemplo: se a saúde for 83, ela se tornará 98, mas não 100.
fonte
&& health < 100
condição é desnecessária. Se for 100, será definido como 100, sem alteração. A única razão pela qual você precisaria disso é se fosse possível obter> 100 de alguma forma e não quisermos que a cura o reduza de volta a 100.Se eu quisesse ter um thread safe, faria dessa forma, em vez de usar um bloco sincronizado.
O compareAndSet atômico atinge o mesmo resultado que sincronizado sem a sobrecarga.
fonte
Maneira mais simples usando o operador de módulo.
saúde = (saúde + 50)% 100;
a saúde nunca será igual ou superior a 100.
fonte
health
for 100, você terminará com 50 de saúde.fonte