Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Olá.
Já procurei bastante, mas ainda não achei um código que possa me adiantar ou dar ideia de como fazer um relógio digital numa contagem regressiva.
Encontrei uns arquivos GIF que possam ajudar a explicar o desafio:
/applications/core/interface/imageproxy/imageproxy.php?img=https://media.giphy.com/media/Fky8gl3Vzlc0E/giphy.gif&key=e875ee649e4c7ae53c9b77354b82983e204f4fb41b47806b603f9d0654c70a0d" />
Eu já tenho o código que faz a contagem regressiva a partir de uma data dada pelo usuário.
O que eu teria que fazer agora é associar cada dígito da contagem a uma imagem separada.
Tentei ajustar imagens GIFs que se adaptassem ao tempo real, mas sempre ocorre um pequeno erro nas frações de segundo que se acumulam e levam a dar uma grande diferença num intervalo de tempo maior.
Portanto, pretendo criar uma forma de associar cada dígito de cada resultado a uma imagem diferente e fazer a ilusão do movimento de passagem da placa do exemplo acima.
Quando o meu resultado dá 300 minutos, eu teria que "quebrar" o 300 em "3", "0" e "0".
Depois, eu teria que associar o "3" a uma imagem que exiba o número 3. E assim por diante.
A animação eu mesmo faria. Já separei as imagens de cada um dos dígitos do exemplo acima em arquivos diferentes.
Encontrei uma pequena dificuldade porque a passagem de contagem regressiva é DIFERENTE da passagem de tempo crescente.
A passagem da imagem 2 para a imagem 1 é diferente do seu inverso.
A imagem 3 para a 2 também é e assim por diante.
Por isso, não pude aproveitar as imagens separadas do exemplo dado acima.
Tive que criar transições do 2 para o 1 no Photoshop.
Mas esse não é o problema. Isso eu já tenho.
O problema, e é esse o motivo desse tópico, é associar cada número da contagem em imagens diferentes.
Para fazer a animação das transições, vou usar um componente TTimer.
Portanto, o que apresento aos colegas é o desafio de fazer a associação entre número e arquivo de imagem.
No exemplo que eu dei, vou ter que pegar a centena 3 e associar à imagem "3".
Mas como saber que é uma centena?
Eu pensei em testar se o resultado atual é maior do que 100.
Código:
If resultado > 100 then begin
If resultado - 100 = 1 then image1.Picture.LoadFromFile('arquivo1');
If resultado - 100 = 2 then image1.Picture.LoadFromFile('arquivo2');
...
If resultado - 100 = 9 then image1.Picture.LoadFromFile('arquivo9');
...Mas aí eu começo a me embaralhar.
E como fazer com as dezenas dentro das centenas?
Tem que fazer um tratamento meio matemático para testar unidade, dezena, centena, milhar, etc...
Alguém poderia dar uma mãozinha aqui?
Eu trago aqui a forma como já está funcionando o programinha:
/applications/core/interface/imageproxy/imageproxy.php?img=https://s20.postimg.org/r2l161o0d/Cont_Reg.png&key=13ccfa7c905e7fafb5592e5d2ab36cfd2eda8d0c5cf5ef3099ef6289d5df19fc" />
Esses números todos teriam que passar para placas que rolam no estilo da imagem GIF lá no começo do tópico.
Os segundos mudam a cada instante, claro, e isso é bem visível.
As placas teriam que rolar em números decrescentes.
A parte gráfica, eu acho que já sei como fazer, animação e tudo.
O tamanho do formulário teria que ser aumentado, claro.
O nó agora é o código para ligar cada número a um arquivo de imagem diferente.
Não entendo muito da coisa, mas seria o caso de usar um ImageList?
A bola está com vocês agora.
.
Ôpa!
Obrigado, Almir, por uma resposta assim tão rápida!
Mas eu não quero um contador digital.
Eu já tenho um contador numérico mesmo e ele me basta para informar os tempos.
O que eu gostaria era aperfeiçoar o layout e colocar aquele contador com placas que viram como num placar.
Para isso, eu teria que trabalhar com imagens e não com componentes.
O ideal também seria que fosse em Delphi: eu não tenho esse IDE Typhon.
Rapaz, andei dando uma rápida olhada no seu blog e vi que só tem coisa interessante por lá.
Parabéns!
Edite o link de seu comentário onde tem "Veja o resultado aqui" porque está faltando um ":" e o navegador dá erro 404.
O código de contagem é simples.O problema da imagem com transiçõ é que deve criar uma função para desenhar essas transições usando Tcanvas.Isso é mais questão de design do que programação em Si.
Poderia por dentro do laço For (u) um conjunto de carregamento de imagem do arquivo com várias transições.Mais isso fica complexo e pesado.
Acho que não precisa de TCanvas, não.
Eu pensei apenas em carregar a imagem de cada unidade para cada número com o componente Image mesmo.
Só isso.
O problema é conseguir associar cada número com suas unidades, dezenas, centenas, etc com arquivos de imagens diferentes.
Releia meu primeiro post.
Se o número de segundos num dado momento for 1.397, eu terei que ler esse número e colocar as imagens na ordem, para cada arquivo:
Imagem 1 na casa 5
Imagem (ponto) na casa 4
Imagem 3 na casa 3
Imagem 9 na casa 2
Imagem 7 na casa 1
De modo a ter:
1.397
E lembrando que o número 7 logo iria virar para o 6, com a animação do TTimer e as imagens intermediárias da virada da placa.
>
3 minutos atrás, Gabarito disse:
Acho que não precisa de TCanvas, não.
Eu pensei apenas em carregar a imagem de cada unidade para cada número com o componente Image mesmo.
Só isso.
O problema é conseguir associar cada número com suas unidades, dezenas, centenas, etc com arquivos de imagens diferentes.
Releia meu primeiro post.
Se o número de segundos num dado momento for 1.397, eu terei que ler esse número e colocar as imagens na ordem, para cada arquivo:
Imagem 1 na casa 5
Imagem (ponto) na casa 4
Imagem 3 na casa 3
Imagem 9 na casa 2
Imagem 7 na casa 1
>
3 minutos atrás, Gabarito disse:
Carregar imagem não é problema e é até fácil.O problema é a transição.Se for usar imagem de números estáticos isso fica fácil até demais.Basta dar nome aos arquivos de imagem com numeros:
"1.bmp" e carregar dentro do laço for(u) (como no exemplo acima)
imagem.picture.loadfromfile(inttostr( u) + '.bmp' ) ;
Depois basta seguir o modelo do meu codigo acima com o carregamento das 3 imagens no lugar do (a.value ,b.value , c.value)Dei uma olhada no código agora.
Quem é a, b e c? Algum componente?
Como você começa o contador para atribuir valores a "cen", "d" e "u"?
Vamos supor que você tenha que iniciar a contagem em 1397.
Almir, amigão, acabei de experimentar seu código.
E ele funciona muito bem!
Ao invés de usar o seu componentes a, b e c, eu usei simples TLabel.
Deu certo.
Eu não imaginei que fosse tão simples!
Vou ver agora como tratar as imagens.
Mais uma pergunta:
Como vou começar a contagem?
Você deu valor 9 às variáveis.
No meu caso, eu vou ter um número grandão, como na imagem do meu primeiro post.
Como quebrar o número a partir de uma variável que está mudando a cada segundo?
Lá no exemplo, o número de segundos é 41.756.271.
Isso está numa variável.
Vou ter que quebrar essa variável em unidades para atribuir a u, d, cen, mil, etc.
Como?
Fiz exemplo com 3 casas decimais carregando do arquivo.Você poderá acrescentar a casa do milhar
Roda perfeito:
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, TplRadioButtonUnit, TplCheckBoxUnit,
TplSpinEditUnit, TplLCDLineUnit, TplLed7SegUnit, ECGroupCtrls, LedNumber,
Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
a: TplLed7Seg;
b: TplLed7Seg;
Button1: TButton;
c: TplLed7Seg;
Edit1: TEdit;
Image1: TImage;
Image2: TImage;
Image3: TImage;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
var cen,d,u:integer;
Lc,Ld,Lu:integer;//valores limitadores do inicio da contagem
begin
Lc:=strtoint( copy(edit1.text,1,1) );//centenas
Ld:=strtoint( copy(edit1.text,2,1) );//dezenas
Lu:=strtoint( copy(edit1.text,3,1) ); //unidades
for cen:=(Lc) downto 0 do
begin
for d:=(Ld) downto 0 do
begin
for u:=(Lu) downto 0 do
begin
sleep(500);
application.ProcessMessages;
image1.Picture.LoadFromFile('c:\num\'+inttostr(cen)+'.bmp');
image2.Picture.LoadFromFile('c:\num\'+inttostr(d)+'.bmp');
image3.Picture.LoadFromFile('c:\num\'+inttostr(u)+'.bmp');
end;
end;
end;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
doublebuffered:=true;
end;
end.
Rapaz!
Você matou a charada em poucos minutos desse nosso bate-papo!
Que maravilha!
Siga o modelo acima.Lembre-se que para cada casa decimal do numero ( 41.756.271 )será necessário um laço FOR encadeado.Nesse seu numero será necessario 8 FOR encadeado.
Almir, meu amigo, você é o mago dos códigos!
Mas eu teria mais umas perguntinhas antes de liberar o caríssimo colega.
Você botou uma diretiva que meu compilador não aceitou:
"Invalid compiler directive"
O que significa
{$mode objfpc}{$H+}
?
Só rodou depois que eu tirei a diretiva.
Outra coisa: eu vou pegar uma variável que está mudando o tempo todo, a do tempo restante até uma determinada data.
Como jogar essa variável no seu código?
Veja o exemplo que eu dei lá em cima:
/applications/core/interface/imageproxy/imageproxy.php?img=https://s20.postimg.org/r2l161o0d/Cont_Reg.png&key=13ccfa7c905e7fafb5592e5d2ab36cfd2eda8d0c5cf5ef3099ef6289d5df19fc" />
Veja que tem uma data fixa.
Eu tenho que jogar as variáveis de segundos, minutos, etc, que estão mudando, haja visto que o tempo muda e a data é fixa, dentro do seu código.
Como?
Esqueci de dizer, mas só para reforçar: aquele 41.756.271 já não é mais aquele.
Os segundos já mudaram enquanto a gente conversava.
Ou seja, essa variável está em constante atualização.
Na hora que eu rodar o programa, ele tem que pegar a variável e identificar seus números para preencher os valores do seu código.
>
5 minutos atrás, Gabarito disse:
Almir, meu amigo, você é o mago dos códigos!
Mas eu teria mais umas perguntinhas antes de liberar o caríssimo colega.
Você botou uma diretiva que meu compilador não aceitou:
"Invalid compiler directive"
O que significa
{$mode objfpc}{$H+}
?
Só rodou depois que eu tirei a diretiva.
A diretiva é do compilador free Pascal no modo Object PASCAL FPC (não estou usando modo Delphi)
Você vai pegar o label onde se mostra os tempo dos segundos da mesma forma que o codigo exemplo pega os valor do Edit1 (use a função copy)
Mas pensando melhor, acho que isso é fácil.
Basta eu usar o copy(variável, 1, 1) etc e resolver.
Podemos dar o tópico como RESOLVIDO.
Acho até que é um recorde, uma questão resolvida em menos de uma hora de postada.
Valeu, amigão!
sua label tem esse valor 41.756.271
Casa_dos_dezmilhoes : =copy(label.caption , 1, 1); //pegou o primeiro caractere "4"
Casa_dos_unidmilhoes : =copy(label.caption , 2, 1); //pegou o segundo caractere "1"
(o importante é considerar a casa decimal e ignorar o valor em si)
você não deve se preocupar com sua aplicação.Deve entender como fiz o codigo de exemplo.Deve criar as variaveis para cada casa decimal.
sua label tem esse valor 41.756.271
Casa_dos_dezmilhoes : =copy(label.caption , 1, 1); //pegou o primeiro caractere "4"
Casa_dos_unidmilhoes : =copy(label.caption , 2, 1); //pegou o segundo caractere "1"
(o importante é considerar a casa decimal e ignorar o valor em si)
você não deve se preocupar com sua aplicação.Deve entender como fiz o codigo de exemplo.Deve criar as variaveis para cada casa decimal.
Almir, meu sincero agradecimento pela sua prestimosa atenção.
Você desmistificou um problema que eu imaginei ser muito mais complicado.
Assunto plenamente resolvido.
Dou meus parabéns pela sua rápida visualização da solução e a maneira paciente e atenciosa com que explicou as perguntas.
Abração.
Se fosse você eu faria usando a IDE do CodeTyphon .Veja um exemplo que fiz especialmente para você.Tem componentes legais.
fiz um contador simples (500 ms).Cada display recebeu um nome (a,b,c)
begin for cen:=0 to 9 do begin for d:=0 to 9 do begin for u:=0 to 9 do begin begin for cen:=9 downto 0 do begin for d:=9 downto 0 do begin for u:=9 downto 0 do begin