Como posso calcular o nível atual do XP total, quando cada nível requer proporcionalmente mais XP?

33

No meu jogo, o XP necessário para alcançar o próximo nível é Nível Atual × Limiar de Nível . Dado isso, como posso obter meu nível atual do total de XP já ganho?


Por exemplo:

Level Threshold = 50
Current Level = 1

Começando no nível 1, eu precisaria (1 × 50) = 50 XP para chegar ao nível 2, e assim por diante.

Level 1: 50 XP needed to reach level 2
Level 2: 100 more XP needed to reach level 3
Level 3: 150 more XP needed to reach level 4

Em outras palavras, a tabela de progressão é a seguinte:

Level 1: 0 XP to 49 XP
Level 2: 50 XP to 149 XP 
Level 3: 150 XP to 299 XP
Level 4: 300 XP to 499 XP

Se eu tiver 300 XP, chegarei ao nível 4. Como posso calcular isso geralmente?

Jay van Diyk
fonte
Relacionada no Stack Overflow: Calcular uma raiz triangular sem sqrt
Damian Yerrick
A quantidade de XP necessária para o próximo nível não aumenta quanto maior o nível atual?
Mast
Bem, a primeira pergunta que você precisa responder é: Qual é o valor do "limite" para cada nível? Com base no seu exemplo, se assumirmos que 300 XP é o mínimo para atingir o nível 4, seu limite aumentará para 75 após o nível 3. Depois de determinar a frequência em que o limite aumenta, você poderá criar um algoritmo para calculá-lo. , como as outras pessoas estão tentando fazer em suas respostas
Taegost
3
O Majte fornece uma boa resposta sobre como calculá-lo, mas a resposta "melhor" é simplesmente não calculá-lo .... armazene a exp geral, mas também o nível atual e o delta do XP. Redefinir o delta cada vez que você subir de nível e você tem todas as informações que você precisa (nível, nível + 1, xp total xp delta) para facilmente calcular qualquer coisa que você precisa usar / display
Jon História
@JonStory De fato. Eu expliquei isso um pouco na minha resposta, porque, bem, quem realmente calcula o nível dinamicamente o tempo todo? Esta questão é, em essência, apenas uma questão de matemática, pois não considera o papel dos níveis em um sistema de jogo.
Zxq9

Respostas:

33

Ao elaborar as matemáticas e resolver as Levelcondições condicionadas à experiência XP, obtemos:

eueveeu=1+1+8×XP÷50.2

Por exemplo, qual é o nível do jogador para ?XP=300

1+1+8×300÷502=4

Como pedido.

Ou, qual é o nível XP = 100000?

1+1+8×100000÷502=63

Mais geralmente expresso, para um limite inicial arbitrário no nível 1:

Level=1+1+8×threshold÷502

Você também pode fazer o inverso e calcular o XPnecessário para qualquer nível, resolvendo a fórmula acima para XP.

XP=(eueveeu2-eueveeu)×threshoeud2

Observe que a fórmula acima funciona com frações, mas você precisa arredondar para o próximo valor inteiro. Por exemplo, em C ++ / C #, você poderia usar o nível (int).

Para obter a fórmula de forma fechada acima, usei equações de diferença, soma de Gauss e uma fórmula quadrática.

Se você está interessado na solução desta fórmula passo a passo ...

Nós fazemos um algoritmo recursivo, iniciando nossas considerações Experience(next_level) = Experience(current_level) + current_level*50.

Por exemplo, para obter , temos:XPeueveeu3

XPeueveeu3=XPeueveeu2+2×50.

De onde 2*50vem a solicitação do OP de que a experiência necessária para alcançar o próximo nível é o nível atual * 50.

Agora, substituímos pela mesma lógica na fórmula. Isso é:Xpeueveeu2

Substitua na fórmula acima:XPLevel2=XPLevel1+2×50

XpLevel3=XpLevel1+1×50+2×50.

e são apenas 50, que é o nosso ponto de partida. ConseqüentementeXpeueveeu1

Xpeueveeu3=50.+2×50.=150

Podemos reconhecer um padrão para calcular recursivamente níveis mais altos e uma cadeia finita de somatórios.

XpeueveeuN=50.+2×50.+3×50.+...+(N-1)×50.=Eu=0 0n-1Eu×50.

Onde N é o nível a ser alcançado. Para obter o XP para o nível N, precisamos resolver para N.

XpeueveeuN÷50.=Eu=0 0n-1Eu

Agora, o lado direito é simplesmente um somatório de 1 a N-1, que pode ser expresso pela soma de Gauss famoso . ConseqüentementeN×(N+1)÷2-N

XpeueveeuN÷50.=N(N+1)÷2-N

ou apenas

2(XpeueveeuN-50.)÷50.=N(N+1)-2N

Por fim, colocando tudo de um lado:

0 0=N2-N-2×XpeueveeuN÷50.

Esta é agora uma fórmula quadrática que produz uma solução negativa e positiva, da qual apenas o positivo é relevante, pois não há níveis negativos. Agora obtemos:

N=1+1+4×2×XpeueveeuN50.2

O nível atual condicional no XP e no limite linear é, portanto:

eueveeu=1+1+8×XP÷threshoeud2

eueveeu=XP5.0XPLevel 100

Editar : esta fórmula está funcionando como deveria e gera corretamente a levelcondição atual XP com uma progressão de limite linear, conforme solicitado pelo OP. (A fórmula anterior produziu "nível + 1" assumindo que o jogador partiu do nível 0, que foi o meu erro - eu havia resolvido isso no meu horário de almoço escrevendo em um pequeno lenço de papel! :)

Majte
fonte
Comentários não são para discussão prolongada; esta conversa foi movida para o bate-papo .
Josh
@ JoshPetrie O problema para nós, que acabamos de ver essa pergunta mais tarde, é que o link do bate-papo está quebrado. Alguma maneira de recuperá-lo?
Mand
@ Eu desfiz o cancelamento, mas ele desaparecerá novamente em mais oito dias.
Josh
25

A solução simples e genérica , se você não precisar repetir esse cálculo milhões de vezes por segundo (e se o fizer, provavelmente está fazendo algo errado), é apenas usar um loop:

expLeft = playerExp
level = 1
while level < levelCap and expLeft >= 0:
    expLeft = expLeft - expToAdvanceFrom(level)
    level = level + 1

if expLeft < 0: level = level - 1     # correct overshoot

A grande vantagem desse método, além de não exigir matemática complicada, é que ele funciona para qualquer função arbitrária de exp por nível. Se desejar, você pode até criar valores de exp arbitrários por nível e armazená-los em uma tabela.

Se você (por algum motivo estranho) precisar de uma solução ainda mais rápida, também poderá pré- calcular a quantidade total de exp necessária para atingir cada nível, armazenar isso em uma tabela e usar uma pesquisa binária para encontrar o nível do jogador. O pré-cálculo ainda leva tempo proporcional ao número total de níveis, mas a pesquisa requer apenas tempo proporcional ao logaritmo do número de níveis.

Ilmari Karonen
fonte
4
Solução mais flexível. E como a velocidade não importa para um cálculo único, melhor eu acho.
GameAlchemist
4
@ Mahj: Talvez eu não tenha sido claro o suficiente. Estou não sugerindo que qualquer uma das soluções postadas exigiria "milhões de iterações". O que eu quis dizer é que, a menos que você precise calcular o nível do jogador milhões de vezes por segundo, minha solução (força bruta ingênua) é mais do que rápida o suficiente. As outras soluções, baseadas em derivar algebricamente uma fórmula de forma fechada para o nível em função de exp, podem ser ainda mais rápidas - mas para código que raramente é chamado (e algo menos que, digamos, 1.000 vezes por segundo, certamente conta como "raro" aqui), não fará nenhuma diferença perceptível.
Ilmari Karonen 28/10/2015
2
Ohh, agora vejo, desculpe. Concordo plenamente com você e você oferece uma ótima alternativa para as etapas de avanço definidas pelo usuário por nível. Mas então, provavelmente, use tabelas pré-processadas, afinal.
Majte 28/10/2015
2
A simplicidade desta solução a torna uma clara vencedora. Não desconte o valor da legibilidade e manutenção.
Mauser
1
Computadores são bons em tarefas domésticas, não em pessoas. Você deseja simplificar a vida das pessoas, o programador, às custas do computador, se necessário. Usando esta solução, você só precisa escrever um método, o encaminhamento, não o encaminhamento e o reverso. A solução mais simples não é a que ele tem no código, mas a construção dessa tabela de pesquisa. Ram é barato, use-o.
Mauser
11

A pergunta foi respondida com código, mas acho que deveria ser respondida com matemática. Alguém pode querer entender em vez de apenas copiar e colar.

XPNível+1=XPNível+NívelLimite

XP

XPNível=(Nível-1)NívelLimite2

Nível

Nível=Limite2+8XPLimite2Limite+12

(truncar para inteiro, porque o jogador precisa de todo o XP necessário para obter algum bônus de nível)

MickLH
fonte
2
Eu gosto desta resposta. Claro e conciso.
Almo 29/10
Hey Mick; já faz um tempo desde que eu fiz relações recorrentes. Não poderíamos também especificar o caso base XP_Level(0) = 50e evitar a solução? Quaisquer benefícios, prós, contras? Eu acho que seria bom tocar nessa resposta. +1
Vaughan Hilts 30/10/2015
@VaughanHilts Não tenho certeza de como a sua notação funciona ou o que você está perguntando, sinta-se à vontade para me enviar um ping no chat do gamedev?
MickLH
Eu entendi a resposta do código muito mais fácil do que isso.
Pharap
Continue trabalhando no @Pharap. Quando eu era adolescente, também entendia o código mais facilmente do que a matemática, mas com experiência e conhecimento, a matemática se tornará óbvia em todos os lugares da vida.
MickLH 12/04
10

Aqui está uma abordagem para resolver o problema usando álgebra básica. Se você não se importa com as etapas, pule para o final.

Uma coisa fácil de apresentar é, dado um nível n, a experiência total enecessária para obter esse nível:

e = sum from k=1 to n of (t(k-1))

O ttermo significa o aumento de XP necessário por nível - 50, no exemplo.

Podemos resolver o acima usando a fórmula para sequências aritméticas ( identidade da soma ):

e = t/2 * n(n-1)

No entanto, queremos a fórmula oposta - o nível do jogador, dada a sua experiência total. O que realmente queremos fazer é resolver o nível n,. Primeiro, vamos agrupar os termos:

n^2 - n - 2e/t = 0

Agora podemos usar a fórmula quadrática:

n = (1 + sqrt(1+8e/t))/2

Equação final:

level = 0.5 + sqrt(1 + 8*(total experience)/(threshold)) / 2
Chaosed0
fonte
1
Obrigado pela resposta. Mas e se eu quiser alterar o Threshold para outra variável? Em vez de 50, eu gostaria de usar 50000 ou 1000 0 para esse assunto. Como devo modificar a equação?
JayVDiyk
2
Sim, as soluções devem ser as mesmas. Eu queria apresentar as etapas da solução, caso alguém estivesse interessado. @JayVDiyk - editará a postagem.
precisa saber é o seguinte
Isso foi um pouco atrevido da sua parte, pois comentei que postarei a solução completa depois do trabalho;) está tudo bem, não me importo. O normal é responder com uma referência à resposta correta e anotar a extensão. Mente nervosa, adorava ter resolvido. Gostaria que mais perguntas como essa fossem postadas aqui.
Majte 28/10/2015
Desculpe, deve ter perdido esse comentário. Não pretendia roubá-lo de você ou algo assim - vou lembrar da próxima vez. Sua resposta é definitivamente mais completa do que a minha após a edição!
Chaosed0
1
+1; sem ofender o @Majte pretendido, eu pessoalmente acho sua explicação mais legível.
Ilmari Karonen
3

Toda a matemática envolvida aqui é muito importante para saber por todos os tipos de razões, algumas delas aplicáveis ​​ao desenvolvimento de jogos.

MAS

Este é um site de desenvolvimento de jogos, não um site de matemática. Então, vamos discutir como essas coisas funcionam não como séries algorítmicas, mas como conjuntos , porque esse é o tipo de matemática que se aplica ao nivelamento de jogos que você pode desenvolver para vender, e esse é o sistema que sustenta a maioria (mas não todos) do nivelamento sistemas (pelo menos historicamente).

Os jogadores tendem a preferir números agradáveis ​​e redondos que são fáceis de lembrar e visualizar, e em nenhum lugar isso é mais importante do que em um sistema de jogo baseado em níveis em que o jogador precisa de X quantidades de xp para avançar para o nível Y.

Há duas boas razões para escolher números redondos:

  • A experiência de nível em si é um número redondo e agradável "100; 200; 1.000.000; etc."
  • O delta entre níveis tende a ser outro número agradável e redondo que o jogador pode olhar e calcular em sua cabeça.

Números redondos são agradáveis. O objetivo dos jogos é ser agradável. Agradabilidade é importante, principalmente porque os dilemas do jogo geralmente são agradáveis ​​em termos de design.

Por que isso é importante ter em mente?

A maioria dos algoritmos de séries compostas não produz números agradáveis ​​e redondos

A maioria das séries não para em um ponto bonito (todas as respostas que eu vi aqui até agora só perduram para sempre). Então, o que fazemos? Aproximamos e depois determinamos que conjunto de níveis deve ser aplicado ao sistema de jogo .

Como sabemos quais aproximações são apropriadas? Consideramos qual é o ponto de nivelamento no sistema de jogo.

A maioria dos jogos tem limites de nível que começam em algum momento. Existem algumas maneiras de isso acontecer:

  • O limite é encontrado relativamente cedo, onde o sistema de níveis existe apenas para ajudar os jogadores a passarem pela primeira fase do jogo de maneira focada para forçá-los a aprender o sistema de jogo completo. Uma vez que eles estão "totalmente crescidos", o longo jogo começa.
  • XP ganha VS o nível de dificuldade tem uma certa economia onde sim, existe um limite de nível, mas é tão distante que esperamos que os jogadores completem o jogo na metade do gráfico de nivelamento. Nos RPGs no estilo DQ / FF, com vários caracteres / classes, é mais comum melhorar o nível de caracteres / classes diferentes, ganhando experiência em taxas diferentes do que alterar o XP necessário para cada nível por classe de personagem . Dessa forma, os jogadores podem se lembrar facilmente dos pequenos números redondos como objetivos universais e saber que cada personagem progride em direção a eles a uma taxa arbitrária estabelecida pelo sistema de jogo ( XP + (XP * Modifier)ou o que seja).
  • Os limites de nível são baseados na categoria de caracteres externos. Ou seja, algum fator fora do sistema de jogo determina como é o sistema de níveis. Isso está se tornando mais comum, pois muitos jogos são pagos, mas são gratuitos. Um jogador grátis pode ter um limite no nível 70, um assinante pode ter um limite no nível 80, uma compra única pode aumentar o nível de alguém além do limite universal, etc.
  • Os limites de nível são universais e vinculados ao mundo do jogo de alguma forma. Este sistema foi popularizado pelo WoW.
  • Qualquer outro sistema de limite de nível que você possa imaginar que aprimore a jogabilidade de uma maneira mais inteligente do que simplesmente recompensar os jogadores por desperdiçarem mais minutos da vida no mundo inventado do que os outros jogadores.

Não são alguns sistemas de jogo onde não há limite de nível eo sistema é através de algoritmos determinados. Normalmente, sistemas como esse usam algum sistema X-powers-Y para fazer os números explodirem rapidamente. Isso torna muito fácil chegar ao nível L-1, razoavelmente esperado que a maioria dos jogadores chegue ao nível L, extremamente difícil chegar ao nível L + 1, e os jogadores envelhecem e morrem antes de atingir L + 2. Nesse caso, "L" é um nível que você decidiu ser o nível-alvo apropriado para o jogo e no qual normalmente limitaria o sistema, mas deixaria a opção aberta para que as pessoas se iludissem a pensar que é uma boa idéia para o XP para sempre. (Sinistro!) Nesse tipo de sistema, a matemática encontrada aqui faz todo sentido. Mas é um caso muito estreito e raramente encontrado em jogos reais.

Então, o que fazemos?

Calcular os níveis e XP? Não. Determine os níveis e XP? Sim.

Você determina o que os níveis significam e decide o que o conjunto de níveis disponível deve estar disponível. Essa decisão se resume a uma granularidade dentro do sistema de jogo (existe uma enorme diferença de poder entre os níveis? Cada nível confere uma nova habilidade? Etc.) e se os níveis são ou não usados ​​como um sistema de bloqueio ("Não é possível vá para a próxima cidade até completar o nível 10, garoto. ", ou um sistema competitivo de escadas imponha níveis baseados em níveis, etc.).

O código para isso é bastante direto e é apenas uma determinação de intervalo:

level(XP) when XP < 100  -> 1;
level(XP) when XP < 200  -> 2;
level(XP) when XP < 500  -> 3;
level(XP) when XP < 1000 -> 4;
% ...more levels...
level(XP) when XP > 1000000 -> 70. % level cap

Ou com uma declaração if, ou um caso, ou uma cadeia de if / elif, ou qualquer que seja o idioma que você esteja usando (Esta parte é o elemento menos interessante de qualquer sistema de jogo, eu apenas forneço duas maneiras, porque eu esteja no modo Erlang agora e a sintaxe acima pode não ser óbvia para todos.):

level(XP) ->
    if
        XP < 100  -> 1;
        XP < 200  -> 2;
        XP < 500  -> 3;
        XP < 1000 -> 4;
        % ...more levels...
        XP > 1000000 -> 70 % level cap
    end.

É matemática incrível? Não. Não mesmo. É implementação manual da determinação do elemento de ajuste? Sim. Isso é tudo o que é, e isso é muito bonito a maneira que eu vi isso realmente feito na maioria dos jogos ao longo dos anos.

Como nota lateral, isso não deve ser feito toda vez que o jogador ganha experiência. Normalmente, você monitora "XP para ir" como um valor e, uma vez que o jogador esgota ou ultrapassa o valor "para ir" (seja lá como você estiver fazendo), você calcula isso uma vez para descobrir onde o jogador está realmente em, armazene isso, calcule o próximo "ir" menos as sobras (se o transporte de XP for permitido) e repita.

zxq9
fonte