Ir para o conteúdo
Kline777

Tratamento de colisões - Delphi XE5 - Android

Mensagens Recomendadas

Kline777

Bem, como prometido, ando a ver se faço qq coisa em 3D para o Android com o Delphi, provavelmente o pong então :P. No entanto, não se faz nada de jeito sem conseguir detectar as colisões entre objectos e foi aqui que a coisa parou um bocado, dado que apesar de ter sido feito bastante para o VCL e em 2D. Não consegui encontrar nada para FireMonkey.

Assim sendo, e como os meus conhecimentos em geometria e álgebra sempre foram poucos ou nulos, peguei em codigo desse já feito e adaptei para usar os objectos do FireMonkey.

Ainda não fiz nada de especial, apenas umas classezitas e detecção de colisões entre a bola e as paredes. Mas penso que o resto andará rápido.

Pelo teste que já fiz, parece correr no android igual ao que corre no Windows. Obviamente a performance ainda é uma fraqueza, mas neste tipo de aplicação penso que não se irá notar muito.

ff8y.png

Obvio que ainda nao liguei ao aspecto, mas pronto, a parte de andar pelo cenario está feita. Brevemente vou por mais qq coisa sobre isto. Se nao acontecer como de costume, que é fazer as classes com a pica toda e depois parar quando for para implementar no projecto xD

  • Voto 2

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Kline777

Bem, duvida:

Para fazer o movimento dos objectos no espaço, na minha classe existe uma propriedade MovSpeed que basicamente define a velocidade do objecto e se esta for maior que zero, activa uma thread para mover o objecto até que a velocidade volte a zero.

 tthread.CreateAnonymousThread(
   procedure ()
   begin
     //Confirmar que nao arranco com 2  threads a fazerem o mesmo
     if (not _IsMoving) and (_MovSpeed>0) then
     begin
       //Activar Lock
       _IsMoving:=true;
       while (_MovSpeed<>0) do
       begin
         //Mover o objecto consoante a sua velocidade e direcção
         center.X:=center.X+(MovVector.x*MovSpeed);
         center.Y:=center.Y+(MovVector.Y*MovSpeed);
         center.Z:=center.Z+(MovVector.Z*MovSpeed);
         //Sleep para o utilizador ver alguma coisa 
         Sleep(RefreshSpeed);
       end;
       //Desactivar o lock
       _IsMoving:=false;
     end;
   end).Start;

Isto por objecto, ou seja, cada objecto move-se no espaço sem ter ideia do movimento dos outros objectos.

A minha duvida é: Será que isto é uma boa abordagem? Para fazer o tratamento de colisões se calhar pode ser perigoso...

Estou a pensar que se calhar ficava mais seguro com um método que recebia a lista de objectos para mover nesse momento e fazê-lo de forma sequencial....

Assim depois de correr a lista dos objectos a mover, corria novamente para ver se algum tinha colidido, e so depois disso passava para a proxima iteração...

Alguém tem alguma ideia mais limpa e funcional, ou acham que é por aqui? :P

Editado por thoga31
GeSHi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Kline777

J0u4T.png

Bem, depois das ferias e de umas batatadas... já consegui avançar mais um pouco. A bola já anda a bater nas paredes e no pad com as movimentaçoes normais.

Basicamente estou a fazer uma unit que se possa incluir num qualquer projecto Firemonkey e que com umas 5 ou 6 linhas de codigo passamos a ter informação das colisoes, adicionar movimentos e fazer uns joguitos basicos com poucas linhas de codigo.

É so adicionar os objectos 3d que quiserem á lista de objectos a 'escutar' e sempre que adicionarem uma direcção e velocidade a um objecto este vai mover-se sem mais programação e a cada colisao dispara um evento com os 2 objectos envolvidos assim como outros campos relevantes.

Está a funcionar no android como no windows, mas como de costume tive muito que me chatear, há coisas que nao se podem usar ou que tem de ser tentativa e erro... por exemplo, nao estou a conseguir usar TList's no android... tive de usar um array, o que me chateia bastante :P

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
bioshock

(...) por exemplo, nao estou a conseguir usar TList's no android... tive de usar um array, o que me chateia bastante :P

Ao que é que te referes propriamente?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
thoga31

Ao facto de termos um tipo de dados muito útil, chamado TList, e que, aparentemente, no Android não está a funcionar devidamente.


Knowledge is free!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Kline777

Ya... presumo que a TList seja basicamente uma lista simples de ponteiros. No windows corre tudo ok, mas no o android a coisa nao aponta para onde deve :P aponta para zonas aleatorias da memoria e dá barrakesh ^^ Mudei para um array de objectos e deu à primeira.

Editado por Kline777

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
bioshock

Pelo que estive a ver aqui http://www.delphibasics.co.uk/RTL.asp?Name=TList, eventualmente, o que mais se pode semelhar em Android são as list.

List<customers> customer = new ArrayList<customers>();

Onde customers é uma classe.

Se quiseres por exemplo dois pontos de referência String, Integer, utilizas o Map.

Map<String, Integer>customers = new HashMap<String, Integer>();

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
bioshock

Eu sei..tinha-me era esquecido que o código é todo compilado em Delphi. Quando escrevi aquilo, estava na ideia que ele tinha ido fazer umas alterações ao código Java. :D

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Kline777
:P Nope... a ideia é ter a coisa a compilar para Windows e Android com o mm codigo Delphi. O problema é que pelos vistos algumas funções nao têm correspondencia. Tambem cometi o erro do usar o Application.ProcessMessages inicialmente e tb foi uma dar de cabeça para dar com aquilo, mas aí ja é bem feito que ninguem me manda usar essa funçao por dá cá aquela palha

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Kline777

Boas, estou com um problema por causa do android que nao estou a conseguir dar a volta. Basicamente tenho uma thread a correr sempre para calcular quando a bola bate no fundo, e quando isso acontece aparece uma label com o resultado actual.

Problema: Estou a mudar o text da label DENTRO da thread que criei... Isto nao é problema no windows mas no android nao dá (Não é limitaçao do delphi, no java é igual) pois pelo que percebi nao podemos fazer alteraçoes visuais sem ser na thread principal.

Questão: Tendo eu algo como

procedure A();
begin
 //Do stuff
 Label1.text:=' 0 - 1':
end;
procedure B();
begin
 TThread.CreateAnonymousThread(
procedure ()
begin
  //Do Stuff
  //Chamar funçao A
  A;
end).Start;
end;

Estando nós dentro da thread na funçao B, existe maneira de dizer para a funçao A ser chamada na thread principal?

Ou acham que posso dar a volta de outra maneira?

Editado por Kline777

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
bioshock

Apesar de não te poder fornecer código de delphi, posso dar a ideia. Esse problema que tens é muito comum. Tudo o que tens de fazer é tornar a função A numa thread à parte, eventualmente como fizestes com a função B.

Editado por bioshock

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Kline777

Pois mas parece-me que neste caso (mudar o text de uma label) não posso simplesmente executar a funçao A numa thread nova, mas sim, especificamente na principal... não sei é como lá voltar :P

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
bioshock

Hum? Atrevo-me a dizer que aí há gato.

Imagina que tens duas funções distintas, à partida não inicializadas.

Num evento qualquer, chamas a função A que está dentro de uma thread, que por sua vez chama a função B que também está dentro de uma thread.

procedure A();
begin
 TThread.CreateAnonymousThread(
	procedure ()
	begin
	   B;
	end).Start;
end;

procedure B();
begin
 TThread.CreateAnonymousThread(
	procedure ()
	begin
	   // código
          Label1.text:=' 0 - 1':
	end).Start;
end;

Estamos a falar da mesma classe, correcto? Se sim, isso devia de funcionar..em Java (Android) pelo menos funciona.

Editado por bioshock

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
bioshock

Estamos a falar da mesma classe, correcto? Se sim, isso devia de funcionar..em Java (Android) pelo menos funciona.

Isto responde ao teu último post.

Se me dizes que estás na activity A (ou como quiseres chamar em Delphi) e alteras o conteúdo da Activity B, também é possível. Em Android podes conseguir isso de várias formas, desde bundles, shared preferences, base de dados, etc. Depois é só trabalhar com os eventos.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Kline777

Ok já resolvi o problema.

Apesar de so nao funcionar no java o problema estava mesmo na implementação. Quando não se sabe usar threads como deve ser é assim xD

Pronto o problema é o que tinha referido, mudanças visuais só se pode fazer na main thread.

A solução que arranjei foi deixar de usar o CreateAnonymousThread e fazer uma class descendente da TThread (como se faz normalmente) e lá criar uma funçao só com as linhas de alteração grafica

Quando esta for necessária, nao deve ser chamadar directamente mas sim com o Syncronize();

Algo como:

TGui=Class(TThread);
 var
	 frm:TForm;
 procedure ChangeGUI();
 protected
	 procedure Execute();
end;

procedure TThread.ChangeGUI();
begin
frm.label1.text:='bu!';
end;

procedure TThread.Execute();
begin
//Do work
//Do some more...
Syncronize(ChangeGUI());
// etc...
end;

Enfim.... os programadores vao todos para o ceu de certeza -.-

Editado por Kline777
  • Voto 1

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Kline777

Bem... a minha paciencia para este jogo acabou por agora :P

Está assim

vnli.png

Com a bola a mover, marcar pontuaçao etc...

Agora ainda vou decidir se vou acabar este ou outro que tinha ja feito. Esta minha mania de parar os projecto a +/- 85% de os concluir vai ser a minha ruína :P Mas enfim

  • Voto 1

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
I-NOZex

sei o que isso é, tenho um problema semelhante :D

mas, se quizeres claro, poderias deixar ai a source?

ja nao pego a algum tempo em delphi, andava a querer ver se pegava para usar a parte de apps android, assim aproveitava e via já como é que se faz, em parte, uma app android em delphi (:


B2R » Beat2Revolution v3.0b | Regista e divulga-nos

beat2revolution.net

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Kline777

Na boa, mas sinceramente aquilo nao tem ciencia nenhuma... são shapes postas directamente no form a partir da palete.

A maior parte do código é uma especie de motor de jogo 2D que comecei para gerir os movimentos e colisoes das TShapes do FireMonkey...

Quando chegar a casa ponho isso aqui ;)

Editado por Kline777

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.