Applet即使使用Double Buffering后也会闪烁 [英] Applet Flickers even after using using Double Buffering

查看:216
本文介绍了Applet即使使用Double Buffering后也会闪烁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我使用了双缓冲

的概念, strong>,但 Applet仍然闪烁
我提交的错误是什么?

  import java.awt.Color; 
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.Timer;
import javax.swing.JApplet;

public class Pong extends JApplet实现Runnable,MouseMotionListener {
Ball ball;
Paddle left_paddle;
桨右手
图像图像;
Graphics DoubleBuffered;

@Override
public void init(){
setSize(800,600);
addMouseMotionListener(this);
setFocusable(true);
requestFocusInWindow();
}

@Override
public void start(){
left_paddle = new Paddle(5,200,this);
right_paddle = new Paddle(this.getWidth() - 30,this.getHeight()/ 2,this);
ball = new Ball(100,100,left_paddle,right_paddle);
线程线程=新线程(this);
thread.start();
}

@Override
public void run(){
while(true){
ball.update(this);
repaint();
try {
Thread.sleep(17); //帧速率约为60 FPS
} catch(InterruptedException ex){

}
}
}

@Override
public void stop(){
}

@Override
public void destroy(){
}

@Override
public void update(Graphics g){
if(image == null){
image = createImage(this.getWidth(),this.getHeight());
DoubleBuffered = image.getGraphics();
}
DoubleBuffered.setColor(getBackground());
DoubleBuffered.fillRect(0,0,this.getWidth(),this.getHeight());

DoubleBuffered.setColor(getForeground());
paint(DoubleBuffered);

DoubleBuffered.drawImage(image,0,0,this);
}

@Override
public void paint(Graphics g){
g.setColor(Color.WHITE);
g.fillRect(0,0,this.getWidth(),this.getHeight());
ball.paint(g);
left_paddle.paint(g);
right_paddle.paint(g);
g.setColor(Color.BLACK);
g.drawLine(this.getWidth()/ 2,0,this.getWidth()/ 2,this.getHeight());
}

@Override
public void mouseDragged(MouseEvent e){
}

@Override
public void mouseMoved MouseEvent e){
int y = e.getY();
int x = e.getX();
if(x< this.getWidth()/ 2){//控制左边的paddle
if(y< 0){
y = 0;
} else if(y + left_paddle.getHeight()> = this.getHeight()){
y = this.getHeight() - left_paddle.getHeight
}
left_paddle.mouse(y);
}
else {
if(y <0){
y = 0;
} else if(y + right_paddle.getHeight()> = this.getHeight()){
y = this.getHeight() - right_paddle.getHeight
}
right_paddle.mouse(y);
}
}
}

class Ball {
private int x;
private int y;
private float dx = 4;
private float dy = 5;
private int radius = 10;
private pad左,右;

Ball(int x,int y,Paddle x1,Paddle y1){
this.x = x;
this.y = y;
left = x1;
right = y1;
}

public void reset()
{
this.x = 400;
this.y = 200;
}

public void update(Pong ref)
{
if(x + dx< left.getX()+ left.getWidth()+ radius& amp; ;& y + dy + radius> = left.getY()& y + dy + radius< = left.getY()+ left.getHeight()){
x = left.getX )+ left.getWidth()+ radius;
dx * =(-1);
//检查左桨碰撞
}
else if(x + dx + radius> = right.getX()& y + dy + radius> = right。 getY()& y + dy + radius< = right.getY()+ right.getHeight()){
x = right.getX()
dx * =(-1);
//检查右侧桨碰撞
}
//如果球碰到边界在中点重置
else if(x + dx + radius> = ref.getWidth ()){
reset();
}
else if(x + dx reset();
}
else {
x + = dx;
}

if(y + dy + radius> ref.getHeight()){
y = ref.getHeight()
dy * =(-1);
}
else if(y + dy y = radius;
dy * =(-1);
}
else {
y + = dy;
}
}

public void paint(Graphics g)
{
g.setColor(Color.RED);
g.fillOval(x-radius,y-radius,2 * radius,2 * radius);
}

}

class Paddle {

private int x;
private int y;
private int width = 25;
private int height = 150;
private timer timer;

public Paddle(int x,int y,Pong ref){
this.x = x;
this.y = y;
}

public int getHeight(){
return height;
}

public int getWidth(){
return width;
}

public int getX(){
return x;
}

public int getY(){
return y;
}

public void paint(Graphics g)
{
g.setColor(Color.BLUE);
g.fillRect(x,y,width,height);
}

//鼠标查找
void mouse(int y_final)
{
y = y_final;
}
}


解决方案

你应该避免重写 paint 更新顶层容器的方法,例如 JApplet



您必须记住调用 super.update ,传递图形上下文您已创建。你还必须记得调用 super.paint 。这里有很多重要的功能,你不想跳过。



你也应该处置你创建的任何图形,因为他们倾向于hog memory;)



但是,由于你使用的是Swing组件,你应该创建一个自定义组件(从 JPanel )并使用 paintComponent 方法。



这主要是因为Swing组件是默认的双缓冲...

  import java.awt.BorderLayout; 
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.Timer;
import javax.swing.JApplet
import javax.swing.JPanel;

public class Pong extends JApplet {

private GamePane gamePane;

@Override
public void init(){
setSize(800,600);
gamePane = new GamePane();
setLayout(new BorderLayout());
add(gamePane);
}

@Override
public void start(){
gamePane.start();
}

@Override
public void stop(){
}

@Override
public void destroy
}

public class GamePane extends JPanel实现MouseMotionListener {

球球;
Paddle left_paddle;
桨右手

public GamePane(){
setBackground(Color.WHITE);
addMouseMotionListener(this);
setFocusable(true);
requestFocusInWindow();
}

public void start(){
left_paddle = new Paddle(5,200);
right_paddle = new Paddle(this.getWidth() - 30,this.getHeight()/ 2);
ball = new Ball(100,100,left_paddle,right_paddle);
timer timer = new Timer(40,new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
ball.update(GamePane.this);
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}

@Override
protected void paintComponent(Graphics g){
super.paintComponent(g); //要更改生成方法的主体,请选择工具|模板。

ball.paint(g);
left_paddle.paint(g);
right_paddle.paint(g);
g.setColor(Color.BLACK);
g.drawLine(this.getWidth()/ 2,0,this.getWidth()/ 2,this.getHeight());

}

@Override
public void mouseDragged(MouseEvent e){
}

@Override
public void mouseMoved(MouseEvent e){
int y = e.getY();
int x = e.getX();
if(x< this.getWidth()/ 2){//控制左边的paddle
if(y< 0){
y = 0;
} else if(y + left_paddle.getHeight()> = this.getHeight()){
y = this.getHeight() - left_paddle.getHeight
}
left_paddle.mouse(y);
} else {
if(y <0){
y = 0;
} else if(y + right_paddle.getHeight()> = this.getHeight()){
y = this.getHeight() - right_paddle.getHeight
}
right_paddle.mouse(y);
}
}
}

class Ball {

private int x;
private int y;
private float dx = 4;
private float dy = 5;
private int radius = 10;
private pad左,右;

Ball(int x,int y,Paddle x1,Paddle y1){
this.x = x;
this.y = y;
left = x1;
right = y1;
}

public void reset(){
this.x = 400;
this.y = 200;
}

public void update(GamePane ref){
if(x + dx< left.getX()+ left.getWidth()+ radius& y + dy + radius> = left.getY()& y + dy + radius <= left.getY()+ left.getHeight()){
x = left.getX()+ left。 getWidth()+ radius;
dx * =(-1);
//检查左桨碰撞
} else if(x + dx + radius> = right.getX()& y + dy + radius> = right.getY()& ;& y + dy + radius< = right.getY()+ right.getHeight()){
x = right.getX()
dx * =(-1);
//检查正确的桨碰撞
} //如果球碰到边界在中间点重置
else if(x + dx + radius> = ref.getWidth()){
reset();
} else if(x + dx reset();
} else {
x + = dx;
}

if(y + dy + radius> ref.getHeight()){
y = ref.getHeight()
dy * =(-1);
} else if(y + dy y = radius;
dy * =(-1);
} else {
y + = dy;
}
}

public void paint(Graphics g){
g.setColor(Color.RED);
g.fillOval(x - radius,y - radius,2 * radius,2 * radius);
}
}

public class Paddle {

private int x;
private int y;
private int width = 25;
private int height = 150;
private timer timer;

public Paddle(int x,int y){
this.x = x;
this.y = y;
}

public int getHeight(){
return height;
}

public int getWidth(){
return width;
}

public int getX(){
return x;
}

public int getY(){
return y;
}

public void paint(Graphics g){
g.setColor(Color.BLUE);
g.fillRect(x,y,width,height);
}

//鼠标查找
void mouse(int y_final){
y = y_final;
}
}
}


I am trying to make a 2 player Pong Applet where the user controls the paddle using mouse.

I have used the concept of Double Buffering, but the Applet still flickers !!! What is the mistake I am committing ?

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.Timer;
import javax.swing.JApplet;

public class Pong extends JApplet implements Runnable, MouseMotionListener {
    Ball ball;
    Paddle left_paddle;
    Paddle right_paddle;
    Image image;
    Graphics DoubleBuffered;

    @Override
    public void init() {
        setSize(800, 600);
        addMouseMotionListener(this);
        setFocusable(true);
        requestFocusInWindow();        
    }

    @Override
    public void start() {
        left_paddle = new Paddle(5, 200, this);
        right_paddle = new Paddle(this.getWidth() - 30, this.getHeight() / 2, this);
        ball = new Ball(100, 100, left_paddle, right_paddle);
        Thread thread = new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        while (true) {
            ball.update(this);
            repaint();
            try {
                Thread.sleep(17); //Frame rate of approx 60 FPS
            } catch (InterruptedException ex) {

            }
        }
    }

    @Override
    public void stop() {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void update(Graphics g) {
        if (image == null) {
            image = createImage(this.getWidth(), this.getHeight());
            DoubleBuffered = image.getGraphics();
        }
        DoubleBuffered.setColor(getBackground());
        DoubleBuffered.fillRect(0, 0, this.getWidth(), this.getHeight());

        DoubleBuffered.setColor(getForeground());
        paint (DoubleBuffered);

        DoubleBuffered.drawImage(image, 0, 0, this);
    }

    @Override
    public void paint(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, this.getWidth(), this.getHeight());
        ball.paint(g);
        left_paddle.paint(g);
        right_paddle.paint(g);
        g.setColor(Color.BLACK);
        g.drawLine(this.getWidth()/2, 0, this.getWidth()/2, this.getHeight());
    }

    @Override
    public void mouseDragged(MouseEvent e) {
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        int y = e.getY();
        int x = e.getX();
        if (x < this.getWidth()/2) { //Control the left paddle
            if (y < 0) {
                y = 0;
            } else if (y + left_paddle.getHeight() >= this.getHeight()) {
                y = this.getHeight() - left_paddle.getHeight();
            }
            left_paddle.mouse(y);
        }
        else {
            if (y < 0) {
                y = 0;
            } else if (y + right_paddle.getHeight() >= this.getHeight()) {
                y = this.getHeight() - right_paddle.getHeight();
            }
            right_paddle.mouse(y);
        }
    }
}

class Ball {
    private int x;
    private int y;
    private float dx=4;
    private float dy=5;
    private int radius = 10;
    private Paddle left, right;

    Ball(int x, int y, Paddle x1, Paddle y1) {
        this.x = x;
        this.y = y;
        left = x1;
        right = y1;
    }

    public void reset ()
    {
        this.x = 400;
        this.y = 200;
    }

    public void update(Pong ref)
    {
        if (x+dx < left.getX()+left.getWidth()+radius && y+dy+radius >= left.getY() && y+dy+radius <= left.getY()+left.getHeight()) {
            x = left.getX()+left.getWidth()+radius;
            dx *= (-1);
            // checks the left paddle collision
        }
        else if (x+dx+radius >= right.getX() && y+dy+radius >= right.getY() && y+dy+radius <= right.getY()+right.getHeight() ) {
            x = right.getX() - radius;
            dx *= (-1);
            //checks the right paddle collision
        }
        //if ball touches the boundary reset it at middle point
        else if (x+dx+radius >= ref.getWidth()) {
            reset();
        }
        else if (x + dx < radius) {
            reset();
        }
        else {
            x += dx;
        }

        if (y+dy +radius > ref.getHeight()) {
            y = ref.getHeight() - radius - 1;
            dy *= (-1);
        }
        else if (y + dy < radius) {
            y = radius;
            dy *= (-1);
        }
        else {
            y += dy;
        }
    }

    public void paint (Graphics g)
    {
        g.setColor(Color.RED);
        g.fillOval(x-radius, y-radius, 2*radius, 2*radius);
    }

}

class Paddle {

    private int x;
    private int y;
    private int width = 25;
    private int height = 150;
    private Timer timer;

    public Paddle(int x, int y, Pong ref) {
        this.x = x;
        this.y = y;
    }

    public int getHeight() {
        return height;
    }

    public int getWidth() {
        return width;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public void paint (Graphics g)
    {
        g.setColor(Color.BLUE);
        g.fillRect(x, y, width, height);
    }

    //mouse lookup
    void mouse(int y_final)
    {
        y = y_final;
    }
}

解决方案

Generally speaking, you should avoid overriding the paint and update methods of top level containers like JApplet.

You must remember to call super.update, passing it the graphics context which you have created. You must also remember to call super.paint. There is a lot of important functionality going in here that you don't want to skip over.

You should also be disposing of any graphics you create, as they tend to hog memory ;)

But, seen as you're using Swing components anyway, you should create yourself a custom component (from something like JPanel) and use it's paintComponent method.

The main reason for this is, Swing components are double buffered by default...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.Timer;
import javax.swing.JApplet;
import javax.swing.JPanel;

public class Pong extends JApplet {

    private GamePane gamePane;

    @Override
    public void init() {
        setSize(800, 600);
        gamePane = new GamePane();
        setLayout(new BorderLayout());
        add(gamePane);
    }

    @Override
    public void start() {
        gamePane.start();
    }

    @Override
    public void stop() {
    }

    @Override
    public void destroy() {
    }

    public class GamePane extends JPanel implements MouseMotionListener {

        Ball ball;
        Paddle left_paddle;
        Paddle right_paddle;

        public GamePane() {
            setBackground(Color.WHITE);
            addMouseMotionListener(this);
            setFocusable(true);
            requestFocusInWindow();
        }

        public void start() {
            left_paddle = new Paddle(5, 200);
            right_paddle = new Paddle(this.getWidth() - 30, this.getHeight() / 2);
            ball = new Ball(100, 100, left_paddle, right_paddle);
            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    ball.update(GamePane.this);
                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.start();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.

            ball.paint(g);
            left_paddle.paint(g);
            right_paddle.paint(g);
            g.setColor(Color.BLACK);
            g.drawLine(this.getWidth() / 2, 0, this.getWidth() / 2, this.getHeight());

        }

        @Override
        public void mouseDragged(MouseEvent e) {
        }

        @Override
        public void mouseMoved(MouseEvent e) {
            int y = e.getY();
            int x = e.getX();
            if (x < this.getWidth() / 2) { //Control the left paddle
                if (y < 0) {
                    y = 0;
                } else if (y + left_paddle.getHeight() >= this.getHeight()) {
                    y = this.getHeight() - left_paddle.getHeight();
                }
                left_paddle.mouse(y);
            } else {
                if (y < 0) {
                    y = 0;
                } else if (y + right_paddle.getHeight() >= this.getHeight()) {
                    y = this.getHeight() - right_paddle.getHeight();
                }
                right_paddle.mouse(y);
            }
        }
    }

    class Ball {

        private int x;
        private int y;
        private float dx = 4;
        private float dy = 5;
        private int radius = 10;
        private Paddle left, right;

        Ball(int x, int y, Paddle x1, Paddle y1) {
            this.x = x;
            this.y = y;
            left = x1;
            right = y1;
        }

        public void reset() {
            this.x = 400;
            this.y = 200;
        }

        public void update(GamePane ref) {
            if (x + dx < left.getX() + left.getWidth() + radius && y + dy + radius >= left.getY() && y + dy + radius <= left.getY() + left.getHeight()) {
                x = left.getX() + left.getWidth() + radius;
                dx *= (-1);
                // checks the left paddle collision
            } else if (x + dx + radius >= right.getX() && y + dy + radius >= right.getY() && y + dy + radius <= right.getY() + right.getHeight()) {
                x = right.getX() - radius;
                dx *= (-1);
                //checks the right paddle collision
            } //if ball touches the boundary reset it at middle point
            else if (x + dx + radius >= ref.getWidth()) {
                reset();
            } else if (x + dx < radius) {
                reset();
            } else {
                x += dx;
            }

            if (y + dy + radius > ref.getHeight()) {
                y = ref.getHeight() - radius - 1;
                dy *= (-1);
            } else if (y + dy < radius) {
                y = radius;
                dy *= (-1);
            } else {
                y += dy;
            }
        }

        public void paint(Graphics g) {
            g.setColor(Color.RED);
            g.fillOval(x - radius, y - radius, 2 * radius, 2 * radius);
        }
    }

    public class Paddle {

        private int x;
        private int y;
        private int width = 25;
        private int height = 150;
        private Timer timer;

        public Paddle(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public int getHeight() {
            return height;
        }

        public int getWidth() {
            return width;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        public void paint(Graphics g) {
            g.setColor(Color.BLUE);
            g.fillRect(x, y, width, height);
        }

        //mouse lookup
        void mouse(int y_final) {
            y = y_final;
        }
    }
}

这篇关于Applet即使使用Double Buffering后也会闪烁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆