Przesuwanie prostokąta

0

Witam cieplutko.
Na początek troche kodu.
Main.java

    
//
public void update(Graphics g){
        paint(g);
    }
    public void paint(Graphics g){
    	g.drawRect(p.getX(), p.getY(), 10, 100);
System.out.println(p.getX()+" "+p.getY());
    }

Player.java

//..
    public int getX(){
    	return x;
    }
    public int getY(){
    	return y;
    }
@Override
	public void keyPressed(KeyEvent e) {
		  int key = e.getKeyCode();
	        if (key == KeyEvent.VK_SPACE) {
	        	System.out.print(y);
	        	y -= 100;
	        	x -= 100;
	        }
}

Po naciśnięciu spacji zmieniam wartości y oraz x, następnie zwracam je za pomocą funkcji. Klasa Main powinna przerysować prostokąt, jednak tego nie robi, mimo, że System.out.println(p.getX()+" "+p.getY()); zwraca odpowiedni wartości.
Jakieś sugestie? :)

0

Metoda paint(), albo wychodzi poza panel (canvas), albo rysuje na panelu (canvasie), który w ogóle nie jest wyświetlany.

0
class Main extends Canvas{
Place p;
    public Main(){
        setBackground(Color.white);
        p = new Player();
        addKeyListener(new Place());
    }

    public static void main(String[] args){
      	Main m = new Main();
        JFrame okno = new JFrame();
        okno.setSize(400, 200);
        okno.add(m);
        okno.setVisible(true);
        okno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public void update(Graphics g){
        paint(g);
    }
    public void paint(Graphics g){
    	g.drawRect(p.getX(), p.getY(), 10, 100);
    	
    }
}

Nie widzę nic błędnego

0

U mnie działa, na pewno masz w keyPressed() wywołanie repaint() dla canvasu? W kodzie, który poprzednio zamieściłeś nie było repaint().

0

Fakt, nie miałem wcześniej wywołane repaint(), zrobiłem to i nie pomaga.

	        if (key == KeyEvent.VK_SPACE) {
	        	System.out.print(y);
	        	y -= 100;
	        	x -= 100;
	        	new Main().repaint();
	        }
0

Omg, przecież tworzysz nowy obiekt klasy Main i na nim malujesz. On istnieje tylko w pamięci komputera.
Przekaż do Playera referencję do klasy Main

p = new Player(this);

zapamiętaj ją w polu klasy Player (np. pod nazwą m) i wywołaj

m.repaint();
0

Zrobiłem tak jeszcze przed twoją aktualizacją, jednak nadal nie umiem poradzić sobie z tym, nie wiem.

//Main.java
p = new Player(this);

//Player.java
Main main;
    public static void main(String[] args){
    }
    public Player(Main m){
    	x = 0;
    	y = 0;
    	width = 10;
    	height = 50;
    	main = m;
    }
//..
@Override
	public void keyPressed(KeyEvent e) {
		  int key = e.getKeyCode();
	        if (key == KeyEvent.VK_SPACE) {
	        	
	        	System.out.print(y);
	        	y -= 100;
	        	x -= 100;
	        	m.repaint();
	        	
	        }
}
0

Co oznacz zmienna m w funkcji keyPressed()?

main.repaint();
0

Nie pomaga, ale zauważyłem coś. System.out.println(p.x); wrzuciłem do paint() i o dziwo zamiast zmienionej współrzędnej pojawia się smutne zero.
Może podam cały kod?
Main.java

package main;

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

public class Main extends Canvas{
	Player p;
    public Main(){
        setBackground(Color.white);
        p = new Player(this);
        addKeyListener(new Player(this));
    }

    public static void main(String[] args){
      	Main m = new Main();
        JFrame okno = new JFrame();
        okno.setSize(400, 200);
        okno.add(m);
        okno.setVisible(true);
        okno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public void update(Graphics g){
        paint(g);
    }
    public void paint(Graphics g){
    	g.drawRect(p.x, p.y, 10, 100);
    }
}

Player.java

package main;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Player implements KeyListener{
int x, y, width, height;
Main main;
    public static void main(String[] args){
    }
    public Player(Main m){
    	x = 0;
    	y = 0;
    	width = 10;
    	height = 50;
    	main = m;
    }
    public int getX(){
    	return x;
    }
    public int getY(){
    	return y;
    } 
	public void keyPressed(KeyEvent e) {
		Main m = new Main();
		  int key = e.getKeyCode();
	        if (key == KeyEvent.VK_SPACE) {
	        	
	        	x -= 100;
	        	y -= 100;
	        	System.out.println("Y: "+getY() + "X: " + x);
	        	main.repaint();
	        }

	        if (key == KeyEvent.VK_LEFT) {
	            x =- 1;
	        }

	        if (key == KeyEvent.VK_RIGHT) {
	            x =- 1;
	        }

	        if (key == KeyEvent.VK_UP) {
	            x =- 1;
	        }

	        if (key == KeyEvent.VK_DOWN) {
	            x =- 1;
	        }
	}
	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}
}
0
p = new Player(this);
addKeyListener(new Player(this));

Tworzysz dwa obiekty: jeden, który nigdy nie zmienia wartości swoich pól (bo nie nasłuchuje), a z którego te wartości odczytujesz (stąd same zera), i drugi, który ustawia odpowiednie wartości, ale z niego nie czytasz.

0
iooi napisał(a):
p = new Player(this);
addKeyListener(new Player(this));

Tworzysz dwa obiekty: jeden, który nigdy nie zmienia wartości swoich pól (bo nie nasłuchuje), a z którego te wartości odczytujesz (stąd same zera), i drugi, który ustawia odpowiednie wartości, ale z niego nie czytasz.

Teraz poprawnie zmienia swoje wartości, dzięki!
Jednak co z repaint()? Nadal nie działa.

0

Poza tym:

if (key == KeyEvent.VK_LEFT) {
    x =- 1;
}

if (key == KeyEvent.VK_RIGHT) {
    x =- 1;
}

if (key == KeyEvent.VK_UP) {
    x =- 1;
}

if (key == KeyEvent.VK_DOWN) {
    x =- 1;
}

Zmieniasz tu ciągle x, w dodatku zamiast pomniejszać o 1, ciągle ustawiasz na -1 (operator =- zamiast -=).

0
iooi napisał(a):

Poza tym:

if (key == KeyEvent.VK_LEFT) {
    x =- 1;
}

if (key == KeyEvent.VK_RIGHT) {
    x =- 1;
}

if (key == KeyEvent.VK_UP) {
    x =- 1;
}

if (key == KeyEvent.VK_DOWN) {
    x =- 1;
}

Zmieniasz tu ciągle x, w dodatku zamiast pomniejszać o 1, ciągle ustawiasz na -1 (operator =- zamiast -=).

Jestem tego świadom, było to ot tak, żeby tylko. Testowałem na spacji, która, jak zgaduję, jest prawidłowo skonstruowana.

0

Sprawdziłem i u mnie działa. Problem w tym, że przy naciskaniu spacji zmniejszasz współrzędne o 100, więc następne prostokąty rysują się już poza canvasem.

0

pokaż dla pewności jeszcze raz cały kod po poprawkach

0

@iooi, nie zwróciłem uwagi, faktycznie działa, dzięki! :)

A jakieś pomysły w jaki sposób przerysować ten prostokąt? Tzn. zrobić to jako platformę, którą gracz może poruszać.

0

W paint musisz czyścić poprzedni ekran (metoda Graphics.clearRect). Dobrze byłoby do tego dodać double-buffering, żeby prostokąt nie migał przy przerysowaniu.

0
iooi napisał(a):

W paint musisz czyścić poprzedni ekran (metoda Graphics.clearRect). Dobrze byłoby do tego dodać double-buffering, żeby prostokąt nie migał przy przerysowaniu.

Zrobione, ładnie porusza platformą, na horyzoncie pojawił się następny problem:
stworzyłem wątek, chciałem, aby zmieniało w nim pozycję X, a następnie repaint().

Ball.java

package main;

public class Ball extends Thread implements Runnable{
int x = 0;
 int y = 0;
Main main;
	public static void main(String[] args){
		new Ball(new Main());
	}
    public Ball(Main m){
    	start();
    	main = m;
    }
    public int getX()
    {
            return x;
    }
    public int getY()
    {
            return y;
    }
    public void run() {
    	while(true){
	    	x+=1;
	    	main.repaint();
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    }
    }

Metoda paint w Main.java

    public void paint(Graphics g){
    		 g.clearRect(0, 0, getSize().width, getSize().height);
    	        g.setColor(Color.white);
    	        g.drawRect(p.getX(), p.getY(), 10, 50);
    	        g.fillRect(p.getX(), p.getY(), 10, 50);
    	    	g.drawOval(b.getX(), b.getY(), 10, 10); //Ball y
    	
    }

Ładnie przerysowuje, jednak dopiero, gdy wcisnę przycisk od przesuwania platformy.

Player.java

package main;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Player implements KeyListener{
int width, height;
int x = 0;
int y = 0;
Main main;
    public static void main(String[] args){
    }
    public Player(Main m){
    	width = 10;
    	height = 50;
    	main = m;
    }
    public int getX(){
    	return x;
    }
    public int getY(){
    	return y;
    } 
	public void keyPressed(KeyEvent e) {
		Main m = new Main();
		  int key = e.getKeyCode();

	        if (key == KeyEvent.VK_UP) {
	            y-=10;
	        	main.repaint();

	        }

	        if (key == KeyEvent.VK_DOWN) {
	            y+=10;
	        	main.repaint();

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

U mnie działa. Pokaż cały kod, który masz. Tym razem poprawnie sformatowany.

0

Player i Ball jest już podane wyżej, a tutaj Main.java:

package main;

import java.awt.*;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;

public class Main extends Canvas{
	Player p;
	static Ball b;
    public Main(){
    	p = new Player(this);
    	
        addKeyListener(p);
    }

    public static void main(String[] args){
    	b = new Ball(new Main());
      	Main m = new Main();
        JFrame okno = new JFrame();
        okno.setSize(500, 300);
        okno.getContentPane().setBackground(Color.black);
        okno.setResizable(false);
        okno.add(m);
        okno.setVisible(true);
        okno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    Graphics db;
    Image dbi;
    public void update(Graphics g){
    	dbi = createImage(10, 50);
    	db = dbi.getGraphics();
        paint(db);
		 g.clearRect(0, 0, getSize().width, getSize().height);
	        g.setColor(Color.white);
	        g.drawRect(p.getX(), p.getY(), 10, 50);
	        g.fillRect(p.getX(), p.getY(), 10, 50);
	    	g.drawOval(b.getX(), b.getY(), 10, 10);
        
    }
    public void paint(Graphics g){
    		 g.clearRect(0, 0, getSize().width, getSize().height);
    	        g.setColor(Color.white);
    	        g.drawRect(p.getX(), p.getY(), 10, 50);
    	        g.fillRect(p.getX(), p.getY(), 10, 50);
    	    	g.drawOval(b.getX(), b.getY(), 10, 10);
    	
    }
}
0

Non-stop tworzysz mnóstwo obiektów Main, listenerów i innych, których nie powinieneś powielać.
Błąd jest pewnie w tym, że repaintujesz nie ten obiekt Main. Masz zrobić jeden obiekt i przekazywać jego referencje do Ball i do Player.

0

Zmiana jednej linijki w kodzie i działa, muszę lepiej analizować kod. Dzięki jeszcze raz.

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