簡體   English   中英

Java中的repaint()方法是否需要計時器或動作?

[英]Does the repaint() method in Java require a timer or action?

我一直在研究一個小的“游戲”,我認為它叫做Pachinko。 我上傳了游戲畫面的圖像。 我將放下球,讓它們看起來像是從釘子上滾下來,最終陷入底部的“門”中。

我的問題是我無法使repaint()方法正常工作。 repaint()方法是否需要計時器或動作才能起作用? 請看一下這兩個類。 我已經在GameWindow類(位於底部附近)內創建了一個Ball類對象,並想使用BallsetPos()方法更新球的x / y值,然后重新繪制,因此球似乎在移動。

我究竟做錯了什么? 我需要一個update()方法來使用repaint()方法嗎?

游戲窗口圖片:

游戲窗口圖片

public class GameWindow extends JPanel{

    private int numBalls = 0;

    // GameWindow Constructor (Sets Ball amount from user)
    public GameWindow(int balls){

        JFrame myFrame = new JFrame("Game Window");
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Globally set ball amount
        setBallAmount(balls);

        myFrame.add(this);  

        myFrame.setSize(325, 790);
        myFrame.setLocationRelativeTo(this);
        myFrame.setResizable(false);
        myFrame.setVisible(true);

    } // End GameWindow Constructor

    // Function setPegAmount;
    // Passes the amount of balls the user to class variable.
    public void setBallAmount(int balls)
    {
        numBalls = balls * 2;
    }

    public void paintComponent(Graphics g){

        super.paintComponent(g); // housekeeping, etc.
        this.setBackground(Color.WHITE); // Background

        int counter = 0; // count what number peg we are painting
        int row = 1;     // calculate what row we are creating
        int rowSpacer = 55;
        boolean evenRow = false;
        int columnSpacer = 60;

        // DRAW PEGS TO SCREEN (4 rows of 8, 4 rows of 7)
        for (int x = 0; x < 60; x++)
        {
            // For odd rows
            if (row % 2 == 1)
            {
                g.setColor(Color.BLACK);
                g.fillOval(rowSpacer - 40, columnSpacer, 10, 10);
                rowSpacer += 40;
                counter++;
            }
            // For Even rows
            else 
            {
                g.setColor(Color.BLACK);
                g.fillOval(rowSpacer - 20, columnSpacer, 10, 10);
                rowSpacer += 40;
                counter++;
            }

            // Check to see if we are finished with odd row
            if (counter % 8 == 0 && evenRow == false)
            {
                row++;
                rowSpacer = 55;
                columnSpacer += 60;
                evenRow = true;
                counter = 0;
            }
            else if(counter % 7 == 0 && evenRow == true) 
            {
                row++;
                rowSpacer = 55;
                columnSpacer += 60;
                evenRow = false;
                counter = 0;
            }
        } // END DRAWING PEGS TO SCREEN

        // DRAW RECTANGULAR WALLS TO SCREEN
        g.setColor(Color.BLACK);    // Wall Color
        g.fillRect(0, 0, 5, 760);   // LEFT Wall
        g.fillRect(315, 0, 5, 760); // RIGHT Wall
        g.fillRect(0, 0, 315, 5);   // TOP Wall
        g.fillRect(0, 755, 320, 5); // BOTTOM Wall

        // DRAW BOTTOM GATES
        int gateSeperator = 35;
        for (int x = 0; x < 7; x++)
        {
            g.setColor(Color.BLACK);
            g.fillRect(gateSeperator, 500, 10, 255);
            gateSeperator += 40;
        }

        // Create instance of ball object
        Ball myBall = new Ball();

        // Test draw ball
        myBall.drawBall(g);    // The ball is drawn to screen
        myBall.setPos(50, 50); // Change the x and y coordinates of the Ball

        repaint(); // Also tried "this.repaint();" but neither does anything


    } // Ends paintComponent

} // End GameWindow Class

Ball.java:

public class Ball{

    private int x = 5;
    private int y = 30;

    public void setPos(int xPos, int yPos)
    {
        x = xPos;
        y = yPos;
    }

    public void drawBall(Graphics g)
    {
        g.setColor(Color.GREEN);
        g.fillOval(x, y, 30, 30);

    }
}

我不認為這是這樣做的方式。 Swing不是我的專長,但是根據我的經驗,在paintComponent調用repaint是不正確的。

例如,告訴組件repaint自身。

/**
 * Tells the view to repaint itself.
 */
public void update() {
    repaint();
}

盡快repaint最終通過paint調用paintComponent

/**
 * Paints the component.
 * @param g The graphics object for the view.
 */
@Override
protected void paintComponent(Graphics g) {
    // Draw some stuff...
}

因此,在paintComponent內調用repaint可能不是您想要的。 您應該做的是使用repaint來調用paintComponent

我認為您不能依靠將repaintupdate放在paintComponent的末尾,因為我相信,多次repaint調用會集中到單個update 因此,是的,要正確設置對象的動畫,您應該使用Swing Timer 例如,

Timer timer = Timer(delay, action);
timer.start();

上面的計時器將以毫秒為單位調用給定的動作。 請參閱以獲取更多詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM