GMBR
Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.
Entrar

Esqueci-me da senha

Últimos assuntos
» Como ajustar velocidade de cada frame da animação no game maker
por Ralphed Ontem à(s) 18:28

» PROBLEMAS COM FÍSICAS DE ÁGUA
por aminaro Ter 16 Abr 2024, 10:07

» Retorno da GMBR!!!
por Ralphed Sex 12 Abr 2024, 22:45

» JOGADOR PARANDO NO AR QUANDO ATACA
por aminaro Qua 10 Abr 2024, 13:51

» Problemas com texto interativo
por Kaaru72 Dom 07 Abr 2024, 11:31

» Erro escondido e indecifrável
por dev_gabize.azv Qui 04 Abr 2024, 10:11

» Mudar cor de apenas uma palavra
por Ralphed Sáb 30 Mar 2024, 00:39

» Procuro Programador de game maker
por Wou Sex 15 Mar 2024, 10:27

» Mod APK
por gamerainha Qua 13 Mar 2024, 06:30

» Aceito pedidos de sprites (Com exemplos meus)
por Sevilha Qua 28 Fev 2024, 12:17

» Inventário simples
por Isquilo_Roedor Qui 22 Fev 2024, 15:18

» Problemas na programaçnao de inimigo [jogo DOOM LIKE]
por Black Mirror Dom 11 Fev 2024, 13:34

» ANDROID MULTI TOUCH
por DiegoBr Dom 04 Fev 2024, 12:13

» Servidor de Discord do fórum?
por Lighter Sáb 27 Jan 2024, 17:18

» Save e Load Json
por Klinton Rodrigues Qui 25 Jan 2024, 11:12

» Colisão com mais de um objeto
por aminaro Seg 22 Jan 2024, 15:02

» Oi sou novo aqui
por Thiago Silveira Alexandre Sáb 20 Jan 2024, 20:55

» Como acessar conteudo comprado no marketplace
por macmilam Sex 19 Jan 2024, 07:42

» Devlogs em vídeos do Block Room
por Joton Seg 15 Jan 2024, 16:56

» Alguém aqui já ganha dinheiro com seus games?
por Joton Seg 15 Jan 2024, 16:49

» ACERVO GMBR MAGAZINE
por Joton Qui 11 Jan 2024, 19:21

» como aumentar o obj sem aumentar a colisão??
por GabrielXavier Qua 10 Jan 2024, 07:21

» Asteroid Core - Early Acesse Update [0.2.0.0]
por JOZ. Seg 08 Jan 2024, 14:39

» Versionamento de código com GitHub
por GabrielXavier Seg 08 Jan 2024, 07:32

» Rio Rise - novo launcher do Gta San Andreas SAMP Brasil
por kolesovsup Sex 29 Dez 2023, 07:16


[Ajuda] Tiro seguir objeto dentro do alcance

3 participantes

Ir para baixo

[Ajuda] Tiro seguir objeto dentro do alcance Empty [Ajuda] Tiro seguir objeto dentro do alcance

Mensagem por Harus Sáb 01 Jun 2013, 12:11

Olá a todos!

Venho acompanhando o fórum há algum tempo e estou tentando aprender a usar o GM por conta, acompanhando os tutoriais e as dúvidas do pessoal.
Sou iniciante e ainda um pouco dependente de D&D.

Estou tentando criar um game no estilo tower defense e me deparei com o seguinte problema:

[Ajuda] Tiro seguir objeto dentro do alcance Exempl[img][/img][img][/img]

Preciso atender os seguintes aspectos:

- A torre começa a atacar quando um inimigo entra no alcance dela.
- Quando não tem inimigos dentro do alcance, a torre não ataca.
- No caso de dois ou mais inimigos dentro do alcance, a torre da preferência para atacar o que estiver mais próximo do final do caminho.

Para saber quando o inimigo está próximo eu uso o comando: if (distance_to_object (obj_enemy) < range)
Isso ativa um alarm que cria a instância do tiro.
No Step do tiro eu uso: move_towards_point(instance_nearest(x,y,obj_enemy).x,instance_nearest(x,y,obj_enemy).y, 8 )

O problema de usar esse comando é que ele ataca o inimigo mais próximo da torre, e não o mais próximo do final do caminho.

Tentei criar um objeto do final do caminho chamado de obj_end_line e trocar o Step do tiro pelo seguinte movimento:
move_towards_point(instance_nearest(obj_end_line.x,obj_end_line.y,obj_enemy).x,instance_nearest(obj_end_line.x,obj_end_line.y,obj_enemy).y, 8 );

Agora ele ataca o inimigo que está a frente, mas tem um problema crucial: O tiro não segue necessáriamente o inimigo que está dentro do alcance da torre, ele segue livremente pelo mapa o inimigo mais próximo do obj_end_line. Por exemplo, na imagem acima, como tem inimigos próximos da primeira torre, os tiros desta primeira torre estariam seguindo o primeiro inimigo lá da frente.

Eu preciso de um comando que escolha dentre os inimigos no alcance da torre, o que está mais próximo do final do caminho.

Não sei se fui bem claro, hehe.

Estou quebrando a cabeça aqui...

Desde já agradeço pela atenção;
Harus
Harus

Data de inscrição : 19/01/2013
Reputação : 0
Número de Mensagens : 2
Prêmios : [Ajuda] Tiro seguir objeto dentro do alcance Empty

Medalhas x 0 Tutoriais x 0 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Ir para o topo Ir para baixo

[Ajuda] Tiro seguir objeto dentro do alcance Empty Re: [Ajuda] Tiro seguir objeto dentro do alcance

Mensagem por PedroX Sáb 01 Jun 2013, 13:53

Você precisa de uma condição composta (dupla). O problema é um pouco complexo, mas podemos usar uma ds_priority...

Primeiro, vamos criar uma lista das instâncias ao alcance da torre, em ordem crescente de distância (prioridade). Esse código deve ser posto dentro do evento (ou código) que dispara o tiro da torre.

Código:
ao_alcance = ds_priority_create();
with (OBJ_INIMIGO) {
 if (distance_to_object(OBJ_TORRE)<other.alcance) {
    ds_priority_add(other.ao_alcance, id, distance_to_object(other));
}
}
if (!ds_priority_empty(ao_alcance))
{
mais_proximo = ds_priority_find_min(ao_alcance);
while(mais_proximo != instance_nearest(obj_end_line.x, obj_end_line.y) && !ds_priority_empty(ao_alcance))
{
mais_proximo = ds_priority_delete_min(ao_alcance); //deleta, mas pega o valor também (embora o nome da função não indique isso)
}
}
ds_priority_destroy(ao_alcance);
move_towards_point(mais_proximo.x, mais_proximo.y, VELOCIDADE );

Espero que sirva, pois pesquisei bastante as funções.

Ver:
http://wiki.yoyogames.com/index.php/GML_Functions:_Priority_Queues
https://gmbr.forumeiros.com/t19975-tutorial-com-lasers#149793

Até mais!

_________________


Leia o Manual do Iniciante e a Lista de Tutoriais, para aprender bastante sobre o GM.
Recomendo o Manual completo das colisões, bem útil.
O exemplo Criar um chat (banir, kickar, etc) é interessante.

Para seu jogo ficar rápido e legal, aprenda a Aumentar o desempenho do seu jogo.

Aprenda a calcular a velocidade de suas animações


Entre para o Clube do Inglês:
PedroX
PedroX

Games Ranking : Nota B

Notas recebidas : C+B
Data de inscrição : 26/07/2008
Reputação : 311
Número de Mensagens : 6087
Prêmios : [Ajuda] Tiro seguir objeto dentro do alcance Empty

Medalhas x 0 Tutoriais x 17 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

https://web.whatsapp.com/send?phone=5519995935953&text=Pedro

Ir para o topo Ir para baixo

[Ajuda] Tiro seguir objeto dentro do alcance Empty Re: [Ajuda] Tiro seguir objeto dentro do alcance

Mensagem por saim Sáb 01 Jun 2013, 18:36

Calma, PedroX, coisas simples primeiro. É o primeiro post do cara, ele ainda está usando DND.

MAS você não está errado em nada. Sua solução é ótima. Só que data structures são um tanto complexas pra um primeiro contato com a comunidade. Vou tentar uma aproximação mais simples. Embora você esteja certo também em afirmar que NÃO É um problema simples.

Primeiro, aquilo que não aparece na pergunta: como os inimigos fazem a curva? É um path? Se for, tem uma variável neles que você pode usar pra saber quem está mais à frente: path_position. Ela te armazena um número de 0 a 1 que representa o quanto do path o objeto já percorreu. Nem preciso dizer qual número representa um objeto mais perto do final, certo?

Agora, pra torre atirar, ela primeiro vai verificar se tem ALGUÉM ao alcance. Tendo, atira. Mas, se for atirar, que seja no que está mais adiantado. Certo?
Vou começar usando seu código:

Código:
if (distance_to_object (obj_enemy) < range){
// vai sair tiro
}

Aí, dentro do código genérico que eu coloquei como comentário, você vai:
- escolher o inimigo com a maior path_position (e que esteja na linha de tiro)
- criar um tiro
- explicar pro tiro quem é a vítima

O maior problema é escolher a vítima, mas com um pouco de gml e geometria, fica mole. Com gml você vai aprender a usar a declaração "with" e as variáveis "var".
Variáveis "var" só existem dentro de um código. Elas não estão em nenhum objeto, estão naquele código e morrem no final dele. Além de serem leves na memória, você pode entrar numa declaração "with" com elas sem se preocupar com o objeto em que elas estão.
Uma declaração "with" é percorrida em todos os objetos que atendem pelo nome dado no argumento. Isso pode ficar bem complexo, mas por enquanto vamos considerar que "with(obj_inimigo)" vai rodar um código em todos os obj_inimigo.

Vamos melhorar um pouco nosso código, então.
Código:
if (distance_to_object (obj_enemy) < range){ // se é pra atirar
var vitima;
with(obj_enemy){ // aqui eu começo a rodar códigos dentro dos inimigos
// se está na linha de tiro e é o mais próximo do final
vitima = self; // note que "vitima" é uma variável "var".
} // aqui eu volto pra torre
with(instance_create(x, y, obj_tiro){ // aqui eu crio um tiro - e já começo a escrever nele
alvo = vitima;
} // aqui eu paro de escrever no tiro
}
O que é "self"? É a id do objeto. Pode ser substituído por "id". Na verdade, ninguem usa "self". E o que é id? É um número gerado automaticamente pra cada instância, que a representa. Cada instância sabe sua id e tem um monte de funções que te retornam o número das ids. Informação valiosa, anote isso num papel.

A segunda parte do código já está explicada. Já verifiquei se é pra criar um tiro e já sei quem é a vítima. Falo pro tiro quem é o coitado que o tiro vai saber quem seguir.
A parte da geometria. Basicamente, o conceito envolvido é: se a sua distância até a mim é x, a minha distância até você é x. Bem básico.
É o seguinte, eu só usei o range da torre pra saber se é pra criar um tiro, ainda não expliquei que o tiro deve seguir um inimigo que está na linha de tiro.
Quem vai explicar isso é o inimigo. Não conta isso pro jogador, tá?

penúltima parte:
Código:
if (distance_to_object (obj_enemy) < range){ // se é pra atirar
var vitima;
with(obj_enemy){ // aqui eu começo a rodar códigos dentro dos inimigos
if (distance_to_object(other) < other . range) // && tá mais perto do fim
vitima = self; // note que "vitima" é uma variável "var".
} // aqui eu volto pra torre
with(instance_create(x, y, obj_tiro){ // aqui eu crio um tiro - e já começo a escrever nele
alvo = vitima;
} // aqui eu paro de escrever no tiro
}

Tem esse "other". Ele não servia só pra colisão?
Não, ele é útil pra caramba. De fato, num evento de colisão, "other" significa "o objeto colidido". Mas dentro de um "with", significa "a instância que chamou o código". Eu gosto de chamar de "a instância original".

Mole? É, eu sei. Mas o difícil já ficou pra trás. De agora pra frente fica mole, mesmo.
Também, já está quase acabando.

Código:
if (distance_to_object (obj_enemy) < range){ // se é pra atirar
var vitima, dist;
dist = 0; // o path_position da vitima (começa com 0)
with(obj_enemy){ // aqui eu começo a rodar códigos dentro dos inimigos
if (distance_to_object(other) < other . range && path_position > dist)
vitima = self; // note que "vitima" é uma variável "var".
dist = path_position; // pulo do gato
} // aqui eu volto pra torre
with(instance_create(x, y, obj_tiro){ // aqui eu crio um tiro - e já começo a escrever nele
alvo = vitima;
} // aqui eu paro de escrever no tiro
}
"Não saquei o pulo do gato..."
seguinte... "dist" começa como zero. não tem como ser menor que isso. Qualquer inimigo que não esteja fora do alcance vai ter um path_position maior que esse. Aí, se ele atender aos requisitos do "if" (estar ao alcance da torre E ter um valor de path_position maior que "dist"), ele vai ser a próxima vítima. Antes de criar o tiro, eu vou correr esse código em todos os obj_enemy, garantindo que o valor de "vitima" vai ser a id da instância DENTRO da linha de tiro e que esteja mais perto do final.

UFA! E eu comecei a escrever porque achei a resposta do PedroX complexa... Foi mal, PedroX, eu acabei complicando a coisa, também. Mas agora já escrevi pra caramba, não vou jogar fora.
Espero que o código esteja bem explicado, de qualquer forma.
saim
saim

Games Ranking : Nota B

Notas recebidas : C-D-A-B
Data de inscrição : 14/01/2011
Reputação : 136
Número de Mensagens : 3033
Prêmios : [Ajuda] Tiro seguir objeto dentro do alcance Empty

Medalhas x 1 Tutoriais x 6 Moedas x 0

Ouro x 1 Prata x 0 Bronze x 3

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Ir para o topo Ir para baixo

[Ajuda] Tiro seguir objeto dentro do alcance Empty Re: [Ajuda] Tiro seguir objeto dentro do alcance

Mensagem por PedroX Sáb 01 Jun 2013, 18:44

Gostei da sua solução. Na verdade, eu fiquei pensando um bom tempo antes de responder e só pensei em ds_priority. O motivo foi que um usuário me perguntou recentemente, por MP, qual era o tópico que você [saim] fez e que eu [Pedro] tinha postado uma solução com ds_priority. É o tutorial "Com lasers", do link que coloquei num post acima.

De qualquer forma, são 2 maneiras de chegar ao mesmo resultado. Ambas parecem funcionar sem bugs (não testei nenhuma). O que não faltou foi solução.

_________________


Leia o Manual do Iniciante e a Lista de Tutoriais, para aprender bastante sobre o GM.
Recomendo o Manual completo das colisões, bem útil.
O exemplo Criar um chat (banir, kickar, etc) é interessante.

Para seu jogo ficar rápido e legal, aprenda a Aumentar o desempenho do seu jogo.

Aprenda a calcular a velocidade de suas animações


Entre para o Clube do Inglês:
PedroX
PedroX

Games Ranking : Nota B

Notas recebidas : C+B
Data de inscrição : 26/07/2008
Reputação : 311
Número de Mensagens : 6087
Prêmios : [Ajuda] Tiro seguir objeto dentro do alcance Empty

Medalhas x 0 Tutoriais x 17 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

https://web.whatsapp.com/send?phone=5519995935953&text=Pedro

Ir para o topo Ir para baixo

[Ajuda] Tiro seguir objeto dentro do alcance Empty Re: [Ajuda] Tiro seguir objeto dentro do alcance

Mensagem por Harus Sáb 01 Jun 2013, 23:53

Primeiramente, agradeço pela ajuda!

Consegui adaptar no game o método do Saim. Aliás, está muito bem explicado. Já deu pra perceber que sou obrigado a desenvolver cada vez mais o gml, porque D&D é bem limitado, o que eu já esperava... O fato de conseguir manipular diferentes objetos, escrever neles, tomar ações com o other, e tudo isso dentro de um único script facilita demais a vida!

Só deu certo usando "id" ao invés de "self"... Não sei se tem a ver com o fato de estar usando GM Studio.

Também tentei o método do PedroX. Tentei, tentei mesmo fazer funcionar, mas não consigo...É bem provável que eu esteja fazendo algo errado, mas ele da erro quando um inimigo morre, ou o tiro se perde e fica indeciso em qual inimigo atacar, enfim, aconteceu variados problemas conforme eu tentava adaptar.

De qualquer modo foi tudo muito útil e aprendi mais um pouco.

Muito obrigado!
Harus
Harus

Data de inscrição : 19/01/2013
Reputação : 0
Número de Mensagens : 2
Prêmios : [Ajuda] Tiro seguir objeto dentro do alcance Empty

Medalhas x 0 Tutoriais x 0 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Ir para o topo Ir para baixo

[Ajuda] Tiro seguir objeto dentro do alcance Empty Re: [Ajuda] Tiro seguir objeto dentro do alcance

Mensagem por saim Seg 03 Jun 2013, 06:27

Harus escreveu:Só deu certo usando "id" ao invés de "self"... Não sei se tem a ver com o fato de estar usando GM Studio.
Não sei o que pode ser. Não acho que seja o GMS, nunca ouvi falar de eliminarem essa variável (que, de fato, não faria falta).
Harus escreveu:da erro quando um inimigo morre, ou o tiro se perde e fica indeciso em qual inimigo atacar, enfim, aconteceu variados problemas conforme eu tentava adaptar.
Ehm... meu método também não prevê o que fazer quando o inimigo morre e o tiro já foi criado...
Bom, eu presumi (corretamente) que você soubesse o que fazer com o tiro, uma vez que ele estivesse criado. Ele deve se mover towards alvo.x, alvo.y. Mas "alvo" é a id de uma instância que pode ser eliminada antes do tiro chegar lá. Por exemplo, duas torres podem atirar ao mesmo tempo e o tiro de uma pode matar o obj_enemy antes do tiro da outra chegar. Nesse caso, o tiro restante vai tentar se mover em direção a uma instância que não existe mais. O resultado é o erro "unknown variable 'x'".

Solução? Mover-se em direção a uma instância que exista. No step, mova-se apenas se a instância existir.
Código:
if (instance_exists(alvo)){
move_towards(alvo.x, alvo.y, velocidade); // não sei se é desse jeito
}
else{
// elimina o tiro (o jogador não deve notar), escolhe outro alvo, sei lá
}

Você também pode gravar a posição que o alvo está e, se ele não existir mais, rumar pra essa posição e explodir quando a distância até ela for menor que a velocidade (dificilmente o tiro vai ficar EXATAMENTE na posição correta). Ou, dentro do inimigo, quando ele estiver morrendo, rodar um
Código:
with(obj_tiro){ // roda em todos os tiros existentes
if (alvo == other){ // escolhe apenas aqueles que me acertariam
// fazer alguma coisa
}
}
// pronto, já pode morrer
Seja qual for a solução, é importante prever esse caso do alvo simplesmente sumir e o tiro ficar sem saber o que fazer.
saim
saim

Games Ranking : Nota B

Notas recebidas : C-D-A-B
Data de inscrição : 14/01/2011
Reputação : 136
Número de Mensagens : 3033
Prêmios : [Ajuda] Tiro seguir objeto dentro do alcance Empty

Medalhas x 1 Tutoriais x 6 Moedas x 0

Ouro x 1 Prata x 0 Bronze x 3

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Ir para o topo Ir para baixo

[Ajuda] Tiro seguir objeto dentro do alcance Empty Re: [Ajuda] Tiro seguir objeto dentro do alcance

Mensagem por Conteúdo patrocinado


Conteúdo patrocinado


Ir para o topo Ir para baixo

Ir para o topo

- Tópicos semelhantes

 
Permissões neste sub-fórum
Não podes responder a tópicos