我的JFrame Flickers [英] My JFrame Flickers

查看:63
本文介绍了我的JFrame Flickers的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个简单的Java游戏-在轨道上开车.我的老师限制我使用矩形之类的东西.我的问题是,当我使用方法repaint()时,我的框架闪烁了.我试图在汽车改变方向时才使用重新绘制方法,但是这样做没有任何好处.有什么建议吗?

I'm trying to make a simple java game -- driving a car through a track. I am conditioned by my teacher to use rectangles and stuff like that . My problem is when I use the method repaint() that my frame flickers. I have tried to put the repaint method just when the car changes direction, but it doesn't do any good. Any suggestions?

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.URL;

import javax.swing.JFrame;


@SuppressWarnings("serial") 
public class MAP extends JFrame
{
    //the URL and Img designed for the images
    URL cLeft,cRight,cUp;
    Image img1,img2,img3;

    //these will keep track of each player’s speed:
    double p1Speed =.5, p2Speed =.5;

    //constant for the screen size and used for the drawing the terrain
    final int WIDTH = 900, HEIGHT = 650;

    //these are ints that represent directions:
    final int UP = 0, RIGHT = 1, DOWN = 2, LEFT = 3;
    //these will keep track of the player’s directions (default = up)
    int p1Direction = 0;

    //this is the rectangle for player 1’s (outer) car:
    Rectangle p1 = new Rectangle(WIDTH/9,HEIGHT/2, WIDTH/30,WIDTH/30);

    //draw the terrain
    Rectangle left = new Rectangle(0,0,WIDTH/9,HEIGHT);
    Rectangle right = new Rectangle((WIDTH/9)*9,0,WIDTH/9,HEIGHT);
    Rectangle top = new Rectangle(0,0,WIDTH, HEIGHT/9);
    Rectangle bottom = new Rectangle(0,(HEIGHT/9)*9,WIDTH,HEIGHT/9);
    Rectangle center = new Rectangle((int)((WIDTH/9)*2.5),(int)((HEIGHT/9)*2.5), (int)((WIDTH/9)*5),(HEIGHT/9)*4);

    //these obstacles will obstruct the path and make navigating harder
    Rectangle obstacle = new
    Rectangle(WIDTH/2,(int)((HEIGHT/9)*7),WIDTH/10,HEIGHT/9);
    Rectangle obstacle2 = new
    Rectangle(WIDTH/3,(int)((HEIGHT/9)*5),WIDTH/10,HEIGHT/4);
    Rectangle obstacle3 = new
    Rectangle(2*(WIDTH/3),(int)((HEIGHT/9)*5),WIDTH/10,HEIGHT/4);
    Rectangle obstacle4 = new Rectangle(WIDTH/3,HEIGHT/9,WIDTH/30,HEIGHT/9);
    Rectangle obstacle5 = new Rectangle(WIDTH/2,(int)((HEIGHT/9)*1.5),WIDTH/30,HEIGHT/4);
    Rectangle finish = new Rectangle(WIDTH/9,(HEIGHT/2)-HEIGHT/9,(int)((WIDTH/9)*1.5),HEIGHT/70);
    Rectangle lineO=new Rectangle(WIDTH/9,HEIGHT/2,(int)((WIDTH/9)*1.5)/2,HEIGHT/140);
    Rectangle lineI = new Rectangle(((WIDTH/9)+((int)((WIDTH/9)*1.5)/2)),(HEIGHT/2)+(HEIGHT/10),(int)((WIDTH/9)*1.5)/2, HEIGHT/140);

    //the constructor:
    public MAP() {

        //the following code creates the JFrame
        super("Radical Racing");
        setSize(WIDTH,HEIGHT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        setResizable(false);

        try {
            cUp = this.getClass().getResource("carUp.jpg");
            cLeft = this.getClass().getResource("carLeft.jpg");
            cRight = this.getClass().getResource("carRight.jpg");
        } catch(Exception e) {
        }

        //attach the URLs to the images
        img1 = Toolkit.getDefaultToolkit().getImage(cUp);
        img2 = Toolkit.getDefaultToolkit().getImage(cLeft);
        img3 = Toolkit.getDefaultToolkit().getImage(cRight);

        repaint();
        Move1 m1 = new Move1();
        m1.start();
    }

    //this will draw the cars and the race track
    public void paint(Graphics g) {
        super.paint(g);

        //draw the background for the racetrack
        g.setColor(Color.DARK_GRAY);
        g.fillRect(0,0,WIDTH,HEIGHT);

        //when we draw, the border will be green
        g.setColor(Color.GREEN);

        //fill rectangle
        g.fillRect(left.x,left.y,left.width,left.height);
        g.fillRect(right.x,right.y,right.width,right.height);
        g.fillRect(top.x,top.y,top.width,top.height);
        g.fillRect(bottom.x,bottom.y,bottom.width,bottom.height);
        g.fillRect(center.x,center.y,center.width,center.height);
        g.fillRect(obstacle.x,obstacle.y,obstacle.width,obstacle.height);
        g.fillRect(obstacle2.x,obstacle2.y,obstacle2.width,obstacle2.height);
        g.fillRect(obstacle3.x,obstacle3.y,obstacle3.width,obstacle3.height);
        g.fillRect(obstacle4.x,obstacle4.y,obstacle3.width,obstacle4.height);
        g.fillRect(obstacle5.x,obstacle5.y,obstacle5.width,obstacle5.height);

        //set the starting line color to white
        g.setColor(Color.WHITE);

        //now draw the starting line
        g.fillRect(lineO.x,lineO.y,lineO.width,lineO.height);
        g.fillRect(lineI.x,lineI.y,lineI.width,lineI.height);

        //set the color of the finish line to yellow
        g.setColor(Color.YELLOW);

        //now draw the finish line
        g.fillRect(finish.x,finish.y,finish.width,finish.height);

        //set the color to blue for p1
        g.setColor(Color.WHITE);

        //now draw the actual player
        g.fill3DRect(p1.x,p1.y,p1.width,p1.height,true);

        //draw the images for the player
        if(p1Direction==UP)
        g.drawImage(img1,p1.x,p1.y,this);
        if(p1Direction==LEFT)
            g.drawImage(img2,p1.x,p1.y,this);
        if(p1Direction==RIGHT)
    g.drawImage(img3,p1.x,p1.y,this);
    }

    private class Move1 extends Thread implements KeyListener {
        public void run() {
            //now, this should all be in an infinite loop, so the process
            //repeats
            addKeyListener(this);
            while(true) {
                //now, put the code in a try block. This will let the
                //program exit
                //if there is an error.

                try {
                    //first, refresh the screen:
                    repaint();
                    //increase speed a bit
                    //  if(p1Speed<=5)
                    //  p1Speed+=.2;
                    //p1.y-=(int) p1Speed;
                    if(p1.intersects(left) || p1.intersects(right) || p1.intersects(top) || p1.intersects(bottom) || p1.intersects(obstacle) || p1.intersects(obstacle2)|| p1.intersects(obstacle3) || p1.intersects(obstacle4) || p1.intersects(obstacle5)) {
                        p1Speed = -5;
                    }
                    //if the car hits the center, do the same as above
                    //but make the speed -2.5.
                    if(p1.intersects(center)) {
                        p1Speed = -5;
                    }
                    //increase speed a bit
                    if(p1Speed<=5)
                        p1Speed+=.2;
                    //these will move the player based on direction
                    if(p1Direction==UP) {
                        p1.y-=(int)p1Speed;
                        //repaint();
                    }
                    if(p1Direction==DOWN) {
                        p1.y+=(int)p1Speed;
                        //repaint();
                    }
                    if(p1Direction==LEFT) {
                        p1.x-=(int)p1Speed;
                        //repaint();
                    }
                    if(p1Direction==RIGHT) {
                        p1.x+=(int)p1Speed;
                        //repaint();
                    }
                    //this delays the refresh rate:
                    Thread.sleep(200);

                } catch(Exception e) {
                    //if there is an exception (an error), exit the loop.
                    break;
                }
            }
        }

        @Override
        public void keyPressed(KeyEvent arg0) {
            // TODO Auto-generated method stub
        }

        @Override
        public void keyReleased(KeyEvent arg0) {
            // TODO Auto-generated method stub
        }

        @Override
        public void keyTyped(KeyEvent event) {
            if(event.getKeyChar()=='a') {
                p1Direction = LEFT;
                repaint();
            }
            if(event.getKeyChar()=='s') {
                p1Direction = DOWN;
                repaint();
            }
            if(event.getKeyChar()=='d') {
                p1Direction = RIGHT;
                repaint();
            }
            if(event.getKeyChar()=='w') {
                p1Direction = UP;
                repaint();
            }
        }
    }
    //this starts the program by calling the constructor:
    public static void main (String[ ] args) {
        new MAP();
    }
}

推荐答案

不要在JFrame的paint方法中直接绘制.取而代之的是绘制JPanel或JComponent并覆盖其paintComponent方法,因为默认情况下Swing会进行双缓冲,因此您可以利用它.

Don't draw directly in the JFrame in its paint method. Instead draw in a JPanel or JComponent and override its paintComponent method since Swing does double buffering by default, and this will allow you to take advantage of this.

这篇关于我的JFrame Flickers的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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