KeyListener nie reaguje

0

Witam! To mój pierwszy post na tym forum. Na wstępie zaznaczam, że to moje początki z JAVĄ dlatego proszę o wyrozumiałość.

Piszę grę w JAVIE, która ma umożliwiać grę w piłkę nożna (1 na 1) na planszy widzianej z góry. Poszczególnych graczy mają reprezentować prostokąty - obecnie stworzony jest jeden zawodnik (player1). Boisko umieściłem na JPanelu.

Niestety utknąłem w momencie, w którym chcę zaprogramować poruszanie się zawodnika po wciśnięciu odpowiedniego przycisku na klawiaturze. Zaimplementowałem funkcję, która ma przesuwać zawodnika o 10 pikseli w lewo, po wciśnięciu strzałki w lewo na klawiaturze. Program się kompiluje i uruchamia, ale nie ma żadnej reakcji ze strony KeyListener-a. Od kilku godzin szperam po Google ale niestety nie jestem w stanie samodzielnie sobie z tym poradzić.

Oto kod mojego programu:

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

/************************************** FOOTBALLER ***************************************************/
class Footballer extends PitchPanel implements Runnable
	{
		int x;
		int y;
		String name;
		String lastName;
		
		Color footballerColor;
		
		public Footballer(int posX, int posY, String na, String laNa, Color col)
		{
			x = posX;
			y = posY;
			name = na;
			lastName = laNa;
			footballerColor = col;
		}
		
		public void moveF(int dX, int dY)		
		{
			x += dX;
			y += dY;
		}
		
		public void paint(Graphics g)
		{
			g.setColor(footballerColor);
			g.fillRect(x, y, 10, 10);
		}
		
		public void run()
		{
			
		}
	}

/************************************** PITCH ***************************************************/
class PitchPanel extends JPanel implements KeyListener
{		
		public Footballer player1;
		public Footballer player2;
		
		public Graphics grafika;
			
		public PitchPanel()
		{
			this.setFocusable(true);
			this.addKeyListener(this);
		}	
							
		public void paint(Graphics g)
		{		
			grafika = g;
			
			Color GrassColor = new Color(45,123,27);		// kolor trawy
			Color LineColor = new Color(250,250,250);		// kolor linii
			
			g.setColor(GrassColor);							// trawa
			g.fillRect(20,80,745,500);						
			g.setColor(LineColor);							// linie wyznaczające boisko
			g.drawLine(40,90,745,90);						
			g.drawLine(745,90,745,570);
			g.drawLine(40,90,40,570);
			g.drawLine(40,570,745,570);
			g.drawRect(30,300,10,60);						// bramki
			g.drawRect(745,300,10,60);
			
			//Stworzenie gracza
			player1 = new Footballer(100,100,"Zbigniew","Boniek",new Color(140,180,170));	
			player1.run();	
			player1.paint(g);		
		}
		
		// Obsługa klawiszy
		public void keyTyped(KeyEvent e)
		{

		}
		
		public void keyPressed(KeyEvent e)
		{
			if(e.getKeyCode() == KeyEvent.VK_LEFT)
			{
				player1.moveF(-10,0);
				player1.paint(grafika);
			}
		}
		
		public void keyReleased(KeyEvent e)
		{}		
}

/************************************** FOOTBALL ***************************************************/
public class Football extends JFrame 
{	
	public static void main(String[] args) 
	{
		Football okno = new Football("Football");
		okno.init();
	}
	
	Football(String tekst)
	{
		super(tekst);
	}
	
	void init()
	{
		// funkcje wywoływane na rzecz okna
		setSize(800,650);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setResizable(false);
		
		// Layout
		Container cp = getContentPane();
		cp.setLayout(new BorderLayout());
		
		// Menu górne
		JMenuBar jmb = new JMenuBar();
		//
		JMenu mGame = new JMenu("Game");
		JMenuItem miNewGame = new JMenuItem("New game");
		JMenuItem miOptions = new JMenuItem("Options");
		JMenuItem miExit = new JMenuItem("Exit");
		//
		JMenu mInfo = new JMenu("Info");
		JMenuItem miHelp = new JMenuItem("Help");
		JMenuItem miAbout = new JMenuItem("About Program");		
		
		// ułożenie menu
		mGame.add(miNewGame);
		mGame.add(miOptions);
		mGame.add(miExit);
		mInfo.add(miHelp);
		mInfo.add(miAbout);
		jmb.add(mGame);
		jmb.add(mInfo);
		cp.add(jmb, BorderLayout.NORTH);
		
		// stworzenie i ułożenie pozostałych elementów programu
		JPanel pitch = new PitchPanel();
		add(pitch);

		// pokazanie okna
		setVisible(true);
	}
}

Bardzo proszę o wskazówki.

0

Ta metoda działa jak najbardziej, możesz sobie wpisać "System.out.println(e);" do treści ifa.
Problem jest błędnym rysowaniem.

  1. keyPressed zmieniasz następująco:
public void keyPressed(KeyEvent e)
{	
         if(e.getKeyCode() == KeyEvent.VK_LEFT)
         {
              player1.moveF(-10,0);
              repaint();
         }
}
  1. Gracza instancjonujesz tylko raz:
public final Footballer player1 = new Footballer(100,100,"Zbigniew","Boniek",new Color(140,180,170));  

Usuwasz "new Footballer.." z metody paint.

  1. Usuwasz "extends PitchPanel" z klasy Footballer

  2. Wywalasz niepotrzebną zmienną "grafika";

0

Wielkie dzięki! - działa :)

0

Witam wszystkich.
Mam podobny problem, więc nie ma co zakładać nowego wątku.

Mam napisać aplikację okienkową bazującą na JFrame. Co istotniejsze fragmenty kodu wyglądają tak:

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

public class Tlo extends JFrame {
	
	JFrame oknoGlowne;

	public Tlo(){

		oknoGlowne = new JFrame("Tablica rozdzielcza");
		oknoGlowne.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		oknoGlowne.setSize(800, 300);			//parametry okna
		oknoGlowne.setLocation(50, 50);
		oknoGlowne.setBackground(Color.BLACK);
		oknoGlowne.setVisible(true);			//uwidoczenienie okna
		
		Klawisz uchwyt = new Klawisz();		//uchwyt do obsługi klawisza
		addKeyListener(uchwyt);
		
	}
	
	public class Klawisz implements KeyListener{
	
	File trasa = new File("trasa.txt");		//plik i strumień tworzymy w wewnętrznej klasie, bo inaczej wyskakuje "unknown source"
	FileWriter strumienZapisu;
		
		public Klawisz(){		//kontruktor, który otworzy strumień
			
			try{
				strumienZapisu = new FileWriter(trasa);
			}catch(IOException io){
				System.out.println(io.getMessage());
			}
			System.out.println("jestem");

		}

		public void Zapis(String wKtora){		//funkcja zapisująca do pliku

			try{
				strumienZapisu.append("Skręt w "+wKtora+System.getProperty("line.separator"));

			}catch(IOException io){
				System.out.println(io.getMessage());
			}

		}

		public void keyPressed(KeyEvent k){
			int kodKlawisza = k.getKeyCode();
			if(kodKlawisza == KeyEvent.VK_LEFT){	//kierunkowskaz w lewo

				System.out.println("w lewo");
				Zapis("lewo");

			}else
			if(kodKlawisza == KeyEvent.VK_RIGHT){	//kierunkowskaz w prawo
				
                                System.out.println("w prawo");
				Zapis("prawo");

			}else
			if(kodKlawisza == KeyEvent.VK_UP && buttons.wskaznik.zwrocPredkosc() < 220){	//przyspieszenie
				System.out.println("przyspiesz");

			}else
			if(kodKlawisza == KeyEvent.VK_DOWN && buttons.wskaznik.zwrocPredkosc() > 0){	//zwolnienie
				System.out.println("zwolnij");

			}else
			if(kodKlawisza == KeyEvent.VK_A){			//zamyka strumień zapisu (może zmienię na opcję w menu). na razie klawisz "a"
				try{
					strumienZapisu.close();
				}catch(IOException io){
					System.out.println(io.getMessage());
				}
			}
		}

		public void keyTyped(KeyEvent k){ }	//tych dwóch nie uzywam, ale muszą być, bo się sypnie

		public void keyReleased(KeyEvent k){ }
	}

}

Obiekt klawisza się tworzy, ale po wciśnięciu klawisza ani nic nie wyświetla się w konsoli, ani nic nie zapisuje się do pliku.
Będę wdzięczny za pomoc.

0

Zmień

addKeyListener(uchwyt);

na

oknoGlowne.addKeyListener(uchwyt);

i wywal

extends JFrame

I jeszcze nie ma zmiennej "buttons".

0

Zrobiłem, jak radziłeś, ale różnicy nie zaobserwowałem.

Zmiennej buttons faktycznie nie zamieścilem w poście, ale jest ona w programie.

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