I have the following code:
private int getKeyboardKeyPressed() {
while (Keyboard.next()) {
if (Keyboard.getEventKeyState()) {
int key = Keyboard.getEventKey();
if (key == Keyboard.KEY_ESCAPE)
return -1;
return key;
}
}
return -1;
}
private int getMouseKeyPressed() {
return Mouse.getEventButton();
}
I use a swing button to let the user input keypresses (press the button, then press the desired key).
This gives me two problems: first mouse is always returned as 0, however documentation says it should return -1 if nothing was pressed.
I figured this could be because of swing's button press, perhaps, but setting up a new thread which does a sleep at first doesn't work either, neither does plain discarding the first press(es) work.
Second, the keyboard detection does not seem to work at all. It does not detect any presses.
Apparently LWJGL needs to have the Display active and cannot catch keys through an active Swing window.
Related
First thing i want to do is to apologize for my english, i will try to write as understanable as possible.
Also, i have already tried to search the solution for this problem, but i didnt find one until now..
The problematic part of the code is the following:
//eventmanagement for the bat
scene.setOnKeyPressed (new EventHandler <KeyEvent> () {
public void moveBat(double speed) {
if ((speed > 0) && ((bat.getLayoutX() + bat.getWidth())<scene.getWidth())){
bat.setLayoutX(bat.getLayoutX() + speed);
}
if ((speed < 0) && ((bat.getLayoutX() > 0))){
bat.setLayoutX(bat.getLayoutX() + speed);
}
};
#Override
public void handle(KeyEvent event){
if (event.getCode().toString() == "RIGHT"){
this.moveBat(batVelocity);
}
if (event.getCode().toString() == "LEFT"){
this.moveBat(-batVelocity);
}
}
});
This thing works, but if i press the LEFT key for example, and i dont unpress it, so just let it remain pressed, then the "bat" will move left once, then delay for about 1 second, and then continue moving in the left direction.
I want to have a continuos movement in the left direction for the time the LEFT button remains pressed. Anyone has an idea how to fix this??
Thank you very much for your time and answers!!
Crutz
So, OnKeyPressed fires when a key is first pressed and then every second or so after. If you want something to happen continuously, instead of having it happen when the OnKeyPressed event fires, consider having OnKeyPressed and OnKeyReleased control some sort of boolean keyIsPressed, and using that in a while loop of some sort. So OnKeyPressed would set keyIsPressed=true and OnKeyReleased would do the opposite
So what you wanna do is save your KeyCode to a List and check it in your AnimationTimer:
Fields:
private List<KeyCode> input = new ArrayList<>();
and your listeners:
scene.setOnKeyPressed((KeyEvent event) -> {
input.add(event.getCode());
});
scene.setOnKeyReleased((KeyEvent event) -> {
input.remove(event.getCode());
});
And in your AnimationTimer:
if (input.contains(KeyCode.RIGHT)) {
//do something
}
if (input.contains(KeyCode.LEFT)) {
//do something else
}
I have a program where the user is traveling in a grid and has to kill an enemy. When they do so, a message comes up stating that the user has heard a scream.
This message is only supposed to display once when the user fires their weapon. I made the message display if the following method was true:
public boolean deadWumpus()
{
for(int x=0;x<10;x++)
{
for(int y=0;y<10;y++)
{
if(map.grid[x][y].getDeadWumpus()==true)
return true;
}
}
return false;
}
I then have a line in my paint() method which states that if this method is true then display the message. However, this keeps on displaying as there is no regulator to tell it to run only once when the user fires.
I attempted to create an int to ensure it only runs once:
// at beginning of program
int once=0;
//in paint()
if(once==0){
if(deadWumpus()==true)
{
g.drawString("You hear a scream.",300,675);
}
}
once++;
Using this it never displays the message. Is there a way I can get the message to only display once when the user shoots and then disappear once the user makes their next move?
Thanks.
The paint() method is called every time a frame of your game is drawn on the screen. When you make it drawn "only once," you made it literally draw "only once," as in, for only one frame, since frames are being update really fast, the text flashes and then never shows up again. I recommend having something like this:
long userFired;
// when the user fires -> userFired = System.currentTimeMillis();
paint() { /*the "2000" means that the text will display for 2 seconds*/
if(System.currentTimeMillis()-userFired < 2000 && deadWumpus()==true) {
g.drawString("You hear a scream.",300,675);
}
}
On the Dell Inspiron 15 3000, the touchpad doesn't have any physical left/right buttons. Instead, it is one giant touchpad that is pressure sensitive. I'm assuming it detects right/left clicks based off of hand position on the trackpad.
In my LWJGL application, I detect mouse button clicks with Mouse.isButtonDown(0). This works fine on computers with a mouse with physical buttons, but doesn't work on touchpads that lack physical buttons. Mouse.getButtonCount() returns 0.
Has anybody had any success in detecting if a mouse button is pressed, should the user be using a trackpad that doesn't have physical buttons?
I think, instead of using
org.lwjgl.input.Mouse
This class could be what you are searching for:
org.lwjgl.input.Controllers
http://legacy.lwjgl.org/javadoc/org/lwjgl/input/Controllers.html
Im not entirely sure though since I only have a mouse and no way to test this with a touchpad.
For those who find this in the future, I did find a fix:
You cannot, should there be no physical buttons, use the Mouse.isButtonDown() method. Instead, you are going to have to read the event buffer. To do so, I wrote my own helper class:
public class Mouse{
private static boolean button_left = false, button_right = false;
public static boolean isButtonDown(int button){
if(button == 0) return button_left;
if(button == 1) return button_right;
return false;
}
public static void update(){
while(org.lwjgl.input.Mouse.next()){
if(org.lwjgl.input.Mouse.getEventButton() == 0) button_left = org.lwjgl.input.Mouse.getEventButtonState();
if(org.lwjgl.input.Mouse.getEventButton() == 1) button_right = org.lwjgl.input.Mouse.getEventButtonState();
}
}
}
The update() method is called every tick, and as such I can get button states using Mouse.isButtonDown(button).
I am implementing minesweeper and I have a little problem with handling mouse events. I want actions to take place on mouseRelease (not mousePressed), so the user can change his mind after pressing a mouse button. There are three possible actions:
LMB released - reveal current field
RMB released - put a flag in current field
both LMB and RMB released - highlight or reveal adjacent fields
Actions are not really important, what I have problem with is how to trigger them.
In cases 1 and 2 no others buttons are down - this is easy to check.
The problem is that releasing both buttons results in two calls of mouseRelease method. If there is too large delay between both buttons releases I would prefer not to trigger an action. In other words, it should trigger only if both buttons were released at about the same time.
I can easily check that e.g. button 3 is down when button 1 is released, however it is not really helpful.
At the moment I have no other idea then storing a time when first button was released and then comparing it against the time when another button is released - and if the difference is small enough, trigger an action.
I do not really like an idea of playing with System.currentTimeMillis() or System.nanoTime() and I wonder whether there is a better way of doing it?
SOLUTION:
What has extremely simplified the problem was not allowing the user to drag a mouse pointer to another field (and hence changing the "selected" field). Delay between releasing both buttons does not matter. If the mouse pointer goes to another field, everything is cleared. Here is the code snippet:
private static final int B1DM = MouseEvent.BUTTON1_DOWN_MASK;
private static final int B3DM = MouseEvent.BUTTON3_DOWN_MASK;
private boolean bothWereDown = false;
#Override
public void mousePressed(MouseEvent e) {
// action if single button pressed
// in my case this is a sub-action of pressing both buttons
int both = B1DM | B3DM;
bothWereDown = (e.getModifiersEx() & both) == both;
if (bothWereDown) {
// action if both buttons pressed
}
}
#Override
public void mouseDragged(MouseEvent e) {
// some other code
if ( /* if pointer leaves field where mouse was pressed */) {
// some other code
bothWereDown = false;
// some other code
}
}
#Override
public void mouseReleased(MouseEvent e) {
// some other code
if (e.getButton() == MouseEvent.BUTTON1) {
if (bothWereDown) {
if ((e.getModifiersEx() & B3DM) != B3DM) {
// action if both released
}
} else {
// action if left button released
}
} else if (e.getButton() == MouseEvent.BUTTON3) {
if (bothWereDown) {
if ((e.getModifiersEx() & B1DM) != B1DM) {
// action if both released
}
} else {
// action if right button released
}
}
}
Obvious solution is to also track mouse presses. No need to play around with timeouts in this case, I think.
So pressing both buttons, then releasing one, will not count as release of single button. In fact, in your case, it would probably do nothing. Only when also other mouse button gets released, that will then count as releasing both buttons.
Edit: Actually, you do not even need to track mouse presses, though you probably want to give visual indication that button is pressed, and releasing it will have an effect. But when button is released, and you detect other is still pressed, just set a flag that half of two button release has happened, and single release of one button will then complete it. If flag is not set on single button release, then it's not part of two button action, and you do the single button release action instead.
I have a program in LWJGL where I have a series of buttons. I'm trying to use Mouse.getEventButton() and Mouse.getEventButtonState() in order to figure out when the mouse is released, but neither seem to be working. After adding a few print statements for debugging, it seems that getEventButton() always returns 0 regardless of what the mouse is doing, and getEventButtonState() always returns false. All other mouse methods I've used so far have behaved normally. Any idea what might be going on?
It can be done by analogy with keyboard as described in this tutorial.
while (Mouse.next()){
if (Mouse.getEventButtonState()) {
if (Mouse.getEventButton() == 0) {
System.out.println("Left button pressed");
}
}else {
if (Mouse.getEventButton() == 0) {
System.out.println("Left button released");
}
}
}