[RESOLVIDO]Problema com thread

5 respostas
dotabyss

Estava brincando de fazer um “joguinho” aqui e tive um problema que nao consigo entender.

Comecei com isso:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class GameNave extends JFrame implements Runnable, KeyListener{
	
	public static void main (String args[])
	{
		GameNave game = new GameNave();
		game.construirJanela();
	}
	
	public void construirJanela()
	{
		Container container = getContentPane();
		container.setBackground(Color.black);
		setTitle("Game: Nave");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setSize(800, 600);
		setLocationRelativeTo(null);
		setVisible(true);
		setResizable(false);
		addKeyListener(this);
		setFocusable(true);
		
		x = 400;
		y = 500;
	}
	
	private Thread animador;
	private int x, y, x2, y2;
	private Image nave;
	
	public void paint (Graphics g)
	{
		super.paint(g);
		nave = new ImageIcon("nave.png").getImage();
		Graphics2D g2d = (Graphics2D)g;
		g2d.drawImage(nave, x, y, this);
	}

	public void addNotify()
	{
		super.addNotify();
		animador = new Thread(this);
		animador.start();		
	}
	
	public void keyPressed(KeyEvent e) {

        int key = e.getKeyCode();

        if (key == KeyEvent.VK_LEFT) {
            x2 = -5;
        }

        if (key == KeyEvent.VK_RIGHT) {
            x2 = 5;
        }

        if (key == KeyEvent.VK_UP) {
            y2 = -5;
        }

        if (key == KeyEvent.VK_DOWN) {
            y2 = 5;
        }
    }

    public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();

        if (key == KeyEvent.VK_LEFT) {
            x2 = 0;
        }

        if (key == KeyEvent.VK_RIGHT) {
            x2 = 0;
        }

        if (key == KeyEvent.VK_UP) {
            y2 = 0;
        }

        if (key == KeyEvent.VK_DOWN) {
            y2 = 0;
        }
    }
    
    public void keyTyped (KeyEvent e)
    {
    	
    }
    
    public void movimento()
    {
    	x += x2;
    	y += y2;
    }
	public void run()
	{
		while (true)
			{
			movimento();
			repaint();
			
			try
			{
				Thread.sleep(25);
			}
			catch (InterruptedException e)
			{
			}
			
			}
	}
}

Até aqui tudo bem. Depois disso quis adicionar a possibilidade de atirar com a nave, entao fiz isso:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

public class GameNave2 extends JFrame implements Runnable, KeyListener{
	
	public static void main (String args[])
	{
		GameNave2 game = new GameNave2();
		game.construirJanela();
	}
	
	public void construirJanela()
	{
		Container container = getContentPane();
		container.setBackground(Color.black);
		setTitle("Game: Nave");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setSize(800, 600);
		setLocationRelativeTo(null);
		setVisible(true);
		setResizable(false);
		addKeyListener(this);
		setFocusable(true);
		
		x = 400;
		y = 500;
	}
	
	private Thread animador;
	private int x, y, x2, y2;
	private Image nave;
	private ArrayList tiros;
	
	public void paint (Graphics g)
	{
		super.paint(g);
		
		nave = new ImageIcon("nave.png").getImage();
		tiros = new ArrayList();
		
		Graphics2D g2d = (Graphics2D)g;
		g2d.drawImage(nave, x, y, this);
		
		ArrayList ms = tiros;
		for (int i = 0; i < ms.size(); i++)
		{
			Tiro t = (Tiro) ms.get(i);
			g2d.drawImage(t.tiro, t.x, t.y, this);
		}
	}

	public void atirar()
	{
		tiros.add(new Tiro(x + 32, y + 16));
	}
	
	public void addNotify()
	{
		super.addNotify();
		animador = new Thread(this);
		animador.start();		
	}
	
	public void keyPressed(KeyEvent e) {

        int key = e.getKeyCode();

        if (key == KeyEvent.VK_SPACE){
        	atirar();
        }
        
        if (key == KeyEvent.VK_LEFT) {
            x2 = -5;
        }

        if (key == KeyEvent.VK_RIGHT) {
            x2 = 5;
        }

        if (key == KeyEvent.VK_UP) {
            y2 = -5;
        }

        if (key == KeyEvent.VK_DOWN) {
            y2 = 5;
        }
    }

    public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();

        if (key == KeyEvent.VK_LEFT) {
            x2 = 0;
        }

        if (key == KeyEvent.VK_RIGHT) {
            x2 = 0;
        }

        if (key == KeyEvent.VK_UP) {
            y2 = 0;
        }

        if (key == KeyEvent.VK_DOWN) {
            y2 = 0;
        }
    }
    
    public void keyTyped (KeyEvent e)
    {
    	
    }
    
    public void movimento()
    {
    	x += x2;
    	y += y2;
    }
	public void run()
	{
		while (true)
			{
			ArrayList ts = tiros;
			for (int i = 0; i < ts.size(); i++)
			{
				Tiro m = (Tiro) ts.get(i);
				if (m.visivel = true)
				{
					m.movimentoTiro();
				}
				else
				{
					ts.remove(i);
				}
			}
			
			movimento();
			repaint();
			
			try
			{
				Thread.sleep(25);
			}
			catch (InterruptedException e)
			{
			}
			
			}
	}
}
import java.awt.Image;
import javax.swing.ImageIcon;

public class Tiro {
	
	int x, y;
	Image tiro;
	boolean visivel;
	
	private final int ALTURA_JANELA = 600;
	private final int VELOCIDADE_TIRO = 2;
	
	public Tiro(int x, int y)
	{
		tiro = new ImageIcon("tiro.png").getImage();
		visivel = true;
		this.x = x;
		this.y = y;
	}
	
	public void movimentoTiro()
	{
		x += VELOCIDADE_TIRO;
		if (x < ALTURA_JANELA)
		{
			visivel = false;
		}
	}
}

Como resultado eu tenho uma janela com a nave desenhada mas sem a capacidade de se movimentar nem nada.

O Eclipse me manda este erro:
“Exception in thread “Thread-3” java.lang.NullPointerException
at tutorial.pack.GameNave2.run(GameNave2.java:128)
at java.lang.Thread.run(Unknown Source)

Não sei como resolver e vim pedir ajuda de alguem que entenda melhor de thread, etc.
Obrigado desde já.

5 Respostas

ViniGodoy

Normalmente os jogos tem uma thread só, chamada loop de animação. Apesar de ter vários objetos na tela, todos são atualizados durante a fase de update() do jogo, ou seja, vc percorre uma lista desses objetos chamando seus respectivos métodos de atualização de lógica.

Sempre que postar um erro, também faça o favor de indicar em que linha do seu código o seu erro está. Nullpointer exception geralmente quer dizer que você tentou chamar um método de um objeto, mas a sua variável continha valor nulo.

dotabyss

Problema resolvido. ;D

pedroroxd

Qual era o problema?
Como resolveu?

Assim ajuda os outros que tiverem a msma dúvida…

E se foi resolvido, clique editar no primeiro post e acrescente depois do título [RESOLVIDO]

dotabyss

Quem quiser saber a solução do(s) problema(s), pode conferir o que foi discutido aqui:

http://www.java-forums.org/threads-synchronization/25652-problem-thread.html

M

dotabyss:
Quem quiser saber a solução do(s) problema(s), pode conferir o que foi discutido aqui:

http://www.java-forums.org/threads-synchronization/25652-problem-thread.html


Quanto ao que o cara que te ajudou disse nesse tópico eu discordo dos dois primeiros itens. Isso porque o mais correto para um jogo fazer a pintura usando direct rendering (porém note que se você não for usar direct rendering, aí sim siga o que ele disse - sobreescreva paintComponent de um JComponent e depois adicione esse componente ao JFrame).

Porém os dois últimos pontos estão certos: não leia arquivos nem execute lógica dentro do método de pintura. Cada método exerce uma função específica. Leia a imagem em um método de inicialização e faça atualizações da lógica em um método específico para isso.

Criado 14 de fevereiro de 2010
Ultima resposta 16 de fev. de 2010
Respostas 5
Participantes 4