I've got a problem with my Applet game in Java. It's flickering a lot when I run it. I have tried double buffering, but it didn't help. Here is a short coded version that shows the flickering...
public class Test extends JApplet implements ActionListener {
JButton start;
int delay;
Timer tm;
// Falling balls
int n; // Total balls
Ball[] ball; // Array with the balls in
int score;
// The amount of balls falling at the same time (increases by one every
// 10:th score)
int ballNr;
// Comment to the game
String comment;
public void init() {
this.setLayout(null);
this.setSize(600, 500);
this.getContentPane().setBackground(Color.cyan);
this.setFocusable(true);
score = 0;
ballNr = 3;
comment = "Avoid the balls!";
// Buttons
start = new JButton("START");
add(start);
start.setBounds(0, 400, 200, 100);
start.addActionListener(this);
// The timer
delay = 12;
tm = new Timer(delay, this);
// The falling balls
n = 12; // Number of balls in total
ball = new Ball[n];
// Declaring twelve new instances of the ball-object with a
// "reference array"
for (int i = 0; i < n; i++) {
ball[i] = new Ball();
}
}
// Paint-method //
public void paint(Graphics g) {
super.paint(g);
// Every 10:th score, the game adds one ball until you reach 100 =
// win! (ballNr + (int)(score * 0.1) -> ballNr increases by one
// every 10:th score
for (int i = 0; i < ballNr + (int) (score * 0.1); i++) {
// Score can't be higher than 100
if (score < 100) {
g.setColor(ball[i].getCol());
g.fillOval(ball[i].getXLoc(), ball[i].getYLoc(),
ball[i].getSize(), ball[i].getSize());
}
}
// Draw the score and the comment
g.setColor(Color.black);
g.setFont(new Font("Arial", Font.BOLD, 24));
g.drawString("SCORE: " + score, 440, 40);
g.setColor(Color.red);
g.setFont(new Font("Arial", Font.BOLD + Font.ITALIC, 28));
g.drawString(comment, 0, 40);
}
// ACTIONLISTENER //
public void actionPerformed(ActionEvent e) {
if (e.getSource() == start) {
tm.start();
this.requestFocusInWindow(); // Make the runner component have focus
}
// Every 10:th score, the game adds one ball until you reach 100 =
// win! (ballNr + (int)(score * 0.1) -> ballNr increases by one
// every 10:th score
for (int i = 0; i < ballNr + (int) (score * 0.1); i++) {
// Score can't pass 100, because then you have won the game
if (score < 100) {
ball[i].setYLoc(ball[i].getYLoc() + ball[i].getVel());
}
}
// If any ball is out of bounds (then the score increases by one)
for (int i = 0; i < n; i++) {
if (outOfBounds(ball[i])) {
ball[i] = new Ball();
}
}
repaint();
}
// If the ball is out of the screen
public boolean outOfBounds(Ball ball) {
if (ball.getYLoc() >= 500) {
score++;
return true;
} else {
return false;
}
}
// Updates new balls
public void updateBalls() {
for (int i = 0; i < n; i++) {
ball[i] = new Ball();
}
}
}
AND
public class Ball {
// Private variables
private Random r; // Generating random positions and
// sizes;
private int size; // Size of the ball
private int vel; // Ball velocity
private int nrOfCol; // Color code (see ballColor-method)
private Color col;
private int xLoc;
private int yLoc;
// Constructor
public Ball() {
r = new Random();
size = r.nextInt(40) + 10; // 10px - 50 px
vel = r.nextInt(6) + 1; // Speed btw 1-5 px/delay
nrOfCol = r.nextInt(8) + 1; // Specific nr from 1-9
col = ballColor();
xLoc = r.nextInt(550);
yLoc = 0;
}
public Ball(int xPos, int yPos, int size, int vel, Color col) {
this.xLoc = xPos;
this.yLoc = yPos;
this.size = size;
this.vel = vel;
this.col = col;
}
// A method to generate different colors of the balls
public Color ballColor() {
Color col;
switch (nrOfCol) {
case 1:
col = Color.black;
break;
case 2:
col = Color.red;
break;
case 3:
col = Color.green;
break;
case 4:
col = Color.yellow;
break;
case 5:
col = Color.pink;
break;
case 6:
col = Color.magenta;
break;
case 7:
col = Color.white;
break;
case 8:
col = Color.orange;
break;
case 9:
col = Color.blue;
break;
default:
col = Color.black;
// All colors except cyan as it is the background color
}
return col;
}
// Getters & setters
public int getXLoc() {
return xLoc;
}
public int getYLoc() {
return yLoc;
}
public void setYLoc(int y) {
yLoc = y;
}
public int getSize() {
return size;
}
public int getVel() {
return vel;
}
public Color getCol() {
return col;
}
}
I hope you can help me out as this is a very annoying issue I get on all my applets with animations. I would really appreciate help from you guys!
Don't use null
layout at all instead there are lots of Layout Manager that can be used.
Use a container to add all the component in it and add it finally in the root container of JApplet
.
Use JPanel
and override paintComponent()
for custom panting that will eliminate the flickering as well.
paint
method is a heavy operation that does lots of things in the background.
Read Difference between paint, paintComponent and paintComponents in Swing
Please have a look at Painting in AWT and Swing that describes it in detail.
It's worth reading How paint method works?
Swing programs should override
paintComponent()
instead of overridingpaint()
. Although the API allows it, there is generally no reason to overridepaintBorder()
orpaintComponents()
(and if you do, make sure you know what you're doing!). This factoring makes it easier for programs to override only the portion of the painting which they need to extend.
Sample code:
JPanel panel = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
// custom painting code goes here
}
}
Here is the code with the fix I suggested in comment.
Don't paint to a top level container like
JApplet
. Instead do custom painting in aJPanel
and override thepaintComponent(..)
method instead ofpaint()
.
Note that a JComponent
is double buffered by default, whereas a top-level container like JApplet
typically isn't.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
/* <applet code=TestApplet width=600 height=500></applet> */
public class TestApplet extends JApplet {
@Override
public void init() {
add(new PlayingArea());
}
}
class PlayingArea extends JPanel implements ActionListener {
JButton start;
int delay;
Timer tm;
// Falling balls
int n; // Total balls
Ball[] ball; // Array with the balls in
int score;
// The amount of balls falling at the same time (increases by one every
// 10:th score)
int ballNr;
// Comment to the game
String comment;
public PlayingArea() {
setBackground(Color.cyan);
setFocusable(true);
score = 0;
ballNr = 3;
comment = "Avoid the balls!";
// Buttons
start = new JButton("START");
add(start);
start.setBounds(0, 400, 200, 100);
start.addActionListener(this);
// The timer
delay = 12;
tm = new Timer(delay, this);
// The falling balls
n = 12; // Number of balls in total
ball = new Ball[n];
// Declaring twelve new instances of the ball-object with a
// "reference array"
for (int i = 0; i < n; i++) {
ball[i] = new Ball();
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(600,500);
}
// Paint-method //
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Every 10:th score, the game adds one ball until you reach 100 =
// win! (ballNr + (int)(score * 0.1) -> ballNr increases by one
// every 10:th score
for (int i = 0; i < ballNr + (int) (score * 0.1); i++) {
// Score can't be higher than 100
if (score < 100) {
g.setColor(ball[i].getCol());
g.fillOval(ball[i].getXLoc(), ball[i].getYLoc(),
ball[i].getSize(), ball[i].getSize());
}
}
// Draw the score and the comment
g.setColor(Color.black);
g.setFont(new Font("Arial", Font.BOLD, 24));
g.drawString("SCORE: " + score, 440, 40);
g.setColor(Color.red);
g.setFont(new Font("Arial", Font.BOLD + Font.ITALIC, 28));
g.drawString(comment, 0, 40);
}
// ACTIONLISTENER //
public void actionPerformed(ActionEvent e) {
if (e.getSource() == start) {
tm.start();
this.requestFocusInWindow(); // Make the runner component have focus
}
// Every 10:th score, the game adds one ball until you reach 100 =
// win! (ballNr + (int)(score * 0.1) -> ballNr increases by one
// every 10:th score
for (int i = 0; i < ballNr + (int) (score * 0.1); i++) {
// Score can't pass 100, because then you have won the game
if (score < 100) {
ball[i].setYLoc(ball[i].getYLoc() + ball[i].getVel());
}
}
// If any ball is out of bounds (then the score increases by one)
for (int i = 0; i < n; i++) {
if (outOfBounds(ball[i])) {
ball[i] = new Ball();
}
}
repaint();
}
// If the ball is out of the screen
public boolean outOfBounds(Ball ball) {
if (ball.getYLoc() >= 500) {
score++;
return true;
} else {
return false;
}
}
// Updates new balls
public void updateBalls() {
for (int i = 0; i < n; i++) {
ball[i] = new Ball();
}
}
}
class Ball {
// Private variables
private Random r; // Generating random positions and
// sizes;
private int size; // Size of the ball
private int vel; // Ball velocity
private int nrOfCol; // Color code (see ballColor-method)
private Color col;
private int xLoc;
private int yLoc;
// Constructor
public Ball() {
r = new Random();
size = r.nextInt(40) + 10; // 10px - 50 px
vel = r.nextInt(6) + 1; // Speed btw 1-5 px/delay
nrOfCol = r.nextInt(8) + 1; // Specific nr from 1-9
col = ballColor();
xLoc = r.nextInt(550);
yLoc = 0;
}
public Ball(int xPos, int yPos, int size, int vel, Color col) {
this.xLoc = xPos;
this.yLoc = yPos;
this.size = size;
this.vel = vel;
this.col = col;
}
// A method to generate different colors of the balls
public Color ballColor() {
Color col;
switch (nrOfCol) {
case 1:
col = Color.black;
break;
case 2:
col = Color.red;
break;
case 3:
col = Color.green;
break;
case 4:
col = Color.yellow;
break;
case 5:
col = Color.pink;
break;
case 6:
col = Color.magenta;
break;
case 7:
col = Color.white;
break;
case 8:
col = Color.orange;
break;
case 9:
col = Color.blue;
break;
default:
col = Color.black;
// All colors except cyan as it is the background color
}
return col;
}
// Getters & setters
public int getXLoc() {
return xLoc;
}
public int getYLoc() {
return yLoc;
}
public void setYLoc(int y) {
yLoc = y;
}
public int getSize() {
return size;
}
public int getVel() {
return vel;
}
public Color getCol() {
return col;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.