Dlaczego obiekt nie zawsze jest wyświetlany?

0

Witam, chciałem napisać sobie prostą gierkę w Java ale już na początku pojawiły się schody a mianowicie obiekt reprezentujący gracza nie zawsze jest wyświetlany na tle, a ja nie wiem co jest tego przyczyną. Dlaczego tak się dzieje że raz jest a raz go nie ma, jak to naprawić?

Kwadrat reprezentujący gracza

 public class Player extends JComponent{
	
	
	
	public int px=0;
	public int py=600;
	

	public void paintComponent(Graphics g){
	    Graphics2D g2 = (Graphics2D) g;	
	    g2.setColor(Color.GREEN);
	    g2.fillRect(px, py, 50, 70);
	
	}
		}

klasa tła w której dzieje się właściwie wszstko

 public class ArenaA extends JComponent implements Runnable{
	Random los = new Random();
	
	
	
	int arenasize=los.nextInt(3000);
	public Image image;		   
	
	Player player = new Player();

	
	public ArenaA(Image image) {
	        this.image = image;
	 }
	
	@Override
    protected void paintComponent(Graphics g) {
		
		super.paintComponent(g);
    	Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(image, 0, 0, getWidth(), getHeight(), this);
     
  
        setFocusable(true);
        requestFocusInWindow();
     
  
	}
	
	@Override
	public void run() {
		
		this.add(player);
		player.setVisible(true);
		
		this.addKeyListener(new KeyListener(){
			
			@Override
			public void keyPressed(KeyEvent e) {
				// TODO Auto-generated method stub
				if(e.getKeyCode()==KeyEvent.VK_D){
					player.px++;
					camx--;
					repaint();
				}
				if(e.getKeyCode()==KeyEvent.VK_A){
					player.px--;
					repaint();
				}
				if(e.getKeyCode()==KeyEvent.VK_W){
					player.py--;
					repaint();
				}
			}

			@Override
			public void keyReleased(KeyEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void keyTyped(KeyEvent e) {
				// TODO Auto-generated method stub
				
			}
		});
	}
	
	

	public int getArenaSize(){
	return arenasize;
}

Klasa z JFrame itd.

 public class ArenaTest {
	
	static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
	static int width = (int) screenSize.getWidth();
	static int height = (int) screenSize.getHeight();
	
	
	static JFrame arenaframe = new JFrame("ARENA");
	
	
	
	
	public void ShowArenaFrame() throws IOException, InterruptedException{
		
	File f = new File("C:/Users/X/Downloads/arena.jpg"); 
	BufferedImage myImage = ImageIO.read(f);
	ArenaA ar = new ArenaA(myImage);
	Thread tar = new Thread(ar);

	tar.start();

	arenaframe.setContentPane(ar);
	arenaframe.setLayout(new BorderLayout());
	arenaframe.setUndecorated(true);
	arenaframe.setBounds(0,0,ar.getArenaSize()+width,height);
	arenaframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	arenaframe.setVisible(true);
}}
2

NIe wiadomo na kiego grzyba Ci ten wątek potrzebny -natomiast na pewno przeszkadza.
Wywal to Thread(ar)

odpal run() ręcznie - w tym samy watku co JFrame (czyli w głownym).

0
jarekr000000 napisał(a):

NIe wiadomo na kiego grzyba Ci ten wątek potrzebny -natomiast na pewno przeszkadza.
Wywal to Thread(ar)

odpal run() ręcznie - w tym samy watku co JFrame (czyli w głownym).

Po zmianie nie wyświetla się wcale. 0 na 30 prób. W tym układzie co jest 10 na 30, skończyło się wyświetleniem obiektu.

1

Na pewno nie masz tam jakieś pozostałości wątku? Na pewno wywołujesz ten kod co jest w run() ?

1

Problem u Ciebie jest następujący:

  • nie potrzebnie tworzysz wątek dodatkowy o czym pisał @jarekr000000
  • wszystkie metody rysujące powinny być wywołane w metodzie paintComponent

zmień klasę ArenaA na następującą

 import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

public class ArenaA extends JComponent {
    Random los = new Random();

    int arenasize = los.nextInt(3000);
    public Image image;

    Player player = new Player();

    public ArenaA(Image image) {
        this.image = image;
    }

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(image, 0, 0, getWidth(), getHeight(), this);

        setFocusable(true);
        requestFocusInWindow();

        run(); // <- tu wywołujesz metodę run po wcześniejszym wywaleniu wątka
    }


    public void run() {

        this.add(player);
        player.setVisible(true);

        this.addKeyListener(new KeyListener() {

            @Override
            public void keyPressed(KeyEvent e) {
                // TODO Auto-generated method stub
                if (e.getKeyCode() == KeyEvent.VK_D) {
                    player.px++;
                    //camx--;
                    repaint();
                }
                if (e.getKeyCode() == KeyEvent.VK_A) {
                    player.px--;
                    repaint();
                }
                if (e.getKeyCode() == KeyEvent.VK_W) {
                    player.py--;
                    repaint();
                }
            }

            @Override
            public void keyReleased(KeyEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void keyTyped(KeyEvent e) {
                // TODO Auto-generated method stub

            }
        });
    }

    public int getArenaSize() {
        return arenasize;
    }


}

nie wiem u mnie za każdym razem się gracz pojawia jak co pisz.

jeszcze kilka (moich) wskazówek

  • stosuj się do Konwencje w Java, bo masz np. metode ShowArenaFrame
  • w miejscu gdzie masz obsługę klawiatury ja był dodał klasę dziedziczącą po KeyAdapter w niej wywołał tylko te metody, które Cię interesują i w addKeyListener dodał jako parametr wcześniej stworzoną klasę. Poprawiło by to czytelność kodu.
 this.addKeyListener(new Keyboard());

Jeżeli chcesz pisać koniecznie gry w swing-u to polecam Tutorial ale osobiście polecam już JavaFX do prostych gier.

Pozdrawiam

0

Dzięki za pomoc i za link do tutorialu tam znalazłem rozwiązanie swojego problemu, nie trzeba wcale dodawać obiektu

 this.add(player);

tak jak to robiłem, wystarczy wywołać samą metodę rysującą tej klasy.

 player.paintComponent(g2d);

Faktycznie wątek okazał się tu zbędny, jeszcze raz dziękuję wszystkim za pomoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1