Ich versuche ein sehr einfaches Plattformspiel in Java zu schreiben. Ich hatte Teile davon mit passivem Rendering (mit einem Timer
Objekt, das repaint()
und revalidate()
usw. aufruft), aber ich habe versucht, aktives Rendering zu implementieren. Es funktioniert irgendwie - in dem es rendert, und die Animation funktioniert, aber es scheint den Schlüssel Listener zu blockieren (was früher gut funktionierte) aus irgendeinem Grund, den ich nicht wirklich verstehe.Keylistener funktioniert nicht beim aktiven Rendern
Ich habe das Problem so wenig wie möglich nachgestellt. Wenn Sie eine Taste drücken, sollte die Ausgabe des Terminals erfolgen, aber es gibt keine. Wenn jemand mir erklären kann, warum die Methoden keyPressed
etc. nicht feuern, würde es sehr geschätzt werden.
bearbeiten - Modifizierte Demo-Code in eine Kopieren/Einfügen als pro Anfrage
EDIT2 - Wie von Andrew Thompson vorgeschlagen, habe ich die ganzen Vollbild-Code entfernt und der keyListener immer noch nicht arbeiten
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
class FullScreenRenderWithListener implements KeyListener {
private JFrame frame;
private World world;
public static void main(String[] args)
{
FullScreenRenderWithListener main = new FullScreenRenderWithListener();
SwingUtilities.invokeLater(main::run);
}
private void run()
{
initWindow();
setupWorld();
frame.setIgnoreRepaint(true);
frame.pack();
frame.createBufferStrategy(2);
frame.setVisible(true);
world.startActive(frame.getBufferStrategy());
}
private void initWindow()
{
frame = new JFrame();
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
}
private void setupWorld()
{
world = new World();
frame.addKeyListener(this);
frame.add(world);
world.addKeyListener(this);
}
@Override
public void keyPressed(KeyEvent event)
{
System.out.println("Pressed");
}
@Override
public void keyReleased(KeyEvent event)
{
System.out.println("Released");
}
@Override
public void keyTyped(KeyEvent event)
{
System.out.println("Typed");
}
}
class World extends JPanel {
private static final int FRAMES_PER_SEC = 60;
private static final int MILL_IN_SEC = 1000;
private static final int TICK_LENGTH =
MILL_IN_SEC/FRAMES_PER_SEC;
private BufferStrategy strategy;
private void sleepUntilEndOfFrame()
{
try {
long used = System.currentTimeMillis() % TICK_LENGTH;
long left = TICK_LENGTH - used;
Thread.sleep(left);
} catch(InterruptedException e) {
// ... Handle this error
}
}
public void startActive(BufferStrategy strategy)
{
this.strategy = strategy;
setIgnoreRepaint(true);
while(true) {
doFrame();
}
}
private void doFrame()
{
updateGameState();
activeRenderFrame();
}
private void updateGameState()
{
// ..
}
private void activeRenderFrame()
{
Graphics2D graphicsContext = (Graphics2D)strategy
.getDrawGraphics();
paintComponent(graphicsContext);
strategy.show();
Toolkit.getDefaultToolkit().sync();
graphicsContext.dispose();
sleepUntilEndOfFrame();
}
@Override
public Dimension getPreferredSize()
{
return new Dimension(500, 500);
}
// Have overridden this method because the class
// also implements passive rendering if active is
// not supported
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
// .. drawing code
}
}
Der Key Listener scheint dem Frame hinzugefügt zu sein. Wenn ein Rahmen zum Rahmen hinzugefügt wird, deckt er ihn vollständig ab und schluckt die Schlüsselereignisse. Aber ich kann nicht sehen, wie der ursprüngliche Rahmen wichtige Ereignisse erhalten hat, da er nicht fokussierbar war. Für weitere Hilfe, drehen Sie die beiden Codebeispiele in eine Kopie/Paste und geben Sie der 'Main' Klasse einen vernünftigen Namen, damit ich es in mein 'Junk-Code'-Paket zum Testen fallen lassen kann. –
@AndrewThompson Fertig –
Haben Sie versucht, die kompilieren Einzelkopie/Paste? Und 'Demo'? O_o Wie wäre es mit etwas Spezifischerem, das wahrscheinlich von jemand anderem mit einem Problem nicht benutzt wird: z.B. 'FullScreenRenderWithKeyListener'? –