• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Nazgulled

Como criar um ciclo for com "velocidades"?

25 mensagens neste tópico

Isto se calhar até é fácil, mas eu já andei a pensar e não consigo me lembrar de nada que fique num pedaço de código simples de usar sem muitas complicações.

O que eu pretendo é mover um objecto (exemplo: um botão de um form em C#) de um lado para o outro, da posição X à X+100, por exemplo. Eu poderia fazer isto com um ciclo for com i=0 até i<100 e incrementando o i com uma unidade em cada iteração do ciclo.

Agora, eu queria ter uma variável que definisse o tipo de velocidade, por exemplo de 1 a 10 onde 5 seria a velocidade "normal" ou seja, o ciclo for teria 100 iterações. Os outros valores tornavam a animação do botão de um lado para o outro mais lento ou mais rápido conforme o valor.

Que sugestões têm para fazer isto?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Se percebi bem, o que tu queres é ter um ciclo em que o valor do incremento varia, certo?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Se percebi bem, o que tu queres é ter um ciclo em que o valor do incremento varia, certo?

Não sei se é o que ele quer mas é o que eu faria.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Para o efeito visual do botão a andar dum lado para outro tens duas questões a considerar: o Espaço e o Tempo.

Supoe que querias que o botão andasse 100 pixeis à velocidade de 10 pixeis por segundo.

Ele pode fazer 10 "saltos" de 10 pixeis cada (o Espaço) com um intervalo de 1 segundo (o Tempo); ou

Ele pode fazer 100 "saltos" de 1 pixel cada (o Espaço) com um intervalo de 0.1 segundos (o Tempo); ou

Ele pode fazer 1 "salto" de 100 pixeis (o Espaço) com um intervalo de 10 segundos (o Tempo); ou

qualquer outra combinação que dê a mesma velocidade.

Para fazeres um movimento fluído, acho que o mais importante é o tempo: praí um "salto" de 0.0125 em 0.0125 segundos (80Hz) funcione (? -- experimenta).

Só precisas de calcular a distância a "saltar" em cada momento, com base na velocidade.

distancia = tempo * velocidade

Depois metes um timer que move o botão a distância calculada a cada intervalo até chegar ao destino.

E acabam-se os teus problemas da velocidade do ciclo for :cheesygrin:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Deve manter-se a ocupação do CPU baixa, daí que deve ajustar-se de modo a ter o maior tempo de interalo possível, saltando vários pixeis de cada vez. 10 a 25Hz deve chegar (porque é para uma página web) mas depois de umas experiências é que vês.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

@Rui Carlos

Sim

@pmg

Isso é mais complicado e dá mais trabalho.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Então é só controlar o incremento com uma variável (i+=step).

(não sei se estou a perceber bem qual é o teu problema  :))

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Mas isso só vai acelerar o movimento e eu quero ter a possibilidade também de o tornar mais lento.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Mas isso só vai acelerar o movimento e eu quero ter a possibilidade também de o tornar mais lento.

Usar um float em vez de um inteiro?

Ou então com uma função de sleep, não sei.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Já tentei com um float mas não resultou por uma razão muito simples. Ao usar o float eu fiz decrementos de 0.1 em vez de 1 e isso fez com que o ciclo tivesse muitas mais iterações. Mas como nós hoje em dia temos computadores extremamente rápidos isso é irrelevante. Mil iterações ou 100 mil foram executadas no mesmo espaço de tempo.

Acho que vou ter de brincar com o Timer do C# e fazer algo +- nos moldes que o pmg disse porque não estou a ver outra forma. Não queria ir por ai porque vai dar mais trabalho :/

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Podes usar o "delay". Eventualmente podes ter que criar uma thread para não bloqueares o teu ciclo principal da aplicação. Não faças atrasos activos, isso consome CPU pa caraças e empata outros programas. A função "delay" tipicamente é "bem feita" e não prende o CPU.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Prefiro a outra solução, tenho mais controlo sobre a animação e não fico "limitado" ao nº de iterações do ciclo.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Como diz o Njay, podes fazer pausas dentro do ciclo (delay() ou sleep() ou whatever()), mas usando este método, creio que ficas com a form "trancada", ou seja: não podes ter dois botões a andar ao mesmo tempo; não podes usar os menus do form ou clicar num botão enquanto o "botão andarilho" não chega ao destino.

O timer nem é tão complicado como parece :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Usar um timer é a melhor opção e é o que eu faria. Só referi a "outra" solução porque o Naz parecia inclinado para usar atrasos activos, e nesse caso seria melhor usar o delay numa thread.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O Java foi desenhado para ser usado amplamente em multithreading, o C# não sei, mas tendo em conta as semelhanças com o Java parece-me que também :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O Java foi desenhado para ser usado amplamente em multithreading, o C# não sei, mas tendo em conta as semelhanças com o Java parece-me que também :)

Nas versões .NET é muito simples trabalhar com multithreading.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Mas eu não quero ir por ai... Para o tipo de problema, não me parece a solução adequada. Não vou estar a criar uma thread só para fazer uma animação...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Mas eu não quero ir por ai... Para o tipo de problema, não me parece a solução adequada. Não vou estar a criar uma thread só para fazer uma animação...

Sim não tem lógica! A não ser que a animação este a aconteçer ao mesmo tempo de outras acções.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não vai estar...

Então usa o timer que é simples e funciona bem!

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Atenção que não é a mesma coisa!

Um timer age como uma thread e um ciclo não. Podem servir os dois mas depende da aplicação.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Muito antes de colocar este tópico aqui eu tinha feito um teste (para mostrar uma cena a um amigo) exactamente dessa forma, movendo um objecto dentro de um for e com um System.Threading.Threads.Sleep(X) lá dentro e isso causou que a animação parasse a meio e a aplicação estancou e tive que terminar o processo. E como disse, não quero estar a criar threads só para fazer uma animação, prefiro usar o Timer que simplifica muita coisa.

Obrigado a todos.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pessoal, acabei por usar antes o BackgroundWorker pois permitiu mais flexibilidade na forma como começar a animação e termina-la, até porque depois a animação é suposto ser feita no sentido inverso.

Não me está apetecer (tenho sono, é tarde e já devia estar a dormir que tenho aulas cedo) criar um tópico na secção de C# com os problemas que estou a ter e traduzir aquilo que já escrevi noutro fórum, mas se tiverem um tempinho e puderem dar uma vista de olhos aqui:

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/e8d77b85-2736-4135-9a77-05a87e677a6d

Eu agradecia, agradecia mais se soubessem onde está o problema :P Não precisam de ler o tópico todo, leiam a partir do meu post onde eu começo por "Hi again", é o post #17 (neste momento é o último) apesar de o fórum não ter nenhum campo que mostre o número deles.

0

Partilhar esta mensagem


Link 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