I am a novice programmer and I have no knowledge of gaming theory.
Ok, we can work with that.
So I decided the smartest way to avoid a lot of rendering and buffering is to have four JPanels.
You've just unnecessarily complicated your program.
Think of a JPanel as a canvas. You want to draw the entire Breakout game; bricks, paddle, and ball, on one JPanel canvas. Don't worry, you'll be able to redraw the entire canvas fast enough to get 60 frames per second if you want.
The way to do this is to create a Brick class, a Paddle class, and a Ball class. You create a Game Model class that contains one instance of the Paddle class, one instance pf the Ball class, and a List of instances of the Brick class.
The Brick class would have fields to determine its position in the wall, the number of points scored when the ball collides with the brick, the color of the brick, and a draw method that knows how to draw one brick.
The ball class would have fields to determine its x, y position, its direction, its velocity, and a draw method that knows how to draw the ball.
The Paddle class would have fields to determine its x, y position, its direction, its velocity, and a draw method that knows haw to draw the paddle.
The Game Model class would have methods to determine when the ball collides with a brick, determine when the ball collides with a brick, determine when the ball collides with a wall, and a draw method that calls the other model class draw methods to draw a ball, a paddle, and a wall of bricks.
This should be enough for now to get you started going in the right direction.
Edited to answer questions:
How would I implement a draw method in all these classes?
Here's an example Ball class. I haven't tested the moveBall method, so it might need some adjustment
import java.awt.Graphics;
import java.awt.geom.Point2D;
public class Ball {
private Point2D position;
/** velocity in pixels per second */
private double velocity;
/**
* direction in radians
* <ul>
* <li>0 - Heading east (+x)</li>
* <li>PI / 2 - Heading north (-y)</li>
* <li>PI - Heading west (-x)</li>
* <li>PI * 3 / 2 - Heading south (+y)</li>
* </ul>
* */
private double direction;
public Point2D getPosition() {
return position;
}
public void setPosition(Point2D position) {
this.position = position;
}
public double getVelocity() {
return velocity;
}
public void setVelocity(double velocity) {
this.velocity = velocity;
}
public double getDirection() {
return direction;
}
public void setDirection(double direction) {
this.direction = direction;
}
public void moveBall(long milliseconds) {
Point2D oldPosition = position;
// Calculate distance of ball motion
double distance = velocity / (1000.0D * milliseconds);
// Calculate new position
double newX = distance * Math.cos(direction);
double newY = distance * Math.sin(direction);
newX = oldPosition.getX() + newX;
newY = oldPosition.getY() - newY;
// Update position
position.setLocation(newX, newY);
}
public void draw(Graphics g) {
int radius = 3;
int x = (int) Math.round(position.getX());
int y = (int) Math.round(position.getY());
// Draw circle of radius and center point x, y
g.drawOval(x - radius, y - radius, radius + radius, radius + radius);
}
}
The draw method draws the ball wherever it actually is located. That's all the draw method does.
Actually moving the ball is the responsibility of the Game Model class. The method for moving the ball is included in this class because the information necessary to move the ball is stored in the Ball class.
I gave the ball a radius of 3, or a diameter of 6 pixels. You may want to make the ball bigger, and use the fillOval method instead of drawOval.
should I just call repaint() at a 30ms interval
Basically, yes.
In psudeocode, you create a game loop
while (running) {
update game model();
draw game();
wait;
}
First, you update the game model. I gave you a Ball class. You would have similar classes for the paddle and bricks. They all have draw methods.
Your Game model class calls all of these draw methods in the proper order. In Breakout, you would draw the boundaries first, then the bricks, then the paddle, and finally, the ball.
Your JPanel (canvas) calls the one draw method in the Game Model class.
I don't have an example game to show you, but if you read the article Sudoku Solver Swing GUI, you'll see how to put together a Swing GUI and you'll see how model classes implement draw methods.
I suggest that you stop working on Breakout for a while and go through the Oracle Swing Tutorial. Don't skip any sections in your haste to write a program. Go through the entire tutorial so you understand how Swing works before you try and use it.