Дрожание движущегося изображения в симулированном полноэкранном и оконном режиме - PullRequest
0 голосов
/ 21 февраля 2019

Итак, я тестировал разные размеры экрана для своей игры.Наилучшим размером экрана, который я тестировал, был эксклюзивный полноэкранный режим в Java API.Но я хочу реализовать в моей игре SFS (имитированный полноэкранный режим) и оконный режим на случай, если клиент не поддерживает эксклюзивный полноэкранный режим.Проблема в том, что при использовании оконного или SFS мои изображения дрожат при движении по экрану.В оконном и SFS я ограничиваю свои fps (кадров в секунду) до 60. В эксклюзивном полноэкранном режиме я просто запускаю методы обновления и рисования, не ограничивая fps, потому что из того, что я наблюдал, похоже, что java автоматически перекрывает мою игруfps до 60. Когда моя игра работает в эксклюзивном полноэкранном режиме, изображения плавно переходят в шелк.Однако в режиме другого экрана изображения дрожат при движении.

Вопрос № 1: Как сделать так, чтобы моя игра работала гладко в оконном режиме и режиме SFS?Я пробовал различные попытки, такие как помещение игрового цикла в edt (Thread Dispatch Thread), и проблема все еще сохраняется.

Вопрос № 2: Почему мой fps ограничен 60 кадрами в секунду при использовании эксклюзивного полноэкранного режима?Я предполагаю, что это потому, что частота моего монитора составляет 60 Гц, или режим отображения моей видеокарты установлен на 60 Гц (1360 на 768, True Color (32 бита), 60 Гц).Я попытался изменить режим отображения видеокарты на 1024 на 768 True Color (32 бита), 75 герц, а частота кадров все еще ограничена до 60.

Вопрос № 3: когда я запускаю свою игру на другой машине, напримермашина, которая быстрее моей, например, монитор с частотой обновления 144 Гц и видеокарта с режимом отображения выше, чем у моей видеокарты, java все еще ограничивает мои игровые fps до 60 на этой машине?

Я надеюсь, что кто-то может мне помочь в этом.

Вот ссылка, которую я использовал в эксклюзивном полноэкранном режиме: https://docs.oracle.com/javase/tutorial/extra/fullscreen/index.html

Вот мой тестовый код

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.awt.*;

import java.awt.image.BufferedImage;
import java.awt.image.BufferStrategy;
import java.awt.geom.AffineTransform;

import javax.swing.*;
import javax.imageio.*;

import java.io.File;

public class ScreenTest extends JFrame
{
private static ScreenTest st;

private Graphics2D g2dbf;
//
private Graphics g;

private BufferedImage bgImage;

private Canvas frameCanvas;
//JFrame size
private int frameWidth,frameHeight;

//Identity transform
private AffineTransform identityTrans;
//Object transform
private AffineTransform objTrans;
//
private BufferStrategy bufferS;

//platform's graphics attributes...
GraphicsEnvironment ge;
GraphicsDevice gd;
GraphicsConfiguration gc;

private double posX, posY;
private double velX, velY;

private BufferedImage myImg;

ScreenTest()
{
    //JFrame properties
    setTitle("Screen Test");
    setIgnoreRepaint(true);
    setResizable(false);
    //setUndecorated(true);

    // Get platform's graphics attributes...
    ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    gd = ge.getDefaultScreenDevice();
    gc = gd.getDefaultConfiguration();

    //Set transform to identity transform
    identityTrans = new AffineTransform();
    //object transform
    objTrans = new AffineTransform();

    //Exclusive Full Screen Mode
    /*
    gd.setFullScreenWindow( this );
    if( gd.isDisplayChangeSupported() ) {
    DisplayMode dm = gd.getDisplayMode();
    frameWidth = dm.getWidth();
    frameHeight = dm.getHeight();

    gd.setDisplayMode( new DisplayMode( frameWidth, frameHeight, dm.getBitDepth(), DisplayMode.REFRESH_RATE_UNKNOWN ));
    }
    */

    //Simulated full screen mode
    //Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    //frameWidth = (int)screenSize.getWidth();
    //frameHeight = (int)screenSize.getHeight();

    //Windowed Mode
    frameWidth = 640;
    frameHeight = 480;

    try { myImg = ImageIO.read(new File("img.png")); }
    catch(IOException e){ System.err.println(e); }

    posX = frameWidth/2;
    posY = frameHeight/2;

    velX = 0;
    velY = -4;

    frameCanvas = new Canvas();
    frameCanvas.setIgnoreRepaint( true );
    frameCanvas.setSize( frameWidth, frameHeight );

    add(frameCanvas);
    pack();
    setVisible(true);


    frameCanvas.createBufferStrategy( 2 );
    bufferS = frameCanvas.getBufferStrategy();

    //back buffer image
    bgImage = gc.createCompatibleImage(frameWidth,frameHeight);

}

void update_Game()
{
    updateImg(); 
}

void drawGraphics()
{
    try
    {
        String str1 = String.format("Velocity X: %.2f",velX);
        String str2 = String.format("Velocity Y: %.2f",velY);

        g2dbf = bgImage.createGraphics();
        g2dbf.setTransform(identityTrans);
        //set background
        g2dbf.setPaint(Color.BLACK);
        g2dbf.fillRect(0,0,frameWidth,frameHeight);

        drawImg();


        //print some status information
        g2dbf.setColor(Color.WHITE);
        g2dbf.drawString("Image: " + Math.round(posX) + "," +
            Math.round(posY) , 5, 40);
        g2dbf.drawString(str1, 5, 60);
        g2dbf.drawString(str2, 5, 80);

        g = bufferS.getDrawGraphics();
        g.drawImage(bgImage,0,0,null);

        if( !bufferS.contentsLost() ) bufferS.show();
    }
    finally
    {
        if(g != null) g.dispose();
        if(g2dbf != null) g2dbf.dispose();
    }
}

void drawImg()
{
    g2dbf.setTransform(identityTrans);
    objTrans.setToIdentity();
    objTrans.translate(posX, posY);
    g2dbf.drawImage(myImg,objTrans,null);
}

void updateImg()
{

    posX += velX;
    posY += velY;

    if (posX < -70) posX = frameWidth + 10;
    else if (posX > frameWidth + 10) posX = -10;

    if (posY < -10) posY = frameHeight + 10;
    else if (posY > frameHeight + 10) posY = -10;

}

public static void main(String[]args) throws InterruptedException,InvocationTargetException
{

    SwingUtilities.invokeAndWait(new Runnable(){
        @Override
        public void run()
        {
           st = new ScreenTest();
        }
    });

     int fps = 0;
     int frames = 0;
     long totalTime = 0,t2 = 0;
     long startTime = 0;
     long endTime = 0;
     final short FRAMES_PER_SECOND = 60;
     final int NANOS_PER_SECOND = 1_000_000_000;
     final float FRAMES_PER_NANO = NANOS_PER_SECOND / FRAMES_PER_SECOND;

    while(true)
    {

          startTime = System.nanoTime();

          if( totalTime > NANOS_PER_SECOND ) {
            System.out.println("FPS: " + frames);
            totalTime -= NANOS_PER_SECOND;
            fps = frames;
            frames = 0;
          } 

          //For Simulated Full Screen and Windowed Mode
          if(t2 > FRAMES_PER_NANO)
          {
              st.drawGraphics();
              st.update_Game();
              frames += 1;
              t2 -= FRAMES_PER_NANO;
          }

          //For Full Screen Exclusive Mode
          //st.drawGraphics();
          //st.update_Game();
          //frames += 1;              


          Thread.yield();

          endTime = System.nanoTime();
          totalTime += endTime - startTime;
          t2 += endTime - startTime;
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...