Is it a keyboard limitation problem?
I'm having an issue with some code I'm just playing around with. Imagine a top down space shooter. The issue I'm having is that, on my computer, when I press and hold the up and left arrows, I cannot shoot (Spacebar). Any other direction (up, down, left, right, up + right, right + down, left + down) works. I had a friend run the code on his computer and he found that all directions worked except up + right and right + down, but up + left worked fine for him. We both looked at the code and can't figure it out. Could this be a hardware issue?
Basically, this is what I'm doing:
import javax.swing.*;
import java.awt.event.*;
public class Test extends JFrame
{
boolean up, down, left, right, fire;
// Main constructor
public Test()
{
// listeners for user input
this.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
switch (e.getKeyCode())
{
case KeyEvent.VK_UP:
{
up = true;
break;
}
case KeyEvent.VK_LEFT:
{
left = true;
break;
}
case KeyEvent.VK_RIGHT:
{
right = true;
break;
}
case KeyEvent.VK_DOWN:
{
down = true;
break;
}
case KeyEvent.VK_SPACE:
{
fire = true;
break;
}
case KeyEvent.VK_ESCAPE:
{
// Exit
System.exit(0);
}
}
}
public void keyReleased(KeyEvent e)
{
// Upon releasing key, stop direction
switch(e.getKeyCode())
{
case KeyEvent.VK_UP:
{
up = false;
break;
}
case KeyEvent.VK_LEFT:
{
left = false;
break;
}
case KeyEvent.VK_RIGHT:
{
right = false;
break;
}
case KeyEvent.VK_DOWN:
{
down = false;
break;
}
}
}
});
}
public static void main(String[] args)
{
// create frame
Test test = new Test();
test.setLocationRelativeTo(null);
test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test.setVisible(true);
test.loop();
}
public void loop()
{
Timer timer = new Timer(250, new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if (up)
System.out.println("Moving UP.");
if (left)
System.out.println("Moving LEFT.");
if (right)
System.out.println("Moving RIGHT.");
if (down)
System.out.println("Moving DOWN.");
if (fire)
{
System.out.println("FIRING.");
fire = false;
}
}
});
timer.start();
}
}
This question was originally asked here.
Yes, it looks like a hardware limitation. You can try to check whether it behaves the same way in other programs, if yes, it's definitely a hardware issue.
Keyboards have these kinds of limitations, see Rollover (key).
Related
I've written a simple KeyListener to recognize Arrow_Left/Right Events.
For some reason my Left-Key is firering 1 VK_LEFT pressed AND 1 VK_RIGHT Event (the Right-Arrow is working normaly)
Does this have to be a Hardware / KeyBoard problem (the arrow keys are working fine) or does one know how to fix this?
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()) {
case KeyEvent.VK_LEFT: {
//left
System.out.println("leftPressed");
keyLeftPressed = true;
}
case KeyEvent.VK_RIGHT: {
//right
System.out.println("rightPressed");
keyRightPressed = true;
}
}
}
The console output on a leftClick is:
leftPressed
rightPressed
On a RightClick:
rightPressed
You forgot break statement on the case statement. If you did not break, the next case will be executed.
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()) {
case KeyEvent.VK_LEFT: {
//left
System.out.println("leftPressed");
keyLeftPressed = true;
break;
}
case KeyEvent.VK_RIGHT: {
//right
System.out.println("rightPressed");
keyRightPressed = true;
break;
}
}
}
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()) {
case KeyEvent.VK_LEFT:
//left
System.out.println("leftPressed");
keyLeftPressed = true;
break;
case KeyEvent.VK_RIGHT:
//right
System.out.println("rightPressed");
keyRightPressed = true;
break;
}
}
You use switch-case in the wrong way. The parenthesis aren't necessary, but you must add the break-statements.
I have one problem. First - I HAVE AND I WILL HAVE JUST ONE BUTTON.
My problem is: How it can be for each button click different effect-animation.
So, when I first time click on button image goes down, then I second time click image goes from left to right, then I third time click image gone and then it repeat for fourth click image goes down(I can make animation left to right, animation down and then image gone.So I know how to do animation (effects), but I just do not know how to create for every click different effect on image)...
first read about ActioListeners
then simply create a listener that uses a counter!
Each time you click the button the listener increases that counter. And you use different animations based on the current value of the counter. When the "last" animation took place - simply reset the counter to start from scratch.
Here you go
public class ButtonCycle extends JPanel {
private int counter = 0;
public ButtonCycle() {
JButton btn = new JButton("Next");
btn.addMouseListener(new MouseListener() {
#Override
public void mouseReleased(MouseEvent e) {}
#Override
public void mousePressed(MouseEvent e) {}
#Override
public void mouseClicked(MouseEvent e) {
switch(counter) {
case 0:
// "Go down"-animation code here
System.out.println("Go down");
counter++;
break;
case 1:
// "Left->right"-animation code here
System.out.println("Left->right");
counter++;
break;
case 2:
// "Disappearing"-animation code here
System.out.println("*poof*, now I'm gone");
counter = 0;
break;
}
}
#Override
public void mouseExited(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
});
add(btn);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame("Button cycling through animations");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setPreferredSize(new Dimension(250,250));
f.setContentPane(new ButtonCycle());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
}
You could utilize the java.util.Random class along with the Random.nextInt() method against values from 1 to 4 within the ActionPerformed event of your Button. Then, depending upon which value is randomly produced run a specific animation method, perhaps through a switch/case or if statements...whatever. Here is an example:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
Random rnd = new Random();
int value = (rnd.nextInt(4) + 1);
switch (value) {
case 1:
imageDown();
break;
case 2:
imageLeftRight();
break;
case 3:
imageGone();
break;
case 4:
imageUp();
break;
}
}
Or if you prefer, you could use the Math.random() method., for example:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
int value = 4 + (int)(Math.random() * (((1 - 2) - 4) + 1));
switch (value) {
case 1:
imageDown();
break;
case 2:
imageLeftRight();
break;
case 3:
imageGone();
break;
case 4:
imageUp();
break;
}
}
Of course there will be times when the random number generated will be the very much the same as the number generated previously but then again you could use a class field to hold the previous random value and if the currently generated value is the same as the previously generated value then you can generate another within perhaps a do/while loop, for example:
private int previousValue = 0;
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
int value = 0;
Random rnd = new Random();
do {
value = (rnd.nextInt(4) + 1);
} while (previousValue == value);
previousValue = value;
switch (value) {
case 1:
imageDown();
break;
case 2:
imageLeftRight();
break;
case 3:
imageGone();
break;
case 4:
imageUp();
break;
}
}
I'm working on a simple memory game where you basically match the same cards. I want the cards to be able to flip back if both didn't match. The flipping codes are the following:
mT1.unselect();
mT2.unselect();
When i put it in the else statement the cards flip back immediately so i used a handler to slow it down.
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
mT1.unselect();
mT2.unselect();
playSound( SOUND_FAILED );
}
}, 2000);
But when i test it doesn't flip back, but the sound is played after the given time. What's the problem?
Full code:
public void onPosition(int position)
{
if (position == mLastPosition)
{
return;
}
mLastPosition = position;
Tile tile = mList.get(position);
tile.select();
int sound = tile.mResId % mSounds.length;
playSound(sound);
switch (mSelectedCount)
{
case 0:
mT1 = tile;
break;
case 1:
mT2 = tile;
if (mT1.getResId() == mT2.getResId())
{
mT1.setFound(true);
mT2.setFound(true);
mFoundCount += 2;
playSound(SOUND_SUCCEED);
}
else
{
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
mT1.unselect();
mT2.unselect();
playSound( SOUND_FAILED );
}
}, 2000);
}
break;
case 2:
if (mT1.getResId() != mT2.getResId())
{
}
mSelectedCount = 0;
mT1 = tile;
break;
}
mSelectedCount++;
mMoveCount++;
updateView();
checkComplete();
}
As with your previous question, you've still not given us enough context, but I'll have a wild stab in the dark - maybe you need to call:
updateView();
in your Runnable's run() method.
Maybe if you post your updateView() method and some more context of how it works, we might be able to help more if this guess doesn't fix it.
I've made a game that is controlled by the arrow keys. Therefore I have a KeyListener listening for the arrow keys:
public void keyReleased(KeyEvent event)
{
switch(event.getExtendedKeyCode())
{
case KeyEvent.VK_UP:
gameManager.up();
break;
case KeyEvent.VK_DOWN:
gameManager.down();
break;
case KeyEvent.VK_RIGHT:
gameManager.right();
break;
case KeyEvent.VK_LEFT:
gameManager.left();
break;
}
}
Now here is my problem:
When I maximize the window using the keyboard by pressing Windows key + Up arrow, these events still get fired. How can I detect that the Windows key has been pressed, while one of the arrow keys got pressed?
Set an flag in your KeyListener, e.g.
boolean windowsPressed;
public void keyPressed(KeyEvent e) {
if(event.getExtendedKeyCode() == VK.WINDOWS) windowsPressed = true;
}
public void keyReleased(KeyEvent event)
{
switch(event.getExtendedKeyCode())
{
case KeyEvent.VK_UP:
if(!windowsPressed) gameManager.up();
break;
case KeyEvent.VK_DOWN:
gameManager.down();
break;
case KeyEvent.VK_RIGHT:
gameManager.right();
break;
case KeyEvent.VK_LEFT:
gameManager.left();
break;
case KeyEvent.VK_WINDOWS:
windowsPressed = false;
break;
}
}
You can catch the window key in your keyreleased
case: KeyEvent.VK_WINDOWS:
//do nothing
so it wont register the up button when you pressed the window + up
Hello in my game when I walk and jump, it stops everything after the jump finishes:
Can you see after a jump, it continues walking for a bit & then stops?
It should stop immediately but my walking queue continues executing because I didn't reset it, it should only reset upon keypress or release. But keypressing will stop working after i release my jump key. I think if I use 2 keys at a time and release on, the OS won't remember the old key I am still pressing. Even in your browser URL input, press and any key and hold, and then hold another key for bit & release it, it won't write the old key anymore.
Is there a fix for this? I am using keylistener, because i couldn't figure out how to find out when a key was released in KeyBinds.
This is how I do it:
public class Keyboard implements KeyListener {
private Player player;
public Keyboard(Player p) {
this.player = p;
}
#Override
public void keyPressed(KeyEvent e) {
System.out.println("yes");
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
this.player.getMovement().moveLeft();
break;
case KeyEvent.VK_RIGHT:
this.player.getMovement().moveRight();
break;
case KeyEvent.VK_SPACE:
this.player.getMovement().jump();
break;
}
}
#Override
public void keyReleased(KeyEvent e) {
int left = KeyEvent.VK_LEFT;
int right = KeyEvent.VK_RIGHT;
if (e.getKeyCode() == left || e.getKeyCode() == right) {
this.player.getMovement().stopMovement();
}
}
#Override
public void keyTyped(KeyEvent e) {
}
}
How can I fix this issue? If you need more parts of the code like the jump or walking queue, let me know.
Keylog:
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Right clicked!
Space is a nice button
Remember process all the keypresses in a separate Thread.
http://wiki.processing.org/w/Multiple_key_presses
Method #1
/**
multiplekeys taken from http://wiki.processing.org/index.php?title=Keep_track_of_multiple_key_presses
#author Yonas Sandbæk http://seltar.wliia.org
*/
// usage:
// if(checkKey("ctrl") && checkKey("s")) println("CTRL+S");
boolean[] keys = new boolean[526];
void draw(){}
boolean checkKey(String k)
{
for(int i = 0; i < keys.length; i++)
if(KeyEvent.getKeyText(i).toLowerCase().equals(k.toLowerCase())) return keys[i];
return false;
}
void keyPressed()
{
keys[keyCode] = true;
println(KeyEvent.getKeyText(keyCode));
}
void keyReleased()
{
keys[keyCode] = false;
}
Methord #2 (And a simpler way of doing this just checking a few keys (without an array))
boolean keyup = false;
boolean keyright = false;
boolean keyleft = false;
boolean keydown = false;
float x,y;
void setup() {
size(640,360);
x = width/2;
y = height/2;
}
void draw() {
background(51);
fill(255);
ellipse(x,y,16,16);
if (keyup) y--;
if (keydown) y++;
if (keyleft) x--;
if (keyright) x++;
}
void keyPressed() {
if (key == CODED) {
if (keyCode == UP) keyup = true;
if (keyCode == DOWN) keydown = true;
if (keyCode == LEFT) keyleft = true;
if (keyCode == RIGHT) keyright = true;
}
}
void keyReleased() {
if (key == CODED) {
if (keyCode == UP) keyup = false;
if (keyCode == DOWN) keydown = false;
if (keyCode == LEFT) keyleft = false;
if (keyCode == RIGHT) keyright = false;
}
}
Method #3
/**
Modified version of Option 1 multiplekeys (should provide improved performance and accuracy)
#author Yonas Sandbæk http://seltar.wliia.org (modified by jeffg)
*/
// usage:
// if(checkKey(KeyEvent.VK_CONTROL) && checkKey(KeyEvent.VK_S)) println("CTRL+S");
boolean[] keys = new boolean[526];
void draw(){}
boolean checkKey(int k)
{
if (keys.length >= k) {
return keys[k];
}
return false;
}
void keyPressed()
{
keys[keyCode] = true;
println(KeyEvent.getKeyText(keyCode));
if(checkKey(CONTROL) && checkKey(KeyEvent.VK_S)) println("CTRL+S");
}
void keyReleased()
{
keys[keyCode] = false;
}
Method #5
/**
* Snappier multiple key detection using Primitive Collections Classes for Java http://pcj.sourceforge.net/
* (standard Java Collection Objects can be used instead)
* #author analogAI http://recursivepath.com/analogAI/
*/
// usage:
// if(this.checkKeysHeld(KeyEvent.VK_CONTROL) && this.checkKeysHeld(KeyEvent.VK_S)) println("CTRL+S");
import bak.pcj.set.IntSet;
import bak.pcj.set.IntOpenHashSet;
public class HelloWorld extends PApplet {
public IntSet keysheld = new IntOpenHashSet();
/**
* #param keycode key integer code, the value are constants defined in KeyEvent Class
* http://java.sun.com/j2se/1.4.2/docs/api/java/awt/event/KeyEvent.html
* e.g. KeyEvent.VK_A for letter A
* KeyEvent.VK_0 for number 0
* KeyEvent.VK_SHIFT for shift button
* #return true if the key is currently held down, false otherwise
*/
public boolean checkKeysHeld(int keycode){
return this.keysheld.contains(keycode);
}
public void keyPressed(){
// add key to the list of keys held down
// with processing, the KeyEvent object is always available as "keyEvent",
// the getKeyChar() is already in the variable 'key', and getKeyCode() is in the variable 'keyCode'.
this.keysheld.add(this.keyEvent.getKeyCode());
println("key pressed: "+KeyEvent.getKeyText(this.keyEvent.getKeyCode()));
println("keys in current held list: "+this.keysheld.toString());
}
public void keyReleased(){
// remove key from the list of keys held down
this.keysheld.remove(this.keyEvent.getKeyCode());
}
}