I have a simple Mario game and have key events that decide different animations and movements of the player.
They are:
Move Left
Move Right
Jump Left
Jump Right
As you can imagine, the player will only be able to play the jump right animation if he is moving right and is/has pressed the jump button
The issue I have come across is that only 1 key value may be sent at once. This makes if statements with && conditions useless.
Here was the code that did not work:
if(key == KeyEvent.VK_LEFT) {
if(distanceTraveled<300)dx=-5; else dx=-4;
if(key == KeyEvent.VK_UP)
player = jump_L_anim.getImage();
else
player = walk_L_anim.getImage();
} else {
if(distanceTraveled<300)dx=5; else dx=4;
if(key == KeyEvent.VK_UP)
player = jump_R_anim.getImage();
else
player = walk_R_anim.getImage();
}
Simple enough, I realized that there are solutions to this and began attempting to figure out the key pressed before the current one.(this key could not be equal to the one currently pressed).
This would allow an if statement such as
if key==right && lastKey == up
run jump_R animation
I managed to be able to grab the last key, but not the last key that was not a repeat.
I felt really confused and decided to watch this missile guidance for dummies video. That made me even more confused, In my boring accounting class I figured out the solution must be to store all previous values in an array, then I would loop through the values from the last to the beginning. I would continue this until the numbers would not continue. The number where the repetition stops is the last value i am looking for.
For anyone confused by this take a look at these console readings of key movements
48
48
48
49
49
49
49
47
47
47
The number I am looking for in this situation is 49. That is because it was the last key pressed that is not the current key.
Is my logic behind this issue correct? How would you solve this issue? I prefer not working with arrays if there is a simple variable only solution available. I am looking for the fastest and most efficient logic.
Perhaps you can store which keys are held down at the moment into an HashSet, and the if statement would be something like:
if (keyCodeSet.contains(x) && keyCodeSet.contains(y))
where x and y are the key numbers you want. When the keys are released, you simply remove them from the set.
You should keep track of when the keys are released. If up is never released, you know it's still being held. If right is never released, you know it's still being held. Each update, you can check if both are down and react accordingly.
It's actually totally simple:
Listen to both keyPressed and keyReleased
use a Set<Key>1 or just 4 variable for the keys you're interested in
when a key gets pressed set, add it to the set
when a key gets released, remove it
On any key press, check if the other key is there. This way you can distinguish "Up+Right" from "Right+Up" if you want to.
1 Key may be Integer or whatever representation you prefer.
I am making a simple game(my first time using key reader) and am using WASD inputs to move the character. I want to make it so that if you press, say, W and A at the same time, you go diagonal. Does anyone know how to do this?
Don't use a KeyListener. Swing was designed to be used with Key Bindings.
Either way you can't listen for multiple keys at once so you need to keep track of which keys have been pressed. Since you want to do animation you would generally use a Swing Timer to schedule the animation. Then every time the Timer fires you check which keys are pressed and move you character based on the keys pressed.
Check out KeyboardAnimation.java source code from Motion Using The Keyboard for an example that demonstrates this approach. This article also gives reasons why key bindings are preferred over a KeyListener.
Filemaker (and, I am given to understand, Amigas) have a popup menu which is different to the JPopup, or the SWT.POPUP in this wise:
It appears when you mousedown over the (say) textfield that holds the currently-selected value.
The selection highlight moves with the mouse pointer as it is dragged.
When you exit (by mouse up) the selection is set to be the item the mouse is over.
If the mouse is not over an item (ie you have exited the menu still dragging) the selected value remains unchanged.
It makes selection from a limited set of options very quick and easy.
Does anyone know of a java implementation that functions this way?
EDIT:
https://stackoverflow.com/questions/13782365/swt-popup-menu-rant-some-code?rq=1
Contains a pretty good implementation of the idea, and I'm happy to take it and work it into my solution.
https://stackoverflow.com/questions/13782365/swt-popup-menu-rant-some-code?rq=1
Contains a pretty good implementation of the idea, and I'm happy to take it and work it into my solution.
So, I converted a game to Slick2D. The movement is broke, and I am at a loss. Before, we used KeyPressed and keyReleased methods, but now with Slick2D movement isn't working right.
Yea, nothing has gone right with converting to Slick2D. First the launcher, which I had a help topic on before, and now this. Though, the other topic was an issue with WebStart hating code.
You can only move right, using A. And you can't stop moving. Am I using the right methods? How can I fix it? Any help is greatly appreciated!
Here is a PasteBin link to the code, if it helps! http://pastebin.com/GRH86Yuw
I'm a fan of Slick, and I'd be happy to help.
The fundamental difference is that Slick is a polling model, not an event-driven model when it comes to input. Basically, in your logic update method you loop through the keys bound to your events, and check to see if any of the keys are currently pressed, and then trigger those events. For a number of reasons that I can go into if you like, polling tends to work better for games, especially with a large number of keys. It's just a different way of doing things, an not that complicated. The biggest upside is that you get centralized input processing a single method, instead of having it spread across multiple KeyListener instance objects.
If you want to look at Pedestrians - a simple pedestrian sim implemented in Slick - you can see an example of how to handle input in Slick.
Specifically, I handle input in this file (lines 192-295), inside the processInput method. Basically, you pass in a reference to the GameContainer object (the Slick object that contains your game), and from that you can get an instance to the Input instance that will allow you to check which keys are pressed, what mouse buttons are clicked, etc.
When I press "Delete" button on the keyboard, program gets three events - KEY_PRESSED, KEY_TYPED, and KEY_RELEASED. The problem is, in KEY_PRESSED and KEY_RELEASED, parameter "keyCode" is set, but in the KEY_TYPED it is not (in fact, there no meaningful info in that event). With F5 key, it is even funnier - KEY_PRESSED and KEY_RELEASED are registered, but KEY_TYPED never occurs.
The listener was added via Toolkit.getDefaultToolkit().addAWTEventListener(). Using JDK 6.26.
What could be my problem?
EDIT:
Here are the events that happen when Delete key is pressed:
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=127,keyText=Delete,keyChar=Delete,keyLocation=KEY_LOCATION_STANDARD,rawCode=119,primaryLevelUnicode=127,scancode=0] on javax.swing.JButton[,0,0,61x30,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.synth.SynthBorder#50f38cf0,flags=288,maximumSize=,minimumSize=,preferredSize=,defaultIcon=javax.swing.ImageIcon#6ae2d0b2,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=SVG,defaultCapable=false]
java.awt.event.KeyEvent[KEY_TYPED,keyCode=0,keyText=Unknown keyCode: 0x0,keyChar=Delete,keyLocation=KEY_LOCATION_UNKNOWN,rawCode=0,primaryLevelUnicode=127,scancode=0] on javax.swing.JButton[,0,0,61x30,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.synth.SynthBorder#50f38cf0,flags=288,maximumSize=,minimumSize=,preferredSize=,defaultIcon=javax.swing.ImageIcon#6ae2d0b2,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=SVG,defaultCapable=false]
java.awt.event.KeyEvent[KEY_RELEASED,keyCode=127,keyText=Delete,keyChar=Delete,keyLocation=KEY_LOCATION_STANDARD,rawCode=119,primaryLevelUnicode=127,scancode=0] on javax.swing.JButton[,0,0,61x30,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.synth.SynthBorder#50f38cf0,flags=288,maximumSize=,minimumSize=,preferredSize=,defaultIcon=javax.swing.ImageIcon#6ae2d0b2,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=SVG,defaultCapable=false]
better would be implements KeyBindings
part of keyboard are reserved Keys for built-in JComponent funcionality, more informations from #camickrs UIManager Defaults
depends of reason(s) why you needed implents KeyListener, because for there are lots of another Listeners for various JComponent, that should be filtering or register text changes inside
some of JComponent Models generated Events from Mouse and Keyboard input
From the JavaDoc The "key typed" event. This event is generated when a character is entered. In the simplest case, it is produced by a single key press. Often, however, characters are produced by series of key presses, and the mapping from key pressed events to key typed events may be many-to-one or many-to-many.
You are trying to get the F5 key which is probably not registered as a character being entered. By using the KEY_RELEASED you will consistently get the result you are looking for and the API is behaving as expected.
Key typed events ALWAYS generate '0' as the key code. Look up the method getKeyChar() instead, or (as has been suggested) listen for keyReleased() instead.
getKeyChar(): http://goo.gl/ajH03