Reputation: 37
I have a problem in my code, because i don't know how to make picture move diagonal when you press ARROW UP and ARROW LEFT at the same time, etc.. Here is my code:
public void keyPressed(KeyEvent ke) {
switch (ke.getKeyCode()) {
case KeyEvent.VK_RIGHT: {
cordX += 5;
}
break;
case KeyEvent.VK_LEFT: {
cordX -= 5;
}
break;
case KeyEvent.VK_DOWN: {
cordY += 5;
}
break;
case KeyEvent.VK_UP: {
cordY -= 3;
}
break;
}
repaint();
}
I don't know if this would work
case KeyEvent.VK_UP && KeyEvent.VK_LEFT: {
cordY += 5;
}
break;
Upvotes: 0
Views: 74
Reputation: 347244
If you are using Swing components, use the Key Bindings API, see How to Use Key Bindings, it will solve a rafter of issues...
In any case, the solution is (basically) the same, what you need to do is define a series of flags which define which keys are currently pressed and at a regular interval update the state of the variables affected by those flags
private boolean down, up, left, right;
//...
public void keyPressed(KeyEvent ke) {
switch (ke.getKeyCode()) {
case KeyEvent.VK_RIGHT:
right = true;
break;
case KeyEvent.VK_LEFT:
left = true;
break;
case KeyEvent.VK_DOWN:
down = true;
break;
case KeyEvent.VK_UP:
up = true;
break;
}
updateState();
}
public void keyReleased(KeyEvent ke) {
switch (ke.getKeyCode()) {
case KeyEvent.VK_RIGHT:
right = false;
break;
case KeyEvent.VK_LEFT:
left = false;
break;
case KeyEvent.VK_DOWN:
down = false;
break;
case KeyEvent.VK_UP:
up = false;
break;
}
updateState();
}
protected void updateState() {
if (right) {
cordX += 5;
} else if (left) {
cordX -= 5;
}
if (down) {
cordY += 5;
} else if (up) {
cordY -= 3;
}
repaint();
}
You could then use a javax.swing.Timer
to schedule a regular call back, which could be used to call updateState
(instead of calling it from the key event handlers).
Have a look at How to use Swing Timers for more details...
Upvotes: 4
Reputation: 810
You can use a Timer.
public class MyClass extends KeyAdapter implements ActionListener {
private Timer timer; //this timer will update your object's position
private int vx = 0; //these values indicate your objects velocity
private int vy = 0; //they are updated as your arrow keys are pressed
public MyClass() {
this.timer = new Timer(100 /*the delay*/, this/*the listener*/);
//the delay indicated how frequently you want to update your position, i chose 100ms, you may chose a different number
}
@Override public void keyPressed(KeyEvent ke) {
switch (ke.getKeyCode()) {
case KeyEvent.VK_RIGHT:
vx = 5;
break;
case KeyEvent.VK_LEFT:
vx = -5;
break;
case KeyEvent.VK_DOWN:
vy = 5;
break;
case KeyEvent.VK_UP:
vy = -3;
break;
}
this.timer.start(); //start your timer when a key is pressed (will do nothing if it's already running)
}
//obviously, you will need to stop your objects once the keys are released.
@Override public void keyReleased(KeyEvent ke) {
switch(ke.getKeyCode()) {
case KeyEvent.VK_RIGHT:
vx = 0;
break;
case KeyEvent.VK_LEFT:
vx = 0;
break;
case KeyEvent.VK_DOWN:
vy = 0;
break;
case KeyEvent.VK_UP:
vy = 0;
break;
}
if(vx == 0 && vy == 0) this.timer.stop(); //no need to run the timer if no key is down
}
//this will be called regularly by the timer
@Override public void actionPerformed(ActionEvent ae) {
cordX += vx; //you just update the positions
cordY += vy; //according to your variables
repaint(); //then repaint
}
}
Edit: You can optimize this to avoid weird behaviour when (for example) both left and right key are pressed.
Upvotes: 0