阻止Applet闪烁

时间:2014-06-22 12:23:39

标签: java swing japplet flicker

我的Java Applet游戏出了问题。当我运行它时,它会闪烁很多。我尝试过双缓冲,但它没有帮助。这是一个显示闪烁的短编码版本......

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();
    }
}
}

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;
}
}

我希望你能帮助我,因为这是一个非常烦人的问题,我会在所有带有动画的小程序上找到它。我非常感谢你们的帮助!

2 个答案:

答案 0 :(得分:2)

一些要点:

请查看详细描述的 Painting in AWT and Swing


值得一读 How paint method works?

  

Swing程序应覆盖paintComponent()而不是覆盖paint()。虽然API允许,但通常没有理由覆盖paintBorder()paintComponents()(如果您这样做,请确保您知道自己在做什么!)。这种因子使程序更容易覆盖它们需要扩展的部分绘画。

示例代码:

   JPanel panel = new JPanel() {
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            // custom painting code goes here
        }
    }

答案 1 :(得分:2)

以下是我在评论中建议的修复代码。

  

不要绘制到JApplet之类的顶级容器。而是在JPanel中进行自定义绘制,并覆盖paintComponent(..)方法而不是paint()

请注意,JComponent默认为双缓冲,而JApplet等顶级容器通常不是。

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;
}
}