带 Swing 的 keyListener 和带 Swing/keyListener 和 Thread 的游戏关卡系统
keyListener with Swing and game level system with Swing/keyListener and Thread
我是一名新手编码员,大约 10 年前有一点点 C++ 经验,现在正在学习 java(大约 4-5 个月)。我有一个小的协作项目正在进行,我有一些事情要弄清楚。
代码如下:
import java.awt.event.*;
import java.awt.*;
import javax.swing.JFrame;
import java.util.Scanner;
import java.util.Random;
public class Game extends JFrame {
GamePanel panel;
int[][] grid;
int size;
//...and some other variables
public Game(String title) {
super(title);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new GamePanel(grid,size);
this.add(panel);
Button button = new Button("WHAT");
button.setBounds(-100, -100, 70, 70);
this.add(button);
button.addKeyListener(new KeyHandler());
}
class KeyHandler extends KeyAdapter {
public void keyPressed(KeyEvent e) {
int keycode = e.getKeyCode();
switch(keycode) {
//arrow keys input and stuff
}
if(checkForWin()) //checkForWin() returns a boolean value for win/loss
//won the game, thus end the thread here
if(checkForLoss()) // similar stuff as checkForLoss()
//lost the game, thus end the thread here
//...update the panel
panel.repaint();
}
}
public static void main(String [] args) {
Game me = new Game("GAME");
me.setVisible(true);
}
}
这就是整个游戏的样子。
我有问题:
我正在使用一个按钮并将其放在负位置以使其不可见并将其用作 KeyListener 的手段。还有其他方法可以添加关键监听器吗?例如)到面板或其他东西?
我想改成每个"level"一个线程,弄成这样
public static void main(String [] args) {
int level = 1;
do {
GameThread gt = new GameThread("Game");
// run() will have the game constructor inside
gt.setLevel(level);
gt.start();
gt.join(); //wait until the game "level" is finished
if(won)
level++;
if(lost)
level = 1;
} while(!checkIfDonePlaying())
}
有点像这样。我无法让线程继续 运行 直到游戏关卡真正完成。我该怎么做?
- 我想添加一个 JLabel 来在框架上显示分数。但是当我这样做时,当我重绘()它时,分数不会更新。我该怎么做?
提前致谢!
这是第一个问题的解决方案:
panel.setFocusable(true);
panel.addKeyListener(this);
那么您应该就可以执行通常的关键侦听器方法了。一定要实现 KeyListener!
其他问题的解决方案正在路上。 (实际上采纳@TNT 的建议并使用键绑定,我更喜欢听众,但对于游戏我通常使用 lwjgl 或 slick2d)
2.
我觉得 运行 宁你的程序水平可能有点低效(可能只是我)我建议在 运行 方法中有一个线程并具有以下内容:
Public void reset(int level)
{
//reset all variables based on local variable level...
}
这样称呼它:
Reset(++currentLevel)); //use ++ before currentLevel so it adds to it and then resets
如果需要,您可以轻松地使用 switch case 来做一些特殊的事情
Switch(level){
case 1: //...
}
等等。 (我正在手机上打字,抱歉出现了奇怪的大写字母)
几件事:
是的,有一种方法可以将 KeyListener
添加到面板,那就是使用 key bindings。例如:
javax.swing.InputMap im = panel.getInputMap(panel.WHEN_IN_FOCUSED_WINDOW);
javax.swing.ActionMap am = panel.getActionMap();
im.put(javax.swing.KeyStroke.getKeyStroke("pressed UP"), "up");
am.put("up", new javax.swing.AbstractAction() {
@Override
public void actionPerformed(ActionEvent ev) {
// handle up arrow key action here
}
});
Swing是一个事件驱动的环境,所以不应该使用do-while循环。相反,请使用 Swing 计时器定期检查您的关卡是否已完成。
因为你没有在你的 JLabel
上做任何自定义绘画,你不应该使用 repaint
。相反,使用它的 setText
方法。
我是一名新手编码员,大约 10 年前有一点点 C++ 经验,现在正在学习 java(大约 4-5 个月)。我有一个小的协作项目正在进行,我有一些事情要弄清楚。
代码如下:
import java.awt.event.*;
import java.awt.*;
import javax.swing.JFrame;
import java.util.Scanner;
import java.util.Random;
public class Game extends JFrame {
GamePanel panel;
int[][] grid;
int size;
//...and some other variables
public Game(String title) {
super(title);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new GamePanel(grid,size);
this.add(panel);
Button button = new Button("WHAT");
button.setBounds(-100, -100, 70, 70);
this.add(button);
button.addKeyListener(new KeyHandler());
}
class KeyHandler extends KeyAdapter {
public void keyPressed(KeyEvent e) {
int keycode = e.getKeyCode();
switch(keycode) {
//arrow keys input and stuff
}
if(checkForWin()) //checkForWin() returns a boolean value for win/loss
//won the game, thus end the thread here
if(checkForLoss()) // similar stuff as checkForLoss()
//lost the game, thus end the thread here
//...update the panel
panel.repaint();
}
}
public static void main(String [] args) {
Game me = new Game("GAME");
me.setVisible(true);
}
}
这就是整个游戏的样子。
我有问题:
我正在使用一个按钮并将其放在负位置以使其不可见并将其用作 KeyListener 的手段。还有其他方法可以添加关键监听器吗?例如)到面板或其他东西?
我想改成每个"level"一个线程,弄成这样
public static void main(String [] args) { int level = 1; do { GameThread gt = new GameThread("Game"); // run() will have the game constructor inside gt.setLevel(level); gt.start(); gt.join(); //wait until the game "level" is finished if(won) level++; if(lost) level = 1; } while(!checkIfDonePlaying()) }
有点像这样。我无法让线程继续 运行 直到游戏关卡真正完成。我该怎么做?
- 我想添加一个 JLabel 来在框架上显示分数。但是当我这样做时,当我重绘()它时,分数不会更新。我该怎么做?
提前致谢!
这是第一个问题的解决方案:
panel.setFocusable(true);
panel.addKeyListener(this);
那么您应该就可以执行通常的关键侦听器方法了。一定要实现 KeyListener! 其他问题的解决方案正在路上。 (实际上采纳@TNT 的建议并使用键绑定,我更喜欢听众,但对于游戏我通常使用 lwjgl 或 slick2d)
2.
我觉得 运行 宁你的程序水平可能有点低效(可能只是我)我建议在 运行 方法中有一个线程并具有以下内容:
Public void reset(int level)
{
//reset all variables based on local variable level...
}
这样称呼它:
Reset(++currentLevel)); //use ++ before currentLevel so it adds to it and then resets
如果需要,您可以轻松地使用 switch case 来做一些特殊的事情
Switch(level){
case 1: //...
}
等等。 (我正在手机上打字,抱歉出现了奇怪的大写字母)
几件事:
是的,有一种方法可以将
KeyListener
添加到面板,那就是使用 key bindings。例如:javax.swing.InputMap im = panel.getInputMap(panel.WHEN_IN_FOCUSED_WINDOW); javax.swing.ActionMap am = panel.getActionMap(); im.put(javax.swing.KeyStroke.getKeyStroke("pressed UP"), "up"); am.put("up", new javax.swing.AbstractAction() { @Override public void actionPerformed(ActionEvent ev) { // handle up arrow key action here } });
Swing是一个事件驱动的环境,所以不应该使用do-while循环。相反,请使用 Swing 计时器定期检查您的关卡是否已完成。
因为你没有在你的
JLabel
上做任何自定义绘画,你不应该使用repaint
。相反,使用它的setText
方法。