Java限制JPanel中的fps

时间:2015-02-26 13:52:03

标签: java swing jpanel

我试图限制程序的fps,因为代码中的球移动方式太快了。 我一直试图用计时器和actionlistener来做,但我不知道如何正确实现它。

主要课程

    package com.company;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;


public class Main extends JPanel implements ActionListener {


    Ball[] balls = new Ball[20];
    Random rand = new Random();
    private final Timer timer = new Timer(40, this);



    Main() {

        for(int i = 0; i<20;i++){
            float r = rand.nextFloat();
            float g = rand.nextFloat();
            float b = rand.nextFloat();
            Color randomColor = new Color(r, g, b);
            balls[i] = new Ball(Ball.randInt(0, 600),Ball.randInt(0, 600),Ball.randInt(10, 50),rand.nextInt(3-1)+1,randomColor,600,600);


        }
    }

    public void paintComponent(Graphics g) {

        super.paintComponent(g);
        for(int i=0;i<20;i++) {
            balls[i].draw(g);
            balls[i].update();
        }

    }


    @Override
    public void actionPerformed(ActionEvent e) {
        this.repaint();
    }


    public static void main(String[] args) {


        Main m = new Main();
        JFrame frame = new JFrame("Title"); //create a new window and set title on window
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //set the window to close when the cross in the corner is pressed
        frame.setSize(600,600);
        frame.add(m); //add the content of the game object to the window
        frame.setVisible(true); //make the window visible



    }


}

球类

package com.company;

import javax.swing.*;
import java.awt.*;
import java.util.Random;
/**
 * Created by John on 25/02/2015.
 */

public class Ball extends JPanel{
    float _speedX;
    float _speedY;
    int _size;
    float _x;
    float _y;
    float _speed;
    Color _color;
    int _windowX;
    int _windowY;




    Ball(int x, int y, int sz, float speed, Color c, int windowX, int windowY){
        _x = x;
        _y = y;
        _speed=speed;
        _speedX = speed;
        _speedY = speed;
        _size = sz;
        _color = c;
        _windowX = windowX;
        _windowY = windowY;



    }



    public void update(){

            _x += _speedX;
            _y += _speedY;

            if (_x+_size<0 || _x+_size>_windowX-_size){
                _speedX*=-1;
            }

            if (_y+_size<0 || _y+_size>_windowY-_size){
                _speedY*=-1;
            }



this.repaint();


    }
    public static int randInt(int min, int max) {
        Random rand = new Random();
        int randomNum = rand.nextInt((max - min) + 1) + min;
        return randomNum;
    }

    public void draw(Graphics g) {
        g.setColor(_color);
        g.fillOval((int)_x,(int) _y, _size, _size);

    }
    }

2 个答案:

答案 0 :(得分:3)

不要从paintComponent()调用update。

球应该从actionPerformed()方法(从Timer调用)改变它们的位置。因此,如果您更改计时器毫秒,则可以使其更快/更慢。

实际上,TImer应该定义重新绘制内容的频率(并更改模型 - contentn元素的位置/大小)

答案 1 :(得分:0)

您不需要将fps锁定到特定值以减慢游戏速度,您只需将更新锁定在定义的时间间隔内发生特定次数的值即可。让我举个例子:

int UPDATES = 60;  // set the updates of the values to 60 per second
int UPDATEUNIT = 1000000; // Just the devider to calc up from nano
long executionStamp = System.nanoTime() / UPDATEUNIT; // the timestamp of the last execution
while(isRunning()) { 
    long now = System.nanoTime() / UPDATEUNIT; // get the current time
    long difference  = now - executionStamp; // get the difference between the last update and the current run
    long interval = MILLI / UPDATES; // a number representing the time that needs to pass for the next value update to happen
    if (difference > interval) {
        _game.updateValues();
        executionStamp = System.nanoTime() / UPDATEUNIT; // set new executiontimestamp
    }
    _game.updateUI(); // Upating the ui should allways be able to have unlimited FPS if you don´t want the user to lock it manually
}