title: How to add smooth movement to my java game?
body: <p>my goal: in something like the pong, key controls should move bats smoothly.</p>
  <p>expectation: want the bats to move smoothly up or down with keys.
  actual results: <strong>bats move like lagging or change in speed.</strong></p>
  <p>I tried using velocity vars with maybe lerp, but they lag.
  I tried Increasing and reducing y value, but it lags worse.
  I searched, but can't find a solution.</p>
  <p>I am calling <strong>rectangles bats and circle pong.</strong>
  also, this is my <strong>first day and post</strong> here.</p>
  <p><a href="https://i.stack.imgur.com/4GZrL.png" rel="nofollow noreferrer">Screenshot from the game</a></p>
  <p>here is the panal code:</p>
  <pre><code>import java.awt.Dimension;
  import java.awt.Font;
  import java.awt.Graphics;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.awt.event.KeyAdapter;
  import java.awt.event.KeyEvent;
  import java.util.Random;
  
  import javax.swing.JPanel;
  import javax.swing.Timer;
  
  public class gamePanel extends JPanel implements ActionListener {
  
      /**
       * 
       */
      private static final long serialVersionUID = 6350159535293799269L;
      static final int SCREEN_WIDTH = 840;
      static final int SCREEN_HEIGHT = 610;
      static final int PONG_SPAWN_FRAME = 50;
      static final int padding = 30;
  
      
      
      static final int pongSize = 30;
      static final int batHeight = SCREEN_HEIGHT / 4;
      static final int batWidth = SCREEN_WIDTH / 32;
      static final int batSpeed = 4;
      static final int pongSpeed = 3;
      static final int scoreTextSize = 45;
      
      boolean running = false;
      
      int redX = padding;
      int redY = SCREEN_HEIGHT / 2;
      int redVelocity = 0;
  
      int blueX = SCREEN_WIDTH - padding;
      int blueY = SCREEN_HEIGHT / 2;
      int blueVelocity = 0;
  
      int redPoints = 0;
      int bluePoints = 0;
  
      int pongX = SCREEN_WIDTH / 4 - pongSize / 2;
      int pongY = 0;
  
      int pongVelocityX = pongSpeed;
      int pongVelocityY = pongSpeed;
  
      final int DELAY = 6;
      Timer timer;
  
      Random random;
  
      gamePanel() {
          random = new Random();
          pongY = random.nextInt((int) (SCREEN_HEIGHT - PONG_SPAWN_FRAME) + PONG_SPAWN_FRAME);
          if (pongVelocityY == 0) {
              if (pongY &gt; SCREEN_HEIGHT / 2 + pongSize) {
                  pongVelocityY = -pongSpeed;
              } else {
                  pongVelocityY = pongSpeed;
              }
          }
          this.setPreferredSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT));
          this.setBackground(Color.DARK_GRAY);
          this.setFocusable(true);
          this.addKeyListener(new myKeyAdapter());
          startGame();
      }
  
      void startGame() {
          running = true;
          timer = new Timer(DELAY, this);
          timer.start();
  
      }
  
      void restart() {
          redX = padding;
          redY = SCREEN_HEIGHT / 2;
          redVelocity = 0;
  
          blueX = SCREEN_WIDTH - padding;
          blueY = SCREEN_HEIGHT / 2;
          blueVelocity = 0;
  
          pongX = SCREEN_WIDTH / 4 - pongSize / 2;
          pongY = 0;
  
          pongVelocityX = pongSpeed;
          pongVelocityY = pongSpeed;
  
          spawnPong();
  
      }
  
      void spawnPong() {
          pongY = random.nextInt((int) (SCREEN_HEIGHT - PONG_SPAWN_FRAME * 2)) + PONG_SPAWN_FRAME;
          if (pongVelocityY == 0) {
              if (pongY &gt; SCREEN_HEIGHT / 2 + pongSize) {
                  pongVelocityY = -pongSpeed;
              } else {
                  pongVelocityY = pongSpeed;
              }
          }
      }
  
      public void paintComponent(Graphics g) {
          super.paintComponent(g);
          draw(g);
      }
  
      void draw(Graphics g) {
          g.setColor(Color.LIGHT_GRAY);
          g.fillOval(pongX, pongY, pongSize, pongSize);
          g.setColor(Color.red);
          g.fillRect(redX - batWidth / 2, redY - batHeight / 2, batWidth, batHeight);
          g.setColor(Color.blue);
          g.fillRect(blueX - batWidth / 2, blueY - batHeight / 2, batWidth, batHeight);
          g.setColor(Color.white);
          g.setFont(new Font(&quot;Roman New Times&quot;, Font.PLAIN, scoreTextSize));
          g.drawString(String.valueOf(redPoints), SCREEN_WIDTH / 4, scoreTextSize);
          g.drawString(String.valueOf(bluePoints), SCREEN_WIDTH / 4 * 3, scoreTextSize);
      }
  
      void pongMove() {
          pongX += pongVelocityX;
          pongY += pongVelocityY;
      }
  
      void batMove() {
          if (redY &gt; batHeight / 2 &amp;&amp; redVelocity &lt; 0) {
              redY += redVelocity * batSpeed;
          }
          if (redY &lt; SCREEN_HEIGHT - batHeight / 2 &amp;&amp; redVelocity &gt; 0) {
              redY += redVelocity * batSpeed;
          }
  
          blueY = pongY;
          /*
           * if (blueY&gt;batHeight/2 &amp;&amp; blueVelocity &lt; 0) { blueY += blueVelocity *
           * pongSpeed; } if (blueY&lt;SCREEN_HEIGHT-batHeight/2 &amp;&amp; blueVelocity &gt; 0) { blueY
           * += blueVelocity * pongSpeed; }
           */
      }
  
      void batLerp() {
          redVelocity *= 0.5f;
          blueVelocity *= 0.5f; 
      }
  
      void checkCollision() {
          if ((pongX &gt; blueX - pongSize - batWidth / 2 &amp;&amp; pongX &lt; blueX - pongSize + batWidth / 2)
                  &amp;&amp; (pongY &gt; blueY - batHeight / 2 &amp;&amp; pongY &lt; blueY + batHeight / 2)) {
              pongVelocityX *= -1;
          }
          if (pongX &lt; redX + batWidth / 2 &amp;&amp; (pongY &gt; redY - batHeight / 2 &amp;&amp; pongY &lt; redY + batHeight / 2)) {
              pongVelocityX *= -1;
          }
          if (pongY &lt; 0) {
              pongVelocityY *= -1;
          }
          if (pongY &gt; SCREEN_HEIGHT - pongSize) {
              pongVelocityY *= -1;
          }
          if (pongX &lt; -pongSize) {
              bluePoints += 1;
              restart();
          }
          if (pongX &gt; SCREEN_WIDTH) {
              redPoints += 1;
              restart();
          }
      }
  
      @Override
      public void actionPerformed(ActionEvent e) {
          if (running) {
              checkCollision();
              batMove();
              batLerp();
              pongMove();
          }
          repaint();
  
      }
  
      public class myKeyAdapter extends KeyAdapter {
          public void keyPressed(KeyEvent e) {
              switch (e.getKeyCode()) {
              case KeyEvent.VK_W:
                  redVelocity = -1;
                  break;
              case KeyEvent.VK_S:
                  redVelocity = 1;
                  break;
              case KeyEvent.VK_UP:
                  blueVelocity = -1;
                  break;
              case KeyEvent.VK_DOWN:
                  blueVelocity = 1;
                  break;
              }
          }
      }
  }
  </code></pre>