Strange behaviour at the beginning of the game

Hello, in my game, player doesn’t start to move constantly. For example:
X coordinates:
100 (position before movement)
104 (start to move)
160 ???
164
168
etc…

Why it suddenly jump from 104 to 160? Here is my code:

	
	private void addListeners(){
		setFocusable(true);
		addKeyListener(new KeyListener(){

			@Override
			public void keyPressed(KeyEvent e) {
				pressed.add(e.getKeyChar());
				System.out.println("KEY");
				if(isKeyDown == false){
					for(Character c : pressed){
						//System.out.print("X : "+player.getX());
						//System.out.println(" Y : "+player.getY());
						
						if(c == 'w' && player.getY()+-1*SPEED > 10){
							speedY = -1*SPEED;
						}if(c == 's' && player.getY()+SPEED < 640){
							speedY = SPEED;
						}if(c == 'a' && player.getX()+-1*SPEED > 10){
							speedX = -1*SPEED;
						}if(c == 'd' && player.getX()+SPEED < 1190){
							speedX = SPEED;
						}
						isKeyDown = true;
					}
				}
				
			}

			@Override
			public void keyReleased(KeyEvent e) {
				pressed.remove(e.getKeyChar());
				int key = e.getKeyCode();
				if(key == KeyEvent.VK_W || key == KeyEvent.VK_S){
					speedY = 0;
				}
				if(key == KeyEvent.VK_A || key == KeyEvent.VK_D){
					speedX = 0;
				}
			}

			@Override
			public void keyTyped(KeyEvent arg0) {
				// TODO Auto-generated method stub
				
			}
			
		});
	}
	
	private void update(){
		System.out.println("UPDATE");
		player.setX(player.getX()+speedX);
		player.setY(player.getY()+speedY);
	}
	
//Timer 20ms
	@Override
	public void actionPerformed(ActionEvent arg0) {
		update();
		repaint();
		isKeyDown = false;
	}

Actually, in player movement, I don’t see that jump. But coordinates jump at the beginning and that makes it impossible to make good collision detection. What’s wrong here?

  1. Do you change that SPEED variable somewhere?

  2. i’m not quite sure why you do this:

if(c == 'w' && player.getY()+-1*SPEED > 10)

this just checks if there is a collision at the beginning of the movement? so you could basically just run out of that rectangle you made up for collisions (if you don’t stop when you touch it and just keep “w” pressed) cause it just gets checked when you press w and not everytime it changes the position.

No, I don’t change it anywhere. Im trying to fix this maybe 7 hours. I tried a lot of things. What I discovered, is that this jump when I click the button very first time, I tried to block that first push, it worked, but then the movement looked very unnatural and the problem still occured when I pressed two buttons in a row(for example left + up). And the collision doesn’t work too. Im so exhausted from this. I would really appreciate if you could help me to achieve what I want: Nice looking movement(I can achieve this) but without that first big jump, which destroys all collision detection.

public Game(){
		initiateImages();
		startGame();
		addListeners();
	}
	
	public void startGame(){
		timer = new Timer(15,this);
		timer.start();
	}
	
	private void addListeners(){
		setFocusable(true);
		addKeyListener(new KeyListener(){

			@Override
			public void keyPressed(KeyEvent e) {
				pressed.add(e.getKeyChar());
				for(Character c : pressed){
					if(c == 'w'){
						speedY = -SPEED;
					}else if(c == 's'){
						speedY = SPEED;
					}else if(c == 'a'){
						speedX = -SPEED;
					}else if(c == 'd'){
						speedX = SPEED;
					}
				}
			}

			@Override
			public void keyReleased(KeyEvent e) {
				pressed.remove(e.getKeyChar());
				if(e.getKeyChar()== 'w' || e.getKeyChar() == 's'){
					speedY = 0;
				}
				if(e.getKeyChar()== 'a' || e.getKeyChar() == 'd'){
					speedX = 0;
				}
			}

			@Override
			public void keyTyped(KeyEvent arg0) {
				// TODO Auto-generated method stub
				
			}
			
		});
	}
	
	private void initiateImages(){
		court = new ImageIcon("images/court2.jpg").getImage();
		ball = new Ball();
		player = new Player();
	}
	
	private void update(){
		if(player.getX()+speedX>10 || player.getX()+speedX<1190){
			player.setX(player.getX()+speedX);
		}
		if(player.getY()+speedY>10 || player.getY()+speedY<640){
			player.setY(player.getY()+speedY);
		}
	}
	
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		
		//Draws background image
		g.drawImage(court, 0, 0, null);
		
		// Creates graphics2D object for rendering hints
		Graphics2D g2d = (Graphics2D)g.create();
		
		// Sets rendering hints.
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
		
		// Draws results
		g2d.setFont(new Font("Serif",Font.BOLD, 36));
		g2d.setColor(Color.WHITE);
		g2d.drawString("Green 0 : 0 Yellow", 40, 40);
		
		// Draws ball and player
		g2d.setFont(new Font("Serif",Font.BOLD, 20));
		g2d.drawImage(ball.getBall(),ball.getX(), ball.getY(),null);
		g2d.drawImage(player.getPlayer(),player.getX(),player.getY(),null);
		g2d.drawString("13",player.getX()+10,player.getY()+25);
	}

	@Override
	public void actionPerformed(ActionEvent arg0) {
		update();
		repaint();
	}

}

This code achieves smooth moves, but that big jump at the beginning(probably because of delay in key presses) are ruining everything.

delayed Key pressing shouldn’t be the problem, that would just make the animation delayed too, not make it jump, i guess something with the time might be wrong so that it gets activated too often. Maybe the KeyPressed Event activates the ActionEvent too?

I’m betting this is an artifact of the Swing timer. It’s hard to say for sure since you don’t show us the imports or extends/implements for your code. There seem to be omitted instance variable declarations as well.

You say that the images appear to move smoothly/correctly. The Swing timer puts the execution of the code on the Event Dispatch Thread (EDT). Maybe, uh…(160-104)/4 = 16 cycles have elapsed and are queued up on the EDT by the time you are inspecting the location variables. There are rules for “collapsing” the contents of the EDT that are a bit too obscure for me to try and figure out if and how they pertain or not.

In general, I think it’s better to use a more normal game loop, or use the util Timer, than the swing Timer anyway. The EDT can easily get clogged if you try to accomplish both rendering and game state calculations.

I’d put all the listeners in place BEFORE kicking off the start of the game.

Hard for me to know if this is the right answer though. My understanding of your code is kind of weak, and I tend to avoid the use of the Swing Timer. Maybe you are using a game loop mechanism that is unseen in your code fragment?

@philfrei was right, I’ve experienced this before. Changing the gameloop with the one at DeWitters article, worked for me.