Java 2d movimentando um circulo

9 respostas
J

Ola dres, tudo bem?? Estou a fazer um programa q consiste basicamente tem uma tela com um circulo se movimentando dentro dela de maneira aleatória. Andei olhando a pagina da sun mas os exemplos não foram muito claros… o q devo fazer para gerar o movimento do circulo???

Ca esta a classe q é representada pelo circulo:

public class Pessoa extends JComponent{
     private int x = 75;	  
	 private int y = 50;
	 protected void paintComponent(Graphics g) {   
		  
	        // Não se pode mudar o estado do objeto g, então fazemos uma cópia dele.   
	        Graphics2D g2d = (Graphics2D) g.create();   
	  	        
	        g2d.setColor(Color.yellow);   
	        g2d.drawOval(this.x, this.y, 21, 21);
	        g2d.setColor(Color.red);
	  	   	g2d.fillOval(this.x+1, this.y, 20, 20);       
	        g2d.dispose();
	    }
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}   

	 
}

e ca esta o cenário onde ela habita.

public class Sala extends JFrame{

	private Container container;
	private JPanel janela;
	
	public Sala(){
		super("Simulação Aleatória - Cinema");
        geraJPanel(); 
		this.container = getContentPane();
		this.container.setLayout(null);
		this.container.add(this.janela);
		setSize(600,400);
		setLocation(100,125);
		setVisible(true);
		
		setDefaultCloseOperation(EXIT_ON_CLOSE);
	}
			
	public static void main(String[] args){
		Sala sala = new Sala();
		
	}
	
	public void geraJPanel(){
		this.janela = new JPanel();
        this.janela.setSize(500, 300);
        this.janela.setBackground(Color.lightGray);
        this.janela.setLayout(new BorderLayout());
        this.janela.add(new Pessoa());
        this.janela.setBorder(BorderFactory.createLineBorder(Color.black, 1));
	}

		
	public Container getContainer() {
		return container;
	}

	public void setContainer(Container container) {
		this.container = container;
	}

	public JPanel getJanela() {
		return janela;
	}

	public void setJanela(JPanel janela) {
		this.janela = janela;
	}
	
	
}

desde já agradeço.

9 Respostas

V

Para fazer movimento, você precisa de um loop. O loop desenhará periodicamente o círculo numa posição deslocada, e então dará a impressão para o usuário de que ele está se movendo.

O que você quer fazer exatamente? Uma boa referência é esse material aqui:
http://www.cokeandcode.com/node/6

P

ViniGodoy:
Para fazer movimento, você precisa de um loop. O loop desenhará periodicamente o círculo numa posição deslocada, e então dará a impressão para o usuário de que ele está se movendo.

O que você quer fazer exatamente? Uma boa referência é esse material aqui:
http://www.cokeandcode.com/node/6

Só uma coisa Vini: Quanto de memória isso come, meu caro?

D

O cara perguntou quanto de memória…
hahehahehaehahehae
o problema de “jogos” é a CPU…
loop, atualização, desenho = tempo de CPU,
respondendo melhor a dúvida do nosso amigo que
abriu o tópico.
para uma aplicação simples o uso de um Timer com um TimerTask já basta…
dentro do seu timertask atualize o x, y do seu objeto Pessoa (seu circulo)
e mande desenha o painel novamente.
na hora de colocar o timertask no Timer não esqueça de definir o delay como 0
e colocar um periodo (taxa de atualização) inferior a 500ms, para ficar bom o negócio

Abs,

C

Sergio Figueras:
ViniGodoy:
Para fazer movimento, você precisa de um loop. O loop desenhará periodicamente o círculo numa posição deslocada, e então dará a impressão para o usuário de que ele está se movendo.

O que você quer fazer exatamente? Uma boa referência é esse material aqui:
http://www.cokeandcode.com/node/6

Só uma coisa Vini: Quanto de memória isso come, meu caro?

Isso consome processador, não memória (como o amigo logo acima comentou).
O desenho pode ser representando, por exemplo, por uma matriz. A mesma está alocada na memória e pronto. Agora, se você vai fazer transformações nesta matriz afim de fazer com que o desenho mude, são cálculos e mais cálculos, mas a memória em si é a mesma.

P

Ô meu deus do céu, é lógico que come processador. Mas normalmente, mesmo por erro, tem muita gente que usa isso de forma genérica e memória pode significar sim o desmepenho geral, incluindo o processador.

V

Se você desenhar em tela cheia, 1024x768, usando 32 bits você consumirá 3.145.728 bytes só na imagem da tela. Usando double-buffering, esse número dobra, então são 6MB. Como as imagens que serão desenhadas ainda estarão em memória, pode se somar mais uns 2 ou 3 megabytes, o que totaliza uns 10mb para a resolução alta.

Não é muito para as placas de vídeo hoje em dia, mas pode ser uma preocupação para quem programa celulares (embora por lá a resolução não seja tão alta).

O resto da informação do jogo, dependendo de qual for, também pode ocupar muita memória. Por exemplo, um RTS pode ter em memória os grafos de navegação dos mapas. Se forem pré-processados, eles podem ser ainda maiores (é a velha troca, processamento versus memória).

Bem simples, diga-se de passagem. O problema é que o swing pode ignorar vários repaints simultâneos e, portanto, pode ficar difícil ter uma animação bem-feita usando TimerTask. O que se faz é passar a ignorar totalmente os repaints e usar o BufferStrategy do JFrame para fazer o desenho e a exibição manualmente. Após a janela ser exibida basta dar o comando:

No seu método de pintura, você pode fazer:

Graphics2D g2d = (Graphics2D) getBufferStrategy().getGraphics(); //Desenho getBufferStrategy().show(); //troca os buffers.

E daí você controla a animação através de outra thread. Outra preocupação é manter a taxa de frames por segundo constante. Tem um ótimo artigo falando só sobre isso no site do livro Killer Game Programming in Java.

P

Se você desenhar em tela cheia, 1024x768, usando 32 bits você consumirá 3.145.728 bytes só na imagem da tela. Usando double-buffering, esse número dobra, então são 6MB. Como as imagens que serão desenhadas ainda estarão em memória, pode se somar mais uns 2 ou 3 megabytes, o que totaliza uns 10mb para a resolução alta.

Não é muito para as placas de vídeo hoje em dia, mas pode ser uma preocupação para quem programa celulares (embora por lá a resolução não seja tão alta).

O resto da informação do jogo, dependendo de qual for, também pode ocupar muita memória. Por exemplo, um RTS pode ter em memória os grafos de navegação dos mapas. Se forem pré-processados, eles podem ser ainda maiores (é a velha troca, processamento versus memória).

Bem simples, diga-se de passagem. O problema é que o swing pode ignorar vários repaints simultâneos e, portanto, pode ficar difícil ter uma animação bem-feita usando TimerTask. O que se faz é passar a ignorar totalmente os repaints e usar o BufferStrategy do JFrame para fazer o desenho e a exibição manualmente. Após a janela ser exibida basta dar o comando:

No seu método de pintura, você pode fazer:

Graphics2D g2d = (Graphics2D) getBufferStrategy().getGraphics(); //Desenho getBufferStrategy().show(); //troca os buffers.

E daí você controla a animação através de outra thread. Outra preocupação é manter a taxa de frames por segundo constante. Tem um ótimo artigo falando só sobre isso no site do livro Killer Game Programming in Java.

Olá Vini,

Obrigado pela resposta. E um parabéns aos retardados que acham que mesmo um Drawzinho desses não ocupa memória.

Mas uma coisa, Vini, em relação a desempenho, voce gosta do Java2D?

V

Gosto sim, especialmente em Full Screen Exclusive Mode.

Você tem que usa-lo direito. Um passo é usar o BufferStrategy, outro é gerenciar bem as BufferedImages. É importante criar imagens compatíveis com a resolução já utilizada do monitor. Também tem que desligar os auto-repaints do Swing e, preferencialmente, trabalhar em Full Screen. Como fiz no Vikanoid.

Ele também é muito poderoso. Suporta conceitos avançados como transformações, rasters. Lê praticamente todo tipo de imagem, apesar de ser especialmente otimizado para o png. E trabalhar com Java é realmente uma mão na roda.

Agora, já adiantando um pouco, nunca trabalhei com a JAI. Para fazer animações já não saberia dizer se é ou não melhor que o Java 2D.

Em questão de memória, 10mb é pouco comparado com uma aplicação vetorial. Pegue um modelo de 30.000 vértices. Considere que cada vértice ocupa 64 bytes (informações de textura, luz e posição). Só aí você já tem 1.8MB de informação. Agora, pense que um cenário completo, desenhado, chega a ter mais de 500.000 vértices, que a aplicação também trabalhará com Double Buffering, e que também haverão objetos fora da placa de vídeo… Fácil, fácil você entende pq as GPUs de hoje não tem menos do que 256MB de RAM…

J

Pessoal … muito obrigado!! Usei o metodo com Timer e funcionou perfeitamente!! mas apareceu outro problema… não consigo inserir uma segunda bolinha… quando insiro a segunda Pessoa na Sala… a primeira desaparece… o q devo fazer??

Desde de já agradeço.

Criado 9 de julho de 2008
Ultima resposta 14 de jul. de 2008
Respostas 9
Participantes 5