0

Basically when i update the ball in my flipper (an Oval created with Graphics2D) it teleports to his next location, which is what I want it to do, but I would much rather have a smooth animation (And I also fear the crispy movement is gonna be hard to deal with for collisions).

So is there a way to get smoother movement?

The main class:

import Flipper.Ball;
import Flipper.Cabinet;

public class Main {

    public static Cabinet cabinet;
    public static Ball ball;

    public static void main(String[] args) throws InterruptedException {
        new Frame();
        cabinet = new Cabinet();
        ball = new Ball();

        while (true)
            update();
    }

    private static void update() throws InterruptedException {
        ball.calcSpeed();
        ball.move();
    }
}

Frame class:

import javax.swing.*;

public class Frame extends JFrame {

    Frame() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.add(new Panel());
        this.pack();
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }
}

Panel class (I left out all of the useless KeyListener/MouseListener methods that i haven't used yet):

mport javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class Panel extends JPanel implements KeyListener, MouseListener {

    Panel() {
        this.setPreferredSize(new Dimension(Constant.WIDTH, Constant.HEIGHT));
        this.setFocusable(true);
        this.addMouseListener(this);
        this.addKeyListener(this);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2 = (Graphics2D) g;

        g2.setColor(Color.BLACK);
        g2.draw(Main.cabinet.getShape());

        g2.setColor(Color.BLUE);
        g2.fillOval(Main.ball.getX(), Main.ball.getY(), Constant.BALLSIZE, Constant.BALLSIZE);

        repaint();
    }
}

Flipper classes:

package Flipper;

import main.Constant;

import java.awt.*;

public class Cabinet {

    private Rectangle shape;
    public Cabinet() {
        this.shape = new Rectangle(Constant.WIDTH, Constant.HEIGHT);
    }

    public Rectangle getShape() {
        return shape;
    }
}
package Flipper;

import main.Constant;

import java.util.concurrent.TimeUnit;

public class Ball {

    private int x;
    private int y;
    private int xSpeed = 1;
    private int ySpeed = 10;

    public Ball() {
        this.x = 230;
        this.y = 160;
    }

    public void calcSpeed() {
        if (y >= Constant.HEIGHT - Constant.BALLSIZE)
            ySpeed = ySpeed * -1;
        if (y <= 0)
            ySpeed = ySpeed * -1;
    }

    public void move() throws InterruptedException {
        y += ySpeed;

        TimeUnit.MILLISECONDS.sleep(50);
    }

    // Getters


    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getxSpeed() {
        return xSpeed;
    }

    public int getySpeed() {
        return ySpeed;
    }


    // Setters

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    public void setxSpeed(int xSpeed) {
        this.xSpeed = xSpeed;
    }

    public void setySpeed(int ySpeed) {
        this.ySpeed = ySpeed;
    }
}

camickr
  • 321,443
  • 19
  • 166
  • 288
Tonda
  • 1
  • 3
    1) Don't use a while loop for animation. Instead, use a Swing Timer. 2) Don't override paint(). Instead override `paintComonent(...)`. 3) Don't invoke repaint() from a painting method. 4) The objects to be painted should be contained in the panel doing the paint, NOT the frame. 5) Don't call your class "Panel" and "Frame". There are AWT components with that name and it is confusing. Class names should be more descriptive. 6) Check out: https://stackoverflow.com/a/54028681/131872 for an example that implements the above suggestions. – camickr Nov 01 '22 at 15:34
  • 1
    Here's a detailed explanation of a `Ball` class in a [Java classic Pong game](https://stackoverflow.com/questions/66732003/how-to-add-smooth-movement-to-my-java-game/66734544#66734544). – Gilbert Le Blanc Nov 01 '22 at 16:00
  • Here's and example of smooth transitions. [Bouncing Balls](https://stackoverflow.com/a/66833594/1552534). They only bounce off the sides. This also uses a timer as suggested. – WJS Nov 01 '22 at 16:47
  • First thing, thank to you all for the answers. Second thing: I tried to improve the code by implementing camickr suggestions and by "taking inspiration" from @WJS 's code. This said I would still like to ask two things: 1] Is the "crispy" ball movement (at high velocity) fixable? 'Cause I tried Gilbert's pong code an it has the same problem, even if mine is a bit different due to physics being implemented (gravity :D) 2] What's the best way to implement a frame per second control system ('cause I noticed that sometimes stuff moves faster for no apparent reason) – Tonda Nov 17 '22 at 18:21
  • also @WJS what is "slope" for in your code? – Tonda Nov 17 '22 at 18:34
  • Each ball has a default slope generated at random. It is used to create the standard path of each ball. It is later used when the balls collide with a side to ensure the angle comes off each side appropriately. It wouldn't make sense for a ball to bounce off the side coming in at a 45 degree angle but bounce away at 90. It must come off at 45 degrees (unless "English" were to be applied as in pool). The only thing that changes is the direction. If you comment out the default slope in the Ball class you will see a boring display of balls moving back and forth at the top of the window. – WJS Nov 17 '22 at 18:51
  • BTW, in main, I should be doing the following to start the app. `SwingUtilities.invokeLater(()-> new Bounce(PANEL_WIDTH, PANEL_HEIGHT).start());` – WJS Nov 17 '22 at 19:08
  • Ok but considering that the x and y components are indipendent (if two x are different their respective ball direction should be different) doesn't the slope became useless? – Tonda Nov 17 '22 at 20:27
  • @WJS how does `SwingUtilities.invokeLater(()-> new Bounce(PANEL_WIDTH, PANEL_HEIGHT).start());` work and y would u use that? (sry if I ask a lot of stuff but these are a lot of useful info and imma take advantage of that >:D) – Tonda Nov 17 '22 at 20:30
  • Check out [SwingUtilities.invokeLater](https://stackoverflow.com/questions/7196889/swingutilities-invokelater) – WJS Nov 17 '22 at 21:40

0 Answers0