Django Wars [Parte 19]: Dando um Level Up no jogador

O Django Wars foi idealizado e desenvolvido no Django 1.4. Algumas funcionalidades aqui descritas podem não funcionar ou funcionar de forma diferente em outras versões do Django

Nosso jogador não vai ficar apenas cometendo crimes e mais crimes e mais crimes e mais crimes…
Assim, sem sentido.
Cometer crimes é uma fonte de lucro e experiência.
Com o lucro ele compra armas e armaduras, e com a experiência ele sobe de nível.
Como já criamos toda a parte da loja de equipamentos e inventário do usuário, está faltando implementer a experiência e o nível.

Em primeiro lugar, o que o usuário ganha ao passar de nível?
Ele recupera seus status (hp, energia e raiva) e ganha pontos para distribuir nos seus atributos.
Porém, esse pontos não foram descritos anteriormente no models.py que define o Player.
Mas isso é tranquilo, basta adicionarmos a seguinte linha na class Player():

#pontos ao subir de nivel
    pontos = models.PositiveSmallIntegerField(default=0)

Para atualizar a tabela no banco de dados, temos o enorme sacrifício de escrever a seguinte linha de comando:

python manage.py syncdb

Só nos falta definir quando te experiência um jogador precisa para subir de nível, e criar uma função que suba de nível.

Para definir quanto de experiência um jogador precisa para passar de nível poderíamos fazer uma progressão geométrica.
Porém, esta progressão seria muito injusta para jogadores de nível mais alto, que sofreriam muito para subir de nível, visto que a progressão poderia ter um requisito muito alto para adquirir um nível que deveria ser “comum”, como um nível 10.
A idéia que queremos é que, nos primeiros níveis, como os 4 primeiros, seja bem fácil de conseguir.
Os níveis até 10 ou 12, tenha uma pequena dificuldade e, a partir dai, a dificuldade começar a crescer, mas não tanto.
Não queremos muitos players de nível alto, este é um desafio, mas também não queremos que seja impossível de ser conquistado, ou o jogador não vai sentir prazer em jogar e vai desistir do jogo.
Poderíamos passar um tempo discutindo funções polinomiais e equações, mas nosso foco é programar.
Por isso, vamos definir a experiência necessária manualmente.
Mas, onde eu vou salvar esta função?
Hora bolas carambolas, dentro da classe que definimos o Player, no arquivo models.py.
Afinal, esta função faz parte do player, nada mais justo que estar dentro da definição do Player, como ensina a documentação do Django.

#verifica se o player subiu de nivel
def level_up(self):
    #definimos a quantidade de xp para cada nivel
    experiencia_necessaria = {1: 10, 2: 20, 3: 30, 4: 50, 5: 80,
                              6: 130, 7: 210, 8: 340, 9: 480, 10: 630,
                              11: 790, 12: 970, 13: 1200, 14: 1600, 15: 2000,
                              16: 2500, 17: 3000, 18: 4000, 19: 5000, 20: 6000}
    
    if self.experiencia >= experiencia_necessaria[self.nivel + 1]:
        self.nivel = self.nivel + 1 #sobe de nivel
        self.pontos = self.pontos + 5 #adiciona 5 pontos para o usuario distribuir
        self.hp = self.vida * 10 #recupera a vida
        self.energia_atual = self.energia #recupera a energia
        self.raiva_atual = self.raiva #recupera a raiva
        
        return True
    else:
        return False

Como pode-se facilmente perceber, o que essa função faz é verificar se o player tem experiência suficiente para subir de nível.
Em caso afirmativo, sobe de nível, recupera o jogador e retorna True.
Em caso negativo, retorna False.

Para mostrar uma forma simples de utilizar o método que acabamos de criar, o level_up, vou alterar a view cometer_crime1 do arquivo views.py.

# cometendo o crime de nivel 1
def cometer_crime1(request):
    if not request.user.is_authenticated():
        return redirect(logar)

    player = request.user.get_profile()

    if player.energia_atual < 1:
        return redirect(crimes)

    player.carteira = player.carteira + (11 * randint(0, player.ataque))
    player.energia_atual = player.energia_atual - 1
    
    #adiciona experiencia ao jogador
    player.experiencia = player.experiencia + 10
    
    #verifica se o jogador subiu de nivel
    player.level_up()
    
    player.save()
    return redirect(crimes)

Note que adicionei a linha 88, que dá experiência ao jogador.
Agora, ao cometer aquele crime, ele ganha 10 de experiência.
Em seguida, executo o level_up() para que as novidades que criamos sejam executadas.

Basta replicar essas alterações nas outras views de crimes, dando mais experiência para crimes mais difíceis.
Por exemplo, o crime 2 dá 20 de experiência e o crime 3 dá 50.
Fica a critério do game designer 😀

Vish, que postagem grande…

O código fonte do projeto, com histórico de modificações e afins, encontra-se em:
https://github.com/frenetic/django-wars

4 thoughts on “Django Wars [Parte 19]: Dando um Level Up no jogador

  1. oi, tenho uma dúvida, quando eu vou registrar um usuario no formulario o seguinte erro é exibido: user_id may not be NULL… alguem poderia me ajudar ?

    1. Olá Lucas,

      pode ter ocorrido que os teus modelos (arquivos models.py) tenham perdido a sincronia com o banco de dados.
      Sugiro que você execute o comando [manage.py syncdb]

      Se nada der certo, por se tratar de um ambiente de testes/desenvolvimento, pode ser que excluíndo o teu arquivo de banco de dados SQLite e começando um novo tudo se resolva.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *