Keylistener implementieren

B

ByeBye 249712

Hallo

Ich muss mit Java 2D ein Spielfeld zeichnen. Es besteht aus lauter Quadraten, welche alle rot sind. Auf dem Spielfeld ist links oben in der Ecke ein schwarzes Quadrat. Nun möchte ich dieses Quadrat mit meiner Tastatur auf dem Spielfeld bewegen können. Zunächst einmal die Klasse in der das Feld gezeichnet wird.

Code:
public class Field extends JPanel {

    /**
     * Saves which Rect is currently black.
     */ 
        
    private Point currentRect = new Point(0, 0);
    
    /**
     * Color of the drawn rect;
     */
    private Color currentRectColor = Color.BLACK;

    /**
     * Constructor.
     * 
     */
    public Field() {
        this.setVisible(true);
        this.repaint();
    }

    @Override
    protected void paintComponent(final Graphics g) {
        super.paintComponent(g);
        Graphics2D twoD = (Graphics2D) g;
        // Backgorund color used as border color.
        this.setBackground(Color.BLACK);
        
        
        

        for (int x = 0; x < MainFrame.RECNUMBER; ++x) {
            // draws the ful squares
            for (int y = 0; y < MainFrame.RECNUMBER; ++y) {
                if (x == currentRect.getX() && y == currentRect.getY()) {
                    twoD.setColor(currentRectColor);
                } 
                
              
                    else {  twoD.setColor(Color.RED);
                }
                twoD.fillRect(x * MainFrame.RECSIZE + x,
                        y * MainFrame.RECSIZE + y, MainFrame.RECSIZE,
                        MainFrame.RECSIZE);
            }
        }
    }
}


Mein Ansatz war jetzt irgendwie bei "private Point currentRect = new Point(0, 0);" (Zeile 8)
immer die neuen Koordinaten die durch das drücken der Tastatur entstehen, dort hinein zu schreiben. Sodass das schwarze Quadrat dann immer an der neuen Stelle gezeichnet wird. Kann mir jemand sagen wie ich dass mache?

Hier der Code mit dem Keylistener

Code:
public class Controller implements ActionListener, KeyListener {


    private Field field ;

    public Controller( Field field ) {
        this.field = field;
        this.field.addKeyListener( this );
    }
         
         
     public final void up() {

		
	
    }    


  
    @Override
    public final void keyPressed(final KeyEvent e) {

		int code = e.getKeyCode();

	
		if (code == KeyEvent.VK_W) {

			up();
		}
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        
    }

    @Override
    public void keyTyped(KeyEvent e) {
        
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }
}

Der ist natürlich noch unvollständig. Ich hoffe da blickt jemand durch. Bin absoluter Anfänger in Java-Programmierung. Wär echt nett wenn mir jemand helfen könnte :)

schöne Grüße
 
Davon abgesehen das es bei uns im Java-Forum zum guten Ton gehört [code=java][/code] - Tags zu verwenden sieht das ganze ziemlich schwammig aus.

Warum erzeugst du ein Objekt der Klasse Controller und setzt in diesem den ActionListener anstatt einfach in der Klasse Field ein
Java:
addActionListener(new Controller(this));
zu verwenden ?

Auch ist es sehr merkwürdig das du in einer von JPanel abgeleiteten Klasse im Konstruktor
Java:
setVisible(true);
repaint();
aufrufst. Das ist weder OOP noch ergibt das irgendeinen Sinn. Davon abgesehen das THIS hier überhaupt nicht notwendig ist.

Ansonsten sieht das halbwegs verwendbar aus.
Was jetzt noch fehlt ist ein field.update(field.getGraphics()) in der Methode Controller.up();

Nur mal so als Frage : wie viel Erfahrung hast du bereits mit Java und warum "Ich muss" ?

Als Grundlage würde ich dir die JavaInsel *einfach mal GooGLe fragen* empfehlen. Da werden auch solche Sachen wie Listener und OOP behandelt.

Code bekommst du von mir bewusst NICHT da du von mir gerade alle Informationen bekommen hast die du brauchst um das was du vorhast umzusetzen.

Wenn du zu irgendetwas konkrete Fragen hast ... dann helfen wir dir gerne ... aber einfach : "ich muss das und das machen ... HILFE" ... dafür sind wir hier nicht zuständig.
Auch fehlt eine Beschreibung des Problems WAS nicht funktioniert oder WOBEI du konkrete Hilfe brauchst.

btw : dein Beispiel ist so leider nicht compilerbar. Auch das sollte man beachten : ein kurzes , compilebares Beispiel an dem das Problem deutlich wird welches man *hoffentlich* ausführlich beschrieben hat.
 
Ich muss mit Java 2D ein Spielfeld zeichnen. Es besteht aus lauter Quadraten, welche alle rot sind. Auf dem Spielfeld ist links oben in der Ecke ein schwarzes Quadrat. Nun möchte ich dieses Quadrat mit meiner Tastatur auf dem Spielfeld bewegen können.
Die Frage ist, wie liegen die roten Quadrate und darf das schwarze Quadrat über die roten Quadrate zu liegen kommen? Je nachdem, brauchst Du ein Modell des Spielfelds, mit dem geprüft werden kann, ob das schwarze Quadrat überhaupt in eine bestimmt Richtung bewegt werden kann.
 
Zuletzt bearbeitet:
Wenn du zu irgendetwas konkrete Fragen hast ... dann helfen wir dir gerne ... aber einfach : "ich muss das und das machen ... HILFE" ... dafür sind wir hier nicht zuständig.
Auch fehlt eine Beschreibung des Problems WAS nicht funktioniert oder WOBEI du konkrete Hilfe brauchst.

Okei dann versuche ich mal mein Problem zu konkretisieren.

Bei

Java:
    @Override
    public final void keyPressed(final KeyEvent e) {
 
        int code = e.getKeyCode();
 
    
        if (code == KeyEvent.VK_W) {
 
            up();
        }
    }

soll, wenn die Taste W gedrück wird, an die Methode up() ein Wert übergeben werden. Ich dachte mir am besten wäre vielleicht ein Integer, welcher dann, jedes mal wenn die Taste W gedrückt wird hochzählt. Dieser Wert soll dann in der Klasse Field an der Stelle

Java:
  private Point currentRect = new Point(0, 0);

übergeben werden. Der Punkt soll dann durch den neuen Wert neu beschrieben werden, sodass dann hier

Java:
 @Override
    protected void paintComponent(final Graphics g) {
        super.paintComponent(g);
        Graphics2D twoD = (Graphics2D) g;
        // Backgorund color used as border color.
        this.setBackground(Color.BLACK);
        
        
        
 
        for (int x = 0; x < MainFrame.RECNUMBER; ++x) {
            // draws the ful squares
            for (int y = 0; y < MainFrame.RECNUMBER; ++y) {
                if (x == currentRect.getX() && y == currentRect.getY()) {
                    twoD.setColor(currentRectColor);
                } 
                
              
                    else {  twoD.setColor(Color.RED);
                }
                twoD.fillRect(x * MainFrame.RECSIZE + x,
                        y * MainFrame.RECSIZE + y, MainFrame.RECSIZE,
                        MainFrame.RECSIZE);
            }
        }

das schwarze Quadrat an der neuen Stelle gezeichnet werden kann.

Ich habe schon probiert in die up() Methode einen Integer zu schreiben der dann hochzählt. Meine frage wäre jetzt wie kann ich diesen Wert dann an meine Field Klasse übergeben? und funktioniert das überhaupt so?

btw : dein Beispiel ist so leider nicht compilerbar. Auch das sollte man beachten : ein kurzes , compilebares Beispiel an dem das Problem deutlich wird welches man *hoffentlich* ausführlich beschrieben hat.


Hier ist noch meine Startup und meine MainFrame-Klasse. Damit müsste das Programm dann complierbar sein.

Java:
public final class StartUp {

	/**
	 * Verhindert Instanziierung dieser Klasse.
	 */
	private StartUp() {

	}

	/**
	 * Einstieg in das Programm.
	 * 
	 * @param args
	 *            Kommandozeilenargumente
	 */
	public static void main(final String[] args) {

		new MainFrame();
	}
}


Java:
public class MainFrame extends JFrame {

    /**
     * Number of rectangles.
     */
    public static final int RECNUMBER = 15;
    /**
     * Size of the single rectangels.
     */
    public static final int RECSIZE = 50;

    /**
     * Constructor.
     */
    public MainFrame() {
        init();
    }

    /**
     * Inits the frame.
     */
    private void init() {
        final Field field = new Field();
        this.add(field);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setTitle("Java2D");
        this.pack();
        this.setResizable(false);
        this.setVisible(true);
        this.setSize(new Dimension(
                RECNUMBER * RECSIZE + this.getInsets().left
                + this.getInsets().right + RECNUMBER - 1,
                RECNUMBER * RECSIZE + this.getInsets().top
                + this.getInsets().bottom + RECNUMBER - 1));
    }
}

schöne Güße
celtx
 
Zuletzt bearbeitet von einem Moderator:
Hi,

also um dein schwarzes Feld zu bewegen, kannst du die x- und y-Position des Feldes einfach immer mit dem Faktor (Länge bzw. Höhe der Felder) multiplizieren. Dann ist dein Feld da wo es hin soll.

Gruß

Fabio
 
Selbst wenn Du an die Instanz von Field rankommst, was willst Du damit machen? Alle Felder sind privat und es gibt auch keine Setter.

also um dein schwarzes Feld zu bewegen, kannst du die x- und y-Position des Feldes einfach immer mit dem Faktor (Länge bzw. Höhe der Felder) multiplizieren. Dann ist dein Feld da wo es hin soll.

Das besetzt Feld müsste noch auf rot. Wo wird das gemacht?
 
Zuletzt bearbeitet von einem Moderator:
@suchong
Es gibt hier bei uns eine EDIT-Funktion mit der du deine Posts nach belieben editieren kannst.

Ich habe mal eine Zusammenführung deiner Posts beantragt.
 
@Grünschnabel
Irgendwie kann ich dir nicht so ganz folgen. Es geht mir hier hauptsächlich um die Klasse Controller. Hier soll mit Hilfe des Keylisteners, durch ein Key-Event eine Variable verändert werden, welche dann in die Klasse Field geschrieben werden soll.
Ich habe inzwischen den Controller soweit verändert. Aber irgendetwas muss hier noch falsch sein. Denn die variable m verändert sich nicht durch drücken der W-Taste.
Hier ist der angepasste Controller:

Java:
public class Controller implements ActionListener, KeyListener {

    public static int m = 3;
 
      
   
    
     
    private Field field ;

    public Controller( Field field ) {
        this.field = field;
        this.field.addKeyListener( this );
    }
         
      
    
    
    
    
    
    @Override
    public final void keyTyped(final KeyEvent e) {

		int code = e.getKeyCode();

	
		if (code == KeyEvent.VK_W) {

		     up();
                        
                       
		}
                
    }
    
        
          public static void up(){
        
          Controller.msetter();
          
    
        }
       
          
          
           public static void msetter (){
           m++;
           
  
        }
         

    @Override
    public void actionPerformed(ActionEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        
    }

 
    @Override
    public void keyReleased(KeyEvent e) {
    }


    
    
}
 
Wie ich es oben bereits schon erwähnte hast du scheinbar keine Ahnung von OOP.
Und genau das ist hier das Problem.

Da sowohl die Variable "m" static , die Setter-Methode *im übrigen nicht gerade ein Name der den Konventionen folgt , von der Signatur ganz zu schweigen* static sowie der Call selbst static sind ... arbeitest du nicht mit einer Instanz-Variable *wie du es warscheinlich willst* sondern nur mit einer Konstanten.

Ich würde dir dann doch noch mal einen Blick in die JavaInsel empfehlen ... und GooGLe mal nach "java oop" ... da dürftest du dann im Sun-Tutorial einiges lernen.

Ich persönlich habe gerade nur sehr wenig bis überhaupt keine Lust dir OOP an diesem Beispiel zu erklären.
 
Selbst wenn Du an die Instanz von Field rankommst, was willst Du damit machen? Alle Felder sind privat und es gibt auch keine Setter.
Also ich meinte das auch nicht so, dass ich direkt auf die Variablen x und y zugreifen kann. Sondern eher in der Form:
Java:
public class Moveable {
   private static final int SPEED_X = 2;
   private static final int SPEED_Y = 2;
   private int x;
   private int y;

   public Moveable(int x, int y) {
      this.x = x;
      this.y = y;
   }

   public void moveUp() {
      y -= SPEED_Y;
   }

   public void moveDown() {
      y += SPEED_Y;
   }

   public void moveRight() {
      x += SPEED_X;
   }

   public void moveLeft() {
      x -= SPEED_X;
   }
}
Dann muss man natürlich noch die X- und Y-Koordinaten via getter abfragen können.
 

Neue Beiträge

Zurück