I'm making a small game project in Java. In it you have a character that shoots in the direction of the mouse when "pressed" or "dragged" (you know, in Java's terms). The only problem is that if you stop dragging but you still hold the left mouse button down you stop shooting.
Is there a way to detect if the mouse button is down after a drag?
NOTE: the mouse is not sensed as "pressed" after the drag.
You will get the information when a mouse button is pressed and when it is released again. If you want to know the state in between, you need to use a boolean to store that information.
Example:
final boolean[] buttonStates = new boolean[3];
public void mousePressed(MouseEvent e) {
buttonStates[e.getButton()] = true;
}
public void mouseReleased(MouseEvent e) {
buttonStates[e.getButton()] = false;
}
You would do the same for keyboard input by the way.
Related
I would like to be able to have background input in Java. I set up the keyboard listener the usual way (I think). This code works fine, but whenever the program loses focus, the keys stop updating. The update method is ran 60 times a second and continues to be ran while the frame is out of focus, but the keys don't update (If a key is pressed when the frame loses focus, the program will act as if you are holding it down).
My question: is there a way to allow Java to receive background inputs when the frame is out of focus? I would prefer a solution without external libraries but any will help.
The reason I would like to do this is because my program will have multiple frames and I need to be able to receive input in the main frame even if it is not in focus, including when none of the frames are in focus.
Not sure how helpful it will be but my current code for listening for key events is below.
Here I add the key listener to my main class.
public static Keyboard key;
key = new Keyboard();
addKeyListener(key);
This code is from my Keyboard class
private boolean[] keys = new boolean[120];
public boolean up, down, left, right;
public void update() {
up = keys[KeyEvent.VK_UP] || keys[KeyEvent.VK_W];
down = keys[KeyEvent.VK_DOWN] || keys[KeyEvent.VK_S];
left = keys[KeyEvent.VK_LEFT] || keys[KeyEvent.VK_A];
right = keys[KeyEvent.VK_RIGHT] || keys[KeyEvent.VK_D];
}
public void keyPressed(KeyEvent e) {
keys[e.getKeyCode()] = true;
}
public void keyReleased(KeyEvent e) {
keys[e.getKeyCode()] = false;
}
Is there a way to figure out the first drag movement of the mouse in Java?
For example:
public void mouseDragged(MouseEvent e)
{
if (first drag of the mouse) // what should I write here?
System.out.println("This is the first drag");
else System.out.println("This isn't the first drag");
}
If I drag the mouse 5 times I should see this text in the console:
This is the first drag
This isn't the first drag
This isn't the first drag
This isn't the first drag
This isn't the first drag
boolean first=true;//this should be a instance variable.
first drag! use a boolean variable to detect first or not.like this
public void mouseDragged(MouseEvent e)
{
if (first) { // this is only true if it's first drag
System.out.println("This is the first drag");
first=false;
}
else {
System.out.println("This isn't the first drag");
}
}
update...
this is how u can detect is it first drag.but there are a problem normally mouse drag event triggered while dragging.to avoid this u can modify this little bit.
declare instance variables
boolean draging = true;
boolean mark = true;
boolean first = true;
print only when dragging start.when we print mouse dragging we stop printing it until mouse released and redragging.
public void mouseDragged(java.awt.event.MouseEvent evt) {
draging = true;
if (mark) {
if (first) {
System.out.println("This is the first drag");
}else{
System.out.println("This isn't the first drag");
}
mark = false;
}
}
change first to false so first dragging is enough.and ready for print new drag[mark = true]
public void mouseReleased(java.awt.event.MouseEvent evt) {
if (draging) {
mark = true;
first=false;
}
}
this is the output of 1st and updated examples.there is a problem of 1st code [because event drag is triggered continuously while dragging ,not ones].
first example
This is the first drag
This is the first drag
This is the first drag
.............................//this continues until u finish[released] first drag
This isn't the first drag
This isn't the first drag
This isn't the first drag
................................
updated one
This is the first drag //a drag [ click--move--relesed] mark only 1time
This isn't the first drag
This isn't the first drag
This isn't the first drag
...............................
I would modify FastSnails solution to this slightly to get around the behaviour that mouseDragged fires on every mouse movement while the button is down:
boolean first = true;
boolean triggered = false;
public void mouseDragged(MouseEvent e){
if(!triggered){
if(first){
System.out.println("This is the first drag");
first=false;
}
else{
System.out.println("This isn't the first drag");
}
triggered = true;
}
}
Of course, we then have to reset that flag in a mouseReleased event, which signals the end of the "drag":
public void mouseReleased(MouseEvent e){
triggered = false;
}
Using this method means that the message only gets triggered once per "drag", rather than at every mouse movement.
I'm trying to stop the tree from collapsing or expanding when the user double clicks a column on a tree. It should only be allowed if the user clicks on the first column.
See, if a user double clicks the checkbox on node2 world1, the tree expands or collapses. I don't want that to happen. My tree needs SWT.FULL_SELECTION to detect the clicks on each of the columns, so that's not the way to go.
My listener looks like this
tree.addTreeListener(new TreeListener() {
#Override
public void treeExpanded(TreeEvent e) {
TreeItem parent = (TreeItem) e.item;
Point p = new Point (e.x, e.y);
int column = CheckboxClickListener.getColumn(p,parent);
if (column > 0) {
e.doit = false;
}
}
#Override
public void treeCollapsed(TreeEvent e) {
TreeItem parent = (TreeItem) e.item;
Point p = new Point (e.x, e.y);
int column = CheckboxClickListener.getColumn(p,parent);
if (column != 0) {
e.doit = false;
}
}
});
Problem is, the mouse event that generated the click is not the same as the TreeEvent that expands the tree. Thus, the e.x and e.y are both zero, making my Point detection useless. Listening to the mouse event and maintaining the last x and y to check here in the TreeExpand event seems bug-prone since the user may also expand the tree using the keyboard (thus the x and y may not reflect the user action). I also considered adding a time constraint to check that but seems like a bad way to handle the issue.
How can I detect which mouse event triggered the expand event?
PS: e.doit=false does nothing, even outside the if condition, so help with stopping the tree from expanding/collapsing would be appreciated as well :)
Thank you!
I found someone saying this is a bug at this link http://www.eclipse.org/forums/index.php/t/257325/
The following code stops the tree from expanding on doubleclick but I'm not sure why or what are the side effects.
tree.addListener (SWT.MeasureItem, new Listener(){
#Override
public void handleEvent(Event event) {}
});
This stops the expanding when doubleclicking ANY column. Clicking on the small arrow at the left of the TreeItem still expands the tree (as it should).
I want my app to detect mouse clicks anywhere on the screen without having to have the app focused. I want it to detect mouse events universally even if its minimized. So far I've only been able to detect mouse events within a swing gui.
Autohotkey can detect mouse clicks and get the mouse's position at any time, how can I do this with java?
It is possible with a little trick. Should be 100% cross-platform (tested on Linux & Windows). Basically, you create a small JWindow, make it "alwaysOnTop" and move it around with the mouse using a timer.
Then, you can record the click, dismiss the window and forward the click to the actual receiver using the Robot class.
Short left and right clicks work completely fine in my tests.
You could also simulate dragging and click-and-hold, just forwarding that seems harder.
I have code for this, but it is in my Java extension (JavaX). JavaX does translate into Java source code, so you can check out the example here.
The code in JavaX:
static int windowSize = 11; // odd should look nice. Set to 1 for an invisible window
static int clickDelay = 0; // Delay in ms between closing window and forwarding click. 0 seems to work fine.
static int trackingSpeed = 10; // How often to move the window (ms)
p {
final new JWindow window;
window.setSize(windowSize, windowSize);
window.setVisible(true);
window.setAlwaysOnTop(true);
JPanel panel = singleColorPanel(Color.red);
window.setContentPane(panel);
revalidate(window);
final new Robot robot;
panel.addMouseListener(new MouseAdapter {
// public void mousePressed(final MouseEvent e) {}
public void mouseReleased(final MouseEvent e) {
print("release! " + e);
window.setVisible(false);
int b = e.getButton();
final int mod =
b == 1 ? InputEvent.BUTTON1_DOWN_MASK
: b == 2 ? InputEvent.BUTTON2_DOWN_MASK
: InputEvent.BUTTON3_DOWN_MASK;
swingLater(clickDelay, r {
print("clicking " + mod);
robot.mousePress(mod);
robot.mouseRelease(mod);
});
}
});
swingEvery(window, trackingSpeed, r {
Point p = getMouseLocation();
window.setLocation(p.x-windowSize/2, p.y-windowSize/2);
//print("moving");
});
}
I'm working on a Java 2D game which requires a max of six keys be held down at the same time.
The game is for two players on the same keyboard, playing simultaneously.
However, all three computers I ran the program on only allow a max of three keys held at a time. They all have trouble with reacting to more than three keys being held.
It seems that pressing a new key after three are already held, either cancels some other key-holding or is ignored.
I've been told that this is a hardware issue. Most keyboards can't handle more than three keys held at a time. But a lot of games do require this, and they do not require special gaming-keyboards to run on my computer without problems.
So there has to be a solution that will make the game playable on any standard keyboard.
If there is, could you please explain to me how to code it in my program?
(I use Key Bindings).
The game's controls:
Player 1
Rotate sprite and set angle of movement: LEFT arrow
Rotate sprite and set angle of movement: RIGHT arrow
Move forward: UP arrow
Shoot missile: ENTER key
Player 2
Rotate sprite and set angle of movement: 'A' key
Rotate sprite and set angle of movement: 'D' key
Move forward: 'W' key
Shoot missile: 'T' key
Relevant code:
The Key Bindings part:
// An action for every key-press.
// Each action sets a flag indicating the key is pressed.
leftAction = new AbstractAction(){
public void actionPerformed(ActionEvent e){
keysPressed1[0] = true;
}
};
rightAction = new AbstractAction(){
public void actionPerformed(ActionEvent e){
keysPressed1[1] = true;
}
};
// And so on...
// ....
// An action for every key-release.
// Each action sets a flag indicating the key was released.
// This is only necessary for some of the keys.
leftReleased = new AbstractAction(){
public void actionPerformed(ActionEvent e){
keysPressed1[0] = false;
}
};
rightReleased = new AbstractAction(){
public void actionPerformed(ActionEvent e){
keysPressed1[1] = false;
}
};
// And so on...
// ....
// Binding the keys to the actions.
inputMap.put(KeyStroke.getKeyStroke("UP"),"upAction");
inputMap.put(KeyStroke.getKeyStroke("LEFT"),"leftAction");
// etc...
actionMap.put("upAction",upAction);
actionMap.put("leftAction",leftAction);
// etc...
In the Board class. It has most of the game's code.
This part checks the flags and reacts to key presses and releases.
keysPressed1 = tank1.getKeys(); // get flags-array of tank1.
keysPressed2 = tank2.getKeys(); // get flags-array of tank2.
if(keysPressed1[0]==true) // if LEFT is pressed.
tank1.setAngle(tank1.getAngle()-3);
if(keysPressed1[1]==true) // if RIGHT is pressed.
tank1.setAngle(tank1.getAngle()+3);
if(keysPressed1[2]==true){ // if UP is pressed.
tank1.setDX(2 * Math.cos(Math.toRadians(tank1.getAngle())));
tank1.setDY(2 * Math.sin(Math.toRadians(tank1.getAngle())));
}
if(keysPressed1[2]==false){ // if UP is released.
tank1.setDX(0);
tank1.setDY(0);
}
// And the same for the second player's keys...
This is mostly how reacting to key-presses and key-releases works in my program. When a key is pressed or released, a flag is set. The Board class reades the flags every game-loop cycle and reacts accordingly.
As I said, the program doesn't react correctly to more than 3 keys held at a time, probably because of the keyboard. Is there a way to code a solution?
Help will be very appreciated.
Thanks a lot
Are you sure you're not experiencing ghosting? If it is ghosting, it's a hardware limitation.
Here is a tester -> http://www.microsoft.com/appliedsciences/content/projects/KeyboardGhostingDemo.aspx
And here is a description of ghosting -> http://www.microsoft.com/appliedsciences/antighostingexplained.mspx
I'm not very familiar with this topic, but doing some research I stumbled upon LWJGL. It's a Java game library and looks pretty promising, according to your problem. Take a look at this.