Wir sind damit beauftragt, ein einfaches Spiel zu machen. Jetzt haben wir das Spiel schon lange gemacht, aber ich habe gerade erst das join/host-Menü implementiert (mit einem JPanel in unserem JFrame, der nur einen Canvas enthält, der zum Rendern unserer Sprites/Shapes verwendet wird /etc.). Wir haben 4 JTextFields und zwei JButtons. Unsere Leinwand wird deaktiviert, wenn diese Anzeige so angezeigt wird, dass sie die Eingabe nicht stört (d. H. Mit ihrem Maus-Listener und dergleichen). Auf Windows-Rechnern können wir auf alle Kästchen klicken, wir bekommen den netten I-Strahl-Cursor usw., und wir können dort normal eingeben und dann auf die Schaltflächen klicken. Wenn dies jedoch unter MacOS versucht wird, können Sie nicht auf die Felder oder Schaltflächen klicken. Du bekommst den I-Beam nicht auf die Boxen. Es ist als ob sie nicht existieren. Wir können jedoch die Tabulatortaste verwenden, um den Fokus durch alle Elemente zu schalten, und können damit die Felder eingeben, die Schaltflächen usw. drücken, genau wie es mit der Maus möglich ist. Ich habe versucht, Fokus auf 20 verschiedene Arten zu verlangen, aber das schien nicht zu funktionieren. Ich habe viele andere Apps auf die gleiche Weise gemacht (JFrame> JPanel> JButton/TextField), und sie alle haben auf MacOS gut funktioniert. So etwas habe ich noch nie gesehen.JTextField kann nicht mit der Maus auf Mac OS fokussiert werden
Anstatt eine ganze Reihe von ganzen Dateien zu posten, werde ich sie abschneiden. Der erste ist unser Haupteinstieg, die Game-Klasse. Es sieht in etwa so aus:
public class Game extends Canvas implements Runnable
private JFrame frame;
private ConnectScreen connectScreen;
public getFrame() { /* get reference to frame */ }
public setFrame() { /* set the frame */ }
public void run() { /* game loop, calls render() */ }
public Game() { /* create window, add canvas to it, get reference to frame, instantiate stuff, etc. */ }
public void tick() { /* every frame this happens, just tells spawners to spawn stuff, etc. */ }
public void render() {
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
///////// Draw things below this/////////////
g.setColor(Color.black);
g.fillRect(0, 0, WIDTH, HEIGHT);
// SCREEN
if (!isPaused()) {
// THIS is where we tell the canvas to enable if we're not on the connect screen
if (gameState != STATE.Join && gameState != STATE.Host) {
this.setEnabled(true);
}
/* i omitted rendering from all of these, since it's not useful here. most say somethingScreen.render(g) or something like that. */
if (gameState == STATE.Wave || gameState == STATE.Multiplayer || gameState == STATE.Bosses || gameState == STATE.Survival) { // render gameplay items
} else if (gameState == STATE.Menu || gameState == STATE.Help || gameState == STATE.Credits) { // render menu
} else if (gameState == STATE.Upgrade) { // render upgrade screen
} else if (gameState == STATE.GameOver) { // render game over screen
} else if (gameState == STATE.Leaderboard) { // render leaderboard
} else if (gameState == STATE.Color) { // render color picker screen
} else if (gameState == STATE.Join || gameState == STATE.Host) {
// if we are on the connect screen, disable this canvas
this.setEnabled(false);
connectScreen.render(g);
} else if (gameState == STATE.LeaderboardDisplay) { // render the leaderboard
}
} else {
pauseMenu.render(g);
}
if(!isPaused()) {} // renders the handler's things
///////// Draw things above this//////////////
g.dispose();
bs.show();
}
}
Darüber hinaus gibt es in dieser Klasse nicht viel von Interesse. Hier ist die (abgespeckte) ConnectScreen Klasse:
public class ConnectScreen extends JPanel {
JFrame frame; // this is the frame from the Game class
JTextField _____; // there are 4 of these
JButton _____; // there are 2 of these
public ConnectScreen(Game game) { // the game is passed in to get the frame from it
super();
this.setBackground(Color.black);
this.setPreferredSize(new java.awt.Dimension(Game.WIDTH, Game.HEIGHT));
this.setSize(new java.awt.Dimension(Game.WIDTH, Game.HEIGHT));
this.game = game;
this.mpSpawn = mp;
game.getFrame().add(this);
this.setFocusable(true);
/* set up each component */
/* add each component (click handlers, etc.) */
/* add panel to frame */
}
public void render(Graphics g) {
super.paintComponent(g);
this.paintComponents(g);
}
}
Wir wissen, dass die Einrichtung von Elementen und so alle gearbeitet, da wir sie und verwenden, um alle auf Windows sehen, aber aus irgendeinem Grund, wenn wir es auf MacOS versuchen, es funktioniert nicht. Wir können sie tab-auswählen und/drücken, aber aus irgendeinem Grund können Sie nicht auf sie klicken, um zu fokussieren. Jede Hilfe wäre willkommen. Vielen Dank!
Das Problem ist nicht mit dem Textfeld oder dem Betriebssystem, aber mit der 'BufferStrategy'. Swing-Komponenten haben ihren eigenen Malmechanismus, der nicht mit 'BufferStrategy' kompatibel ist - als allgemeine Regel sollten Sie NIEMALS eine' paint'-Methode direkt aufrufen. – MadProgrammer
Stattdessen müssen Sie zwischen 'JPanel' und' Canvas' wechseln - mischen Sie nicht Swing-Komponenten und 'BufferStrategy' Rendering – MadProgrammer
FYI: Es gibt eine ganze Pipeline von Funktionen, die Sie in Ihrem Versuch übersprungen haben" Wenn Sie die Swing-Komponenten manuell rendern, richtet diese Funktion den Ereignisverteilungsprozess ein, mit dem die Komponenten benachrichtigt werden, wenn Ereignisse auftreten. Ihr Versuch ist bestenfalls naiv und zeigt einen allgemeinen Mangel an Wissen darüber, wie die gesamte API funktioniert (nichts für ungut, die meisten Tage, die Sie nicht brauchen würden), weshalb ich vorschlage, die BufferStrategy nicht zu verwenden 'this Way, aber um physisch zwischen ihnen zu wechseln (add/remove/setVisible was auch immer) – MadProgrammer