Reputation: 11
Hello I'm building a relatively small 2D Game based off of the Original Snake Using Java and Swing GUI's. I am getting incredibly low FPS counts in the range of ~7 to ~10 FPS even though my application is very small at the moment. All that is displayed to the screen is 4 10x10 PNG's so this is slightly worrying considering what I was hoping to implement.
The code for my main class is given below, and the method I am using to display the FPS is given below that.
public class Board extends JPanel implements ActionListener {
private final int BOARD_WIDTH = 300;
private final int BOARD_HEIGHT = 300;
private final int SEGMENT_SIZE = 10;
private final int MAX_PARTS = (BOARD_WIDTH / SEGMENT_SIZE) * (BOARD_HEIGHT * SEGMENT_SIZE);
private final int DELAY = 140;
private final int RAND_POS = 29;
private final int x[] = new int[MAX_PARTS];
private final int y[] = new int[MAX_PARTS];
private int bodyLen;
private int appleX;
private int appleY;
private boolean rightDirection = true;
private boolean leftDirection = false;
private boolean upDirection = false;
private boolean downDirection = false;
private boolean inGame = true;
private Timer timer;
private Image body;
private Image head;
private Image apple;
private FPSCounter fpscount;
public Board() {
initBoard();
}
private void initBoard() {
fpscount = new FPSCounter();
fpscount.start();
addKeyListener(new TAdapter());
setBackground(Color.black);
setFocusable(true);
setPreferredSize(new Dimension(BOARD_WIDTH, BOARD_HEIGHT));
loadImages();
initGame();
}
private void loadImages() {
ImageIcon app = new ImageIcon("src/main/resources/Apple.png");
apple = app.getImage();
ImageIcon bod = new ImageIcon("src/main/resources/Body.png");
body = bod.getImage();
}
private void initGame() {
bodyLen = 3;
for(int i = 0; i < bodyLen; i++) {
x[i] = 50 - i * 10;
y[i] = 50;
}
getApple();
timer = new Timer(DELAY, this);
timer.start();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
fpscount.frame(); //added line (step 4).
g.drawString("" + fpscount.get(), 5, 22); //added line (step 5).
}
private void doDrawing(Graphics g) {
if (inGame) {
g.drawImage(apple, appleX, appleY, this);
for(int i = 0; i < bodyLen; i++) {
g.drawImage(body, x[i], y[i], this);
}
Toolkit.getDefaultToolkit().sync();
}
}
private void getApple() {
int r = (int) (Math.random() * RAND_POS);
appleX = r * SEGMENT_SIZE;
r = (int) (Math.random() * RAND_POS);
appleY = r * SEGMENT_SIZE;
}
@Override
public void actionPerformed(ActionEvent e) {
if(inGame) {
move();
}
repaint();
}
private void move() {
for(int i = bodyLen; i > 0; i--) {
x[i] = x[i - 1];
y[i] = y[i - 1];
}
if(leftDirection) {
x[0] -= SEGMENT_SIZE;
}
if(rightDirection) {
x[0] += SEGMENT_SIZE;
}
if(upDirection) {
y[0] -= SEGMENT_SIZE;
}
if(downDirection) {
y[0] += SEGMENT_SIZE;
}
}
private class TAdapter extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if((key == KeyEvent.VK_RIGHT) && (!leftDirection)) {
rightDirection = true;
upDirection = false;
downDirection = false;
leftDirection = false;
}
if((key == KeyEvent.VK_LEFT) && (!rightDirection)) {
leftDirection = true;
upDirection = false;
downDirection = false;
rightDirection = false;
}
if((key == KeyEvent.VK_UP) && (!downDirection)) {
upDirection = true;
rightDirection = false;
leftDirection = false;
downDirection = false;
}
if((key == KeyEvent.VK_DOWN) && (!upDirection)) {
downDirection = true;
leftDirection = false;
rightDirection = false;
upDirection = false;
}
}
}
}
FPS Counter Class
private final Timer resetTimer;
private int current, last;
public FPSCounter() {
resetTimer = new Timer(1000, this);
}
public synchronized void start() {
resetTimer.start();
current = 0;
last = -1;
}
public synchronized void stop() {
resetTimer.stop();
current = -1;
}
public synchronized void frame() {
current++;
}
@Override
public void actionPerformed(ActionEvent e) {
last = current;
current = 0;
}
public synchronized int get() {
return last;
}
}
Maybe it's just my FPS Counter class that is off but any information you could give that might be able to solve this issue would be greatly appreciated.
Upvotes: 1
Views: 454
Reputation: 324088
private final int DELAY = 140;
Your delay is 140.
So your frames per second will be 1000 / 140 = 7.14.
Typically people aim for a frame rate of 60. So you should use a delay of 1000 / 60 = 16.
Upvotes: 1