Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Rodrigomdo

Mostar imagem aleatória sem se repetir - Delphi XE5

Recommended Posts

Bom, tenho um projeto, e preciso que ao clicar na tela (Num panel), apareça uma imagem aleatória entre 5 imagens (Ou mais, o número de imagens pode variar), sem se repetir, e ao ir clicando na tela, vá aparecendo imagem por imagem, sem se repetir, até acabar, usei vários TImage e para elas aparecerem, só altero a propriedade Visible para True.

Estou usando o seguinte código:

 

procedure TForm2.Panel1Click(Sender: TObject);
const
  N = 5;
var
  I, T, P: Integer;
  Num: array[0..N - 1] of Integer;
begin
  ListView1.Items.Clear;
  for I := 0 to N - 1 do
    Num[I] := I;
  for I := N - 1 downto 0 do
  begin
    P := Random(I + 1);
    T := Num[I];
    Num[I] := Num[P];
    Num[P] := T;
  end;
  case T of
    1 : Image1.Visible := True;
    2 : Image2.Visible := True;
    3 : Image3.Visible := True;
    4 : Image4.Visible := True;
    5 : Image5.Visible := True;
  end;
end;

 


Até deu certo com esse, mas ele só funciona uma vez e preciso que a cada clique, apareça uma imagem.

Desde já agradeço, valeu gente!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom, vamos em partes.... primeiro, acho um problema você usar tantos componentes image, já que você pode ter N imagens, ficará meio inviável ficar pondo 1 Image para cada uma com o passar do tempo (sem contar que será difícil você controlar isso depois)... segundo, seu for para randomizar as imagens não faz sentido, pois você executa ele 5 vezes para pegar só o último random executado no laço. Não precisa usar ele num for, visto que o random por sí só tem a função de gerar um randômico entre 0 e o range informado (no caso, só teria que controlar para o caso dele gerar zero mudar para 1 por exemplo e comparar ele a um array de valores já consumidos - aqui eu criaria uma função que me retornaria se o range já foi utilizado ou não).

 

Uma coisa que não está clara no seu código também.... qual é a função do array Num? E o que acontece quando você consumir todo o range de imagens disponíveis para exibir? Vai travar na última exibida? Reiniciar? Qual é a idéia por trás disso, gerar um visualizador de imagens? Dê mais detalhes...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom, vamos em partes.... primeiro, acho um problema você usar tantos componentes image, já que você pode ter N imagens, ficará meio inviável ficar pondo 1 Image para cada uma com o passar do tempo (sem contar que será difícil você controlar isso depois)... segundo, seu for para randomizar as imagens não faz sentido, pois você executa ele 5 vezes para pegar só o último random executado no laço. Não precisa usar ele num for, visto que o random por sí só tem a função de gerar um randômico entre 0 e o range informado (no caso, só teria que controlar para o caso dele gerar zero mudar para 1 por exemplo e comparar ele a um array de valores já consumidos - aqui eu criaria uma função que me retornaria se o range já foi utilizado ou não).

 

Uma coisa que não está clara no seu código também.... qual é a função do array Num? E o que acontece quando você consumir todo o range de imagens disponíveis para exibir? Vai travar na última exibida? Reiniciar? Qual é a idéia por trás disso, gerar um visualizador de imagens? Dê mais detalhes...

 

O código que estou usando, encontrei na internet, não consegui resolver só.

 

Ele vai travar na última exibida.

É um projeto de um jogo, baseado num jogo de baralho, ai clicar na tela, aparece uma carta aleatória entre várias.

 

Valeuu!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Entendi... bom, eu faria algo bem diferente do que está tentando fazer... vamos por partes...

 

Primeiramente, eu criaria um tipo de dado para gerar um array dinâmico com as imagens, algo como o mostrado abaixo:

 

 

type ListaImagens = Record
     NomeArquivo : string;
     Visualizado : boolean;
end;

 

Depois, declararia na lista de variáveis privadas do form as seguintes variáveis:

 

 

    imagens: array of ListaImagens;
    bGerouListaArquivos : boolean;

 

E nas constantes criaria as seguintes:

 

 

const
   diretorioImagens : String = 'c:\TEMP\Imagens\'; //Aqui eu colocaria o diretório onde as imagens estão salvas, para facilitar manutenções futuras.
   ExtensaoArquivo  : String = '.jpg';

 

No create do form, eu setaria a variável bGerouListaArquivos para False. No exemplo que eu montei, usarei ela dentro do evento onclick do panel da forma que segue:

 

 

procedure TForm1.Panel1Click(Sender: TObject);
var Indice : integer;

    //Insere o nome dos arquivos em um array dinâmico
    procedure InsereImagensArray;
    var iIndice     : Integer;
        SR          : TSearchRec;
        NomeArquivo : String;
    begin
       //Inicializa o array
       imagens := nil;

       //Valida se existe o diretório
       if DirectoryExists(diretorioImagens) then
       begin
          FillChar(SR, SizeOf(TSearchRec), 0);
          iIndice := -1;
          //Abre a pesquisa para capturar a lista de imagens com a extensão desejada
          if FindFirst(diretorioImagens + '*' + ExtensaoArquivo, faAnyFile, SR) = 0 then
          try
             repeat
                NomeArquivo := ChangeFileExt(SR.Name, '');  //Pega somente o nome do arquivo, sem a extensão
                //Insere o registro no array dinâmico
                SetLength(imagens, Length(imagens) + 1);
                inc(iIndice);
                imagens[iIndice].NomeArquivo := NomeArquivo;
                imagens[iIndice].Visualizado := False;
             until FindNext(SR) <> 0;
          finally
             FindClose(SR);
          end; // if findfirst
       end;
    end;

    //Captura uma imagem randômicamente dentro do array dinâmico
    Function RetornaIndiceImagem : Integer;
    var Indice,
        TotalImagens,
        Tentativas : Integer;
    begin
        Indice       := -1;
        TotalImagens := Length(imagens);
        Tentativas   := 0;
        //Varre array dinâmico em busca de uma imagem ainda não utilizada
        while (Indice = -1) and (Tentativas < TotalImagens) do
        begin
           inc(Tentativas);
           Indice := Random(TotalImagens);
           //Testa se a imagem já foi exibida
           try
             if imagens[Indice].Visualizado then
                Indice := -1;
             except
                Indice := -1;
             end;
        end;
        Result := Indice;
    end;
//Início do Onclick do Panel
begin
   if not bGerouListaArquivos then
   begin
      InsereImagensArray;
      bGerouListaArquivos := True;
   end;

   Indice := RetornaIndiceImagem;

   if Indice <> -1 then
   begin
      Image1.Picture.LoadFromFile(diretorioImagens + imagens[Indice].NomeArquivo + ExtensaoArquivo);
      Image1.AutoSize := true;
      imagens[Indice].Visualizado := True;
   end;

end;

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.