在模拟全屏和窗口模式下抖动的动态图像

时间:2019-02-20 23:03:57

标签: java 2d

因此,我正在为我的游戏测试不同的屏幕尺寸。我测试的最佳屏幕尺寸是java API中的排他性全屏模式。但是,我想在我的游戏中实现SFS(模拟全屏)和窗口模式,以防客户端不支持独占全屏模式。问题是,当我使用窗口式或SFS格式时,在屏幕上移动时图像会抖动。在窗口和SFS中,我将游戏的fps(每秒帧数)设置为60,在独占全屏模式下,我只运行了update和draw方法而没有设置fps的设置,因为从我观察到的情况来看,看起来Java会自动为游戏设置上限fps到60。当我的游戏在独占全屏模式下运行时,图像像丝绸一样平滑移动。但是,在其他屏幕模式下,图像在移动时会抖动。

问题#1:如何使我的游戏在窗口和SFS模式下流畅运行?我尝试了各种尝试,例如将游戏循环放入edt(Event Dispatch Thread),但问题仍然存在。

问题2:为什么在使用独家全屏模式时,我的fps设置为60 fps?我认为这是因为我的显示器速率为60hertz或图形卡显示模式设置为60hertz(1360 x 768,真彩色(32位),60 Hz)。我试图将768 True True Color(32位),75 Hz的显卡显示模式更改为1024,而fps仍然限制为60。

问题3:当我在其他计算机上运行游戏时,例如比我的计算机快的计算机。一台具有144hz刷新率的显示器和一个显示模式高于我的图形卡的图形卡,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;
    }
  }
}

0 个答案:

没有答案