我有一個FPS計數器的乒乓遊戲,但我有一些問題。我希望FPS計數器不被限制在60 FPS,我希望FPS計數器儘可能高。Pong遊戲運行速度過快FPS計數器
FPS目前正在運行,但問題是遊戲運行速度非常快,我希望遊戲始終以可播放的速度運行。我試圖添加一個計時器5毫秒,但導致FPS計數器無法正常工作。
我希望FPS計數器不限制在60 FPS,但同時使用某種計時器。這裏是我的代碼:
package Game;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
public class Main extends JPanel implements KeyListener, ActionListener{
// Lite variabler
JFrame frame;
int windowWidth, windowHeight;
Point bollXY;
int screenWidth, screenHeight;
Image bildPaddel;
Image bildBollen;
int paddelY;
int paddel2Y;
boolean paddelUp, paddelDown;
Random rand;
int score, score2;
boolean bollUp, bollRight, changeDirection;
int fruktDistansRand;
long time;
int fps, newfps;
int fpsTimesCounter;
// Konstruktor
public Main(){
// Definera variabler
frame = new JFrame();
bildPaddel = new ImageIcon("src/images/Player.png").getImage();
bildBollen = new ImageIcon("src/images/Pong.png").getImage();
bollXY = new Point(673, 352);
paddelY = 312;
paddel2Y = 312;
paddelUp = false;
rand = new Random();
score = 0;
score2 = 0;
bollUp = false;
bollRight = false;
changeDirection = false;
fruktDistansRand = 0;
time = System.currentTimeMillis();
fps = 0;
newfps = 0;
fpsTimesCounter = 0;
// Lyssnare
frame.addKeyListener(this);
// Bygga fönstret
frame.add(this);
// Obligatoriska egenskaper
frame.setTitle("Pong");
frame.setSize(1366, 724); // Eftersom spelet inte ska vara helt i fullskärm sätts fönstret på 1366x724 så att aktivitetsfältet syns
frame.setVisible(true);
frame.setLocationRelativeTo(null); // Centrerar fönstret
frame.setResizable(false);
this.setBackground(Color.BLACK);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
bollUp = true;
bollRight = true;
changeDirection = false;
bollXY = new Point();
frame.add(this);
}
// Metoder
public static void main(String[] args) {
new Main();
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(bildBollen, bollXY.x, bollXY.y, null);
g.drawImage(bildPaddel, 50, paddelY, null);
g.drawImage(bildPaddel, 1300, paddel2Y, null);
g.setFont(new Font("Arial", Font.BOLD, 100));
g.setColor(Color.WHITE);
g.drawString(score2 + "", 1002, 100);
g.drawString(score + "", 314, 100);
if(System.currentTimeMillis() - time >= 1000){
time = System.currentTimeMillis();
fps = newfps;
newfps = 0;
}
else{
newfps++;
}
g.setFont(new Font("Arial", Font.BOLD, 25));
g.drawString(fps + "", 5, 22);
update();
}
public void AI(){
fruktDistansRand = rand.nextInt(200) + 950;
if(bollXY.x > fruktDistansRand && bollXY.x < 1380 && bollRight && paddel2Y > 0 && paddel2Y < 596){
if(paddel2Y + 50 < bollXY.y){
paddel2Y = paddel2Y + 3;
}
else{
paddel2Y = paddel2Y - 3;
}
if(paddel2Y <= 0){
paddel2Y = paddel2Y + 3;
}
if(paddel2Y >= 596){
paddel2Y = paddel2Y - 3;
}
}
}
public void ifUp(){
if(bollUp){
if(changeDirection){
if(bollXY.y < 0){
bollUp = false;
}
else{
bollXY.y = bollXY.y - 3;
}
}
else{
if(bollXY.y < 0){
bollUp = false;
}
else{
bollXY.y = bollXY.y - 3;
}
}
}
else{
if(changeDirection){
if(bollXY.y > 675){
bollUp = true;
}
else{
bollXY.y = bollXY.y + 3;
}
}
else{
if(bollXY.y > 675){
bollUp = true;
}
else{
bollXY.y = bollXY.y + 3;
}
}
}
}
public void update(){
if(paddelUp){
if(paddelY > 0){
paddelY = paddelY - 3;
}
}
if(paddelDown){
if(paddelY < 596){
paddelY = paddelY + 3;
}
}
if(bollRight){
if(bollXY.x > 1290 && bollXY.x < 1300 && bollXY.y < paddel2Y + 100 && bollXY.y > paddel2Y-20){
if(!bollUp && bollXY.y < paddel2Y){
changeDirection = true;
bollUp = true;
}
else if(bollUp && bollXY.y > paddel2Y + 80){
changeDirection = true;
bollUp = false;
}
bollRight = false;
}
else if(bollXY.x > 1600){
score++;
bollXY.y = rand.nextInt(690);
bollXY.x = 678;
}
else
bollXY.x = bollXY.x + 3;
ifUp();
}
else{
if(bollXY.x > 50 && bollXY.x < 60 &&bollXY.y < paddelY + 100 && bollXY.y > paddelY-20){
if(!bollUp && bollXY.y < paddelY){
changeDirection = true;
bollUp = true;
}
else if(bollUp && bollXY.y > paddelY + 80){
changeDirection = true;
bollUp = false;
}
bollRight = true;
}
else if(bollXY.x < -244){
score2++;
bollXY.x = 678;
bollXY.y = rand.nextInt(596);
}
else
bollXY.x = bollXY.x - 3;
ifUp();
}
AI();
repaint();
}
@Override
public void actionPerformed(ActionEvent e) {
update();
}
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_W || e.getKeyCode() == KeyEvent.VK_UP){
paddelUp = true;
}
if(e.getKeyCode() == KeyEvent.VK_S || e.getKeyCode() == KeyEvent.VK_DOWN){
paddelDown = true;
}
}
@Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_W || e.getKeyCode() == KeyEvent.VK_UP){
paddelUp = false;
}
if(e.getKeyCode() == KeyEvent.VK_S || e.getKeyCode() == KeyEvent.VK_DOWN){
paddelDown = false;
}
}
@Override
public void keyTyped(KeyEvent e) {
}
}
這似乎是一個語義問題;如果遊戲沒有重繪速度超過60fps,爲什麼櫃檯顯示的東西更高? –
不要從paintComponent調用更新。不知道你想用這種方法做什麼。它應該有如何繪製面板的指示,沒有別的。 – Steven
我很困惑,爲什麼你想要fps與幀更新的實際速率不同?在任何情況下,您都想單獨更新遊戲狀態,否則它們將被綁定到相同的時間間隔,或者基於時間流逝而不是固定的進行移動。我認爲儘可能快地在重新繪製中看不到太多好處,但這不是必要的。 –