# How can I make Diagonal movement?

This is a follow-up question to my last one. I am developing a game which has an Icon on a JLabelwhich the user controls with WASD keys. Right now it can go up, down, left, and right, but I want to know how I can make it move diagonally if two keys are held. I have recreated a short example and posted it below along with a gif(sorry, it's not very smooth), and I am hoping you can help me out. Thanks!

public class Experiments extends JFrame {
javax.swing.Timer movement;
int x = 230;
int y = 120;
boolean wPressed, aPressed, sPressed, dPressed;

public Experiments() {
layoutGame();
setTitle("Example");
setSize(500, 350);
setLocationRelativeTo(null);
setVisible(true);
}

private void layoutGame() {
JLabel bg = new JLabel();
bg.setIcon(new ImageIcon(this.getClass().getClassLoader().getResource("space.png")));
add(bg, BorderLayout.CENTER);

JLabel you = new JLabel();
you.setBounds(x, y, 50, 50);
you.setIcon(new ImageIcon(this.getClass().getClassLoader().getResource("happy.png")));
bg.add(you, JLabel.CENTER);

JTextPane direction = new JTextPane();
direction.setText("Direction");
add(direction, BorderLayout.SOUTH);
move(you);

direction.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
movement.stop();
if(e.getKeyChar() == 'w') {
wPressed = true;
move(you);
} else if (e.getKeyChar() == 'a') {
aPressed = true;
move(you);
} else if (e.getKeyChar() == 's') {
sPressed = true;
move(you);
} else if (e.getKeyChar() == 'd') {
dPressed = true;
move(you);
}
direction.setText(null);
}
public void keyReleased(KeyEvent e) {
wPressed = false;
aPressed = false;
sPressed = false;
dPressed = false;
}
});
}

private void move(JLabel icon) {
int delay = 10; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if(icon.getX() >= 0 && icon.getX() <= 450 && icon.getY() >= 0 && icon.getY() <= 250) {
if (wPressed) {
y = y - 4;
} else if(aPressed) {
x = x - 4;
} else if(sPressed) {
y = y + 4;
} else if(dPressed) {
x = x + 4;
}
icon.setBounds(x, y, 50, 50);
icon.repaint();
}
}
};
movement = new javax.swing.Timer(delay, taskPerformer);
movement.start();
}

public static void main(String[] args) {
new Experiments();
}
}


The output is smooth, but I had to make a gif, so it looks bumpy(sorry again):

• What have you tried? Do you think checking wPressed and aPressed would be the logic needed to go in the up-left direction? – Cedric Martens Jul 9 '17 at 3:29
• All you really need to do is change the else if to ifs and put move(you) to the bottom. – Nathan Merrill Jul 9 '17 at 3:45
• Also, by setting all movement to 0 when ANY key is released, it's going to frustrate players. You need to check which key was released and set that isPressed value to false. – Draco18s no longer trusts SE Aug 12 '17 at 23:10

## 2 Answers

The logic is simple (as shown in the comments). You'll want to make the movement values the sum of potential values, according to which keys are pressed. However, to make the distance traveled constant, you must normalize the vector. The vector is the xy pair of movement values (e.g. <+1,0> or <-1,+1>). Normalizing means making the magnitude (length) of the vector one, to become a unit vector. To do this, you must divide each component (x and y) by it's magnitude. To calculate the magnitude, use the length formula from algebra class:

// dx and dy are the respective movement values
mag = sqrt(dx*dx + dy*dy)
dx /= mag
dy /= mag


That way, you will always move at the same speed, whether going diagonally or not.

centy = stamp('cat6',120,120,120)
centy.move//any coordinate you want.(x,y,milliseconds)

• It's not clear how this solves the problem posed in the question above. The identifier centy doesn't appear in the original question's code. Can you edit your answer to elaborate on the change you're recommending to solve the problem? – DMGregory Mar 17 '18 at 10:40