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
Agora é a hora boa, a hora que nosso site vai separar os meninos dos homens.
Os homens estão no trabalho e os meninos estão em casa atacando os coitados que estão ocupados…
Primeiro, a url que leva ao coro comer no centro.
url(r'^alvos/atacar/(\d+)/$', djangowars.views.luta.atacar),
url(r'^alvos/atacar/(\d+)/$', djangowars.views.luta.atacar),
url(r'^alvos/atacar/(\d+)/$', djangowars.views.luta.atacar),
Agora que vem a parte boa, a view que calcula o fight.
Vou colocá-la no arquivo views/luta.py:
def atacar(request, alvo_id):
if not request.user.is_authenticated():
return redirect('pagina_de_login')
#verifica se esta sendo passado um alvo valido
alvo = get_object_or_404(Player, pk=alvo_id)
#pega o nosso jogador da sessao
jogador = request.user.get_profile()
#verifica se a experiencia do alvo eh menor que 60% da experiencia do atacante
if jogador.experiencia * 0.6 > alvo.experiencia:
#atualiza o alvo e o jogador
#verifica se o nosso jogador possui raiva para atacar
if jogador.raiva_atual == 0:
#verifica se o nosso jogador esta "morto"
#verifica se o alvo esta 'morto'
#salva o hp inicial do jogador e do alvo para fazer um pequeno relatorio no final
#pega o valor da arma do jogador
jogador_arma = jogador.arma_ativa.poder
#pega o valor da armadura do jogador
if jogador.armadura_ativa:
jogador_armadura = jogador.armadura_ativa.poder
#pega o valor da arma do alvo
alvo_arma = alvo.arma_ativa.poder
#pega o valor da armadura do alvo
alvo_armadura = alvo.armadura_ativa.poder
#agora o bicho vai pegar!
for turno in [1, 2, 3, 4, 5]:
#primeiro o jogador ataca
ataque = randint(jogador.ataque/3, jogador.ataque)
defesa = randint(alvo.defesa/3, alvo.defesa)
dano = ataque * jogador_arma - defesa * alvo_armadura
ataque = randint(alvo.ataque/3, alvo.ataque)
defesa = randint(jogador.defesa/3, jogador.defesa)
dano = ataque * alvo_arma - defesa * jogador_armadura
jogador.hp = jogador.hp - dano
#verifica se alguem morreu no combate
if jogador.hp == 0 or alvo.hp == 0:
elif alvo_hp - alvo.hp > jogador_hp - jogador.hp:
#se o jogador ganhou, tira dinheiro do alvo e da ao jogador
grana = alvo.carteira * ( randint(10, 90)/100.0 ) #entre 10% e 90% do valor da carteira
alvo.carteira = alvo.carteira - grana
jogador.carteira = jogador.carteira + grana
#ganha 10% da experiencia do adversario
jogador.experiencia = jogador.experiencia + alvo.experiencia * 0.1
grana = jogador.carteira * ( randint(10, 90)/100.0 ) #entre 10% e 90% do valor da carteira
alvo.carteira = alvo.carteira + grana
jogador.carteira = jogador.carteira - grana
#ganha 10% da experiencia do adversario
alvo.experiencia = alvo.experiencia + jogador.experiencia * 0.1
# o nosso atacante perde 1 de raiva
jogador.raiva_atual = jogador.raiva_atual - 1
#verifica se alguem deu level up
#salva todas as alteracoes no banco de dados
#exibe o template com o resultado da luta
return render_to_response("atacar.html", {"player": jogador,
"vida": jogador.vida * 10,
"jogador_hp": jogador_hp,
#view da luta
def atacar(request, alvo_id):
if not request.user.is_authenticated():
return redirect('pagina_de_login')
#verifica se esta sendo passado um alvo valido
alvo = get_object_or_404(Player, pk=alvo_id)
#pega o nosso jogador da sessao
jogador = request.user.get_profile()
#verifica se a experiencia do alvo eh menor que 60% da experiencia do atacante
if jogador.experiencia * 0.6 > alvo.experiencia:
return redirect(alvos)
#atualiza o alvo e o jogador
alvo.refresh()
jogador.refresh()
#verifica se o nosso jogador possui raiva para atacar
if jogador.raiva_atual == 0:
return redirect(alvos)
#verifica se o nosso jogador esta "morto"
if jogador.hp == 0:
return redirect(alvos)
#verifica se o alvo esta 'morto'
if alvo.hp == 0:
return redirect(alvos)
#salva o hp inicial do jogador e do alvo para fazer um pequeno relatorio no final
jogador_hp = jogador.hp
alvo_hp = alvo.hp
#pega o valor da arma do jogador
if jogador.arma_ativa:
jogador_arma = jogador.arma_ativa.poder
else:
jogador_arma = 1
#pega o valor da armadura do jogador
if jogador.armadura_ativa:
jogador_armadura = jogador.armadura_ativa.poder
else:
jogador_armadura = 1
#pega o valor da arma do alvo
if alvo.arma_ativa:
alvo_arma = alvo.arma_ativa.poder
else:
alvo_arma = 1
#pega o valor da armadura do alvo
if alvo.armadura_ativa:
alvo_armadura = alvo.armadura_ativa.poder
else:
alvo_armadura = 1
#agora o bicho vai pegar!
#a luta dura 5 turnos
for turno in [1, 2, 3, 4, 5]:
#primeiro o jogador ataca
ataque = randint(jogador.ataque/3, jogador.ataque)
defesa = randint(alvo.defesa/3, alvo.defesa)
#calcula o dano
dano = ataque * jogador_arma - defesa * alvo_armadura
if dano > 0:
alvo.hp = alvo.hp - dano
#agora o alvo ataca
ataque = randint(alvo.ataque/3, alvo.ataque)
defesa = randint(jogador.defesa/3, jogador.defesa)
#calcula o dano
dano = ataque * alvo_arma - defesa * jogador_armadura
if dano > 0:
jogador.hp = jogador.hp - dano
#verifica se alguem morreu no combate
if jogador.hp == 0 or alvo.hp == 0:
break
#descobrindo quem perdeu
if jogador.hp == 0:
vitoria = False
elif alvo.hp == 0:
vitoria = True
elif alvo_hp - alvo.hp > jogador_hp - jogador.hp:
vitoria = True
else:
vitoria = False
#se o jogador ganhou, tira dinheiro do alvo e da ao jogador
if vitoria:
grana = alvo.carteira * ( randint(10, 90)/100.0 ) #entre 10% e 90% do valor da carteira
grana = round(grana)
alvo.carteira = alvo.carteira - grana
jogador.carteira = jogador.carteira + grana
#ganha 10% da experiencia do adversario
jogador.experiencia = jogador.experiencia + alvo.experiencia * 0.1
else:
grana = jogador.carteira * ( randint(10, 90)/100.0 ) #entre 10% e 90% do valor da carteira
grana = round(grana)
alvo.carteira = alvo.carteira + grana
jogador.carteira = jogador.carteira - grana
#ganha 10% da experiencia do adversario
alvo.experiencia = alvo.experiencia + jogador.experiencia * 0.1
# o nosso atacante perde 1 de raiva
jogador.raiva_atual = jogador.raiva_atual - 1
#verifica se alguem deu level up
alvo.level_up()
jogador.level_up()
#salva todas as alteracoes no banco de dados
alvo.save()
jogador.save()
#exibe o template com o resultado da luta
return render_to_response("atacar.html", {"player": jogador,
"vida": jogador.vida * 10,
"alvo": alvo,
"vitoria": vitoria,
"grana": grana,
"jogador_hp": jogador_hp,
"alvo_hp": alvo_hp})
#view da luta
def atacar(request, alvo_id):
if not request.user.is_authenticated():
return redirect('pagina_de_login')
#verifica se esta sendo passado um alvo valido
alvo = get_object_or_404(Player, pk=alvo_id)
#pega o nosso jogador da sessao
jogador = request.user.get_profile()
#verifica se a experiencia do alvo eh menor que 60% da experiencia do atacante
if jogador.experiencia * 0.6 > alvo.experiencia:
return redirect(alvos)
#atualiza o alvo e o jogador
alvo.refresh()
jogador.refresh()
#verifica se o nosso jogador possui raiva para atacar
if jogador.raiva_atual == 0:
return redirect(alvos)
#verifica se o nosso jogador esta "morto"
if jogador.hp == 0:
return redirect(alvos)
#verifica se o alvo esta 'morto'
if alvo.hp == 0:
return redirect(alvos)
#salva o hp inicial do jogador e do alvo para fazer um pequeno relatorio no final
jogador_hp = jogador.hp
alvo_hp = alvo.hp
#pega o valor da arma do jogador
if jogador.arma_ativa:
jogador_arma = jogador.arma_ativa.poder
else:
jogador_arma = 1
#pega o valor da armadura do jogador
if jogador.armadura_ativa:
jogador_armadura = jogador.armadura_ativa.poder
else:
jogador_armadura = 1
#pega o valor da arma do alvo
if alvo.arma_ativa:
alvo_arma = alvo.arma_ativa.poder
else:
alvo_arma = 1
#pega o valor da armadura do alvo
if alvo.armadura_ativa:
alvo_armadura = alvo.armadura_ativa.poder
else:
alvo_armadura = 1
#agora o bicho vai pegar!
#a luta dura 5 turnos
for turno in [1, 2, 3, 4, 5]:
#primeiro o jogador ataca
ataque = randint(jogador.ataque/3, jogador.ataque)
defesa = randint(alvo.defesa/3, alvo.defesa)
#calcula o dano
dano = ataque * jogador_arma - defesa * alvo_armadura
if dano > 0:
alvo.hp = alvo.hp - dano
#agora o alvo ataca
ataque = randint(alvo.ataque/3, alvo.ataque)
defesa = randint(jogador.defesa/3, jogador.defesa)
#calcula o dano
dano = ataque * alvo_arma - defesa * jogador_armadura
if dano > 0:
jogador.hp = jogador.hp - dano
#verifica se alguem morreu no combate
if jogador.hp == 0 or alvo.hp == 0:
break
#descobrindo quem perdeu
if jogador.hp == 0:
vitoria = False
elif alvo.hp == 0:
vitoria = True
elif alvo_hp - alvo.hp > jogador_hp - jogador.hp:
vitoria = True
else:
vitoria = False
#se o jogador ganhou, tira dinheiro do alvo e da ao jogador
if vitoria:
grana = alvo.carteira * ( randint(10, 90)/100.0 ) #entre 10% e 90% do valor da carteira
grana = round(grana)
alvo.carteira = alvo.carteira - grana
jogador.carteira = jogador.carteira + grana
#ganha 10% da experiencia do adversario
jogador.experiencia = jogador.experiencia + alvo.experiencia * 0.1
else:
grana = jogador.carteira * ( randint(10, 90)/100.0 ) #entre 10% e 90% do valor da carteira
grana = round(grana)
alvo.carteira = alvo.carteira + grana
jogador.carteira = jogador.carteira - grana
#ganha 10% da experiencia do adversario
alvo.experiencia = alvo.experiencia + jogador.experiencia * 0.1
# o nosso atacante perde 1 de raiva
jogador.raiva_atual = jogador.raiva_atual - 1
#verifica se alguem deu level up
alvo.level_up()
jogador.level_up()
#salva todas as alteracoes no banco de dados
alvo.save()
jogador.save()
#exibe o template com o resultado da luta
return render_to_response("atacar.html", {"player": jogador,
"vida": jogador.vida * 10,
"alvo": alvo,
"vitoria": vitoria,
"grana": grana,
"jogador_hp": jogador_hp,
"alvo_hp": alvo_hp})
É grande, mas é bem fácil de compreender:
1 – a gente verifica se está sendo passado um jogador válido
2 – verifica se o alvo tem o mínimo de experiência requisitada. Assim, se algum jogador tentar criar uma URL na mão, não vai atacar um jogador mais fraco.
3 – verifica se tem raiva o suficiente para atacar
4 – verifica se nem o alvo e nem o jogador estão mortos. Morto não pode atacar e nem ser atacado, a não ser que sejam zumbis ou vampiros ou mumias.
5 – salva quanto de hp cada um tem antes de começar a luta. Fazemos isso para saber quem perdeu mais hp no final do combate.
6 – pegamos o poder da arma e da armadura do jogador e do alvo.
7 – pequeno loop da luta. as lutas duram 5 turnos
8 – verifica quem venceu. quem morrer, perde. quem perder mais hp, perde
9 – calcula a quantidade de dinheiro que o vencedor rouba do perdedor
10 – tira um ponto de raiva do atacante
11 – verifica se alguem deu level_up
12 – salva tudo
13 – exibe template.
O loop da luta é bem mobral.
Randomiza um número entre um terço do atributo ataque e o ataque inteiro e multiplica esse valor na arma.
Faz o mesmo para a defesa e multiplica o valor na armadura.
A diferença entre o resultado do ataque e o resultado da defesa é o dano que o atacante causa no defensor.
Sussa demais, né?
Eu poderia tentar algo mais parecido com sistemas de RPG de mesa, mas queremos um jogo simples.
Para finalizar, mostramos o template.
atacar.html
Energia {{ player.energia_atual }}/{{ player.energia }}
Raiva {{ player.raiva_atual }}/{{ player.raiva }}
HP: {{ player.hp }}/{{ vida }}
Carteira {{ player.carteira }}
Você atacou <b>{{ alvo.user.username }}</b><br />
Resultado da luta: {% if vitoria %}<b>VITÓRIA!</b>{% else %}<b>DERROTA!</b>{% endif %}<br />
Seu Hp inicial: <b>{{ jogador_hp }}</b>, Hp final: <b>{{ player.hp }}</b><br />
Hp inicial de {{ alvo.user.username }}: <b>{{ alvo_hp }}</b>, Hp final: <b>{{ alvo.hp }}</b><br />
Você recebeu: <b>{{ grana }}</b><br />
Você perdeu: <b>{{ grana }}</b><br />
</div> <!-- /container -->
<div class="container">
<p>
Informações do usuário:
Nível {{ player.nivel }}
|
Energia {{ player.energia_atual }}/{{ player.energia }}
|
Raiva {{ player.raiva_atual }}/{{ player.raiva }}
HP: {{ player.hp }}/{{ vida }}
|
Carteira {{ player.carteira }}
</p>
<!--lista de alvos-->
Você atacou <b>{{ alvo.user.username }}</b><br />
Resultado da luta: {% if vitoria %}<b>VITÓRIA!</b>{% else %}<b>DERROTA!</b>{% endif %}<br />
Seu Hp inicial: <b>{{ jogador_hp }}</b>, Hp final: <b>{{ player.hp }}</b><br />
Hp inicial de {{ alvo.user.username }}: <b>{{ alvo_hp }}</b>, Hp final: <b>{{ alvo.hp }}</b><br />
{% if vitoria %}
Você recebeu: <b>{{ grana }}</b><br />
{% else %}
Você perdeu: <b>{{ grana }}</b><br />
{% endif %}
</div> <!-- /container -->
<div class="container">
<p>
Informações do usuário:
Nível {{ player.nivel }}
|
Energia {{ player.energia_atual }}/{{ player.energia }}
|
Raiva {{ player.raiva_atual }}/{{ player.raiva }}
HP: {{ player.hp }}/{{ vida }}
|
Carteira {{ player.carteira }}
</p>
<!--lista de alvos-->
Você atacou <b>{{ alvo.user.username }}</b><br />
Resultado da luta: {% if vitoria %}<b>VITÓRIA!</b>{% else %}<b>DERROTA!</b>{% endif %}<br />
Seu Hp inicial: <b>{{ jogador_hp }}</b>, Hp final: <b>{{ player.hp }}</b><br />
Hp inicial de {{ alvo.user.username }}: <b>{{ alvo_hp }}</b>, Hp final: <b>{{ alvo.hp }}</b><br />
{% if vitoria %}
Você recebeu: <b>{{ grana }}</b><br />
{% else %}
Você perdeu: <b>{{ grana }}</b><br />
{% endif %}
</div> <!-- /container -->
O código fonte de toda essa gambiarra desse maravilhoso jogo encontra-se em:
https://github.com/frenetic/django-wars
Lá na linha 109 o certo é:
alvo_armadura = alvo.armadura_ativa.poder
Tá ficando massa!
na verdade, tá quase certo
na linha 109 era pra ser
alvo_arma = alvo.arma_ativa.poder
mas ao invés de escrever “alvo_arma” eu só escrevi “alvo”.
Que burro, dá zero pra mim…
Vou corrigir aqui no post e depois coloco no github
Na linha 155, o certo é:
elif alvo_hp – alvo.hp > jogador_hp – jogador.hp:
vitoria = True
else:
vitoria = False
OMG! :O
como que eu confundi saporra?
Corrigindo e colocando no GitHub
As alterações foram feitas na postagem e no código lá no GitHub.
Valeu Diego!