Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
限制不同计算机上的游戏速度 我用OpenGL和C++来创建一个2D游戏。_C++_Opengl_Performance - Fatal编程技术网

限制不同计算机上的游戏速度 我用OpenGL和C++来创建一个2D游戏。

限制不同计算机上的游戏速度 我用OpenGL和C++来创建一个2D游戏。,c++,opengl,performance,C++,Opengl,Performance,我想让游戏在不同的电脑上以相同的速度运行,此时我的游戏在我的桌面上运行的速度比我的笔记本电脑快(即,我的玩家在我的桌面上移动得更快) 有人告诉我QueryPerformanceCounter(),但我不知道如何使用它 我如何使用它,或者有更好/更简单的方法吗 我的显示功能 void display() { static long timestamp = clock(); // First frame will have zero

我想让游戏在不同的电脑上以相同的速度运行,此时我的游戏在我的桌面上运行的速度比我的笔记本电脑快(即,我的玩家在我的桌面上移动得更快)

有人告诉我QueryPerformanceCounter(),但我不知道如何使用它

我如何使用它,或者有更好/更简单的方法吗

我的显示功能

void display()                                  
{
static long timestamp = clock();
// First frame will have zero delta, but this is just an example.
float delta = (float)(clock() - timestamp) / CLOCKS_PER_SEC;

glClear(GL_COLOR_BUFFER_BIT);

glLoadIdentity();

createBackground();

int curSpeed = (player.getVelocity()/player.getMaxSpeed())*100;

glColor3f(1.0,0.0,0.0);
glRasterPos2i(-screenWidth+20,screenHeight-50);
glPrint("Speed: %i",curSpeed);

glRasterPos2i(screenWidth-200,screenHeight-50);
glPrint("Lives: %i",lives);

glRasterPos2i(screenWidth-800,screenHeight-50);
glPrint("Heading: %f",player.getHeading());

for(int i = 0;i<90;i++){
    if (numBullets[i].fireStatus == true){
        numBullets[i].updatePosition(player);
        if (numBullets[i].getXPos() > screenWidth || numBullets[i].getXPos() < -screenWidth || numBullets[i].getYPos() > screenHeight || numBullets[i].getYPos() < -screenHeight ){
            numBullets[i].fireStatus = false;
            numBullets[i].reset(player);
            numBullets[i].~Bullet();
        }
    }
}

player.updatePosition(playerTex,delta);

glFlush();

timestamp = clock();

大多数游戏使用帧时间比例因子。基本上,您可以找到物理和运动设置的帧长度,并将其除以游戏运行时帧的实际长度(1/fps)。这将生成一个标量因子,您可以将该因子乘以运动的变化,以保持所有运动的一致性,同时保持增加FPS带来的好处


一个很好的例子是

通常,您希望根据时间增量(即自上一帧以来经过的时间)进行所有游戏性计算。这将使所有机器的速度标准化。除非您需要极高的精度,否则可以使用
clock()
(来自
)获取当前时间戳

例如:

void main_loop() {
   static long timestamp = clock();
   // First frame will have zero delta, but this is just an example.
   float delta = (float)(clock() - timestamp) / CLOCKS_PER_SEC;

   calculate_physics(delta);
   render();

   timestamp = clock();
}

void calculate_physics(float delta) {
   // Calculate expected displacement per second.
   applyDisplacement(displacement * delta);
}

void render() {
   // Do rendering.
}
编辑:如果您想要更高的精度,应该使用操作系统计时器功能。在Windows上,最精确的方法是使用
QueryPerformanceCounter()
。范例

#include <windows.h>

void main_loop(double delta) {
  // ...
}

int main() {
  LARGE_INTEGER freq, last, current;
  double delta;
  QueryPerformanceFrequency(&freq);

  QueryPerformanceCounter(&last);
  while (1) {
    QueryPerformanceCounter(&current);
    delta = (double)(current.QuadPart - last.QuadPart) / (double)freq.QuadPart;

    main_loop(delta);

    last = current;
  }
}
#包括
空主回路(双三角){
// ...
}
int main(){
大整数频率,最后一个,当前;
双三角洲;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&last);
而(1){
QueryPerformanceCounter(¤t);
delta=(双精度)(current.QuadPart-last.QuadPart)/(双精度)freq.QuadPart;
主回路(三角洲);
last=当前值;
}
}

解决问题的最佳方法是每10毫秒(或类似时间)只更新一次对象的位置,但要尽可能频繁地渲染对象。这被称为“固定时间步长”,因为您只在固定的时间间隔更新游戏状态。这需要将渲染代码与更新代码分离(这是一个好主意)

基本上(在psudoe代码中),您将执行以下操作:

accumulatedTimeSinceLastUpdate = 0;
while(gameIsRunning)
{
  accumulatedTimeSinceLastUpdate += timeSinceLastFrame();
  while(accumulatedTimeSinceLastUpdate >= 10) // or another value
  {
    updatePositions();
    accumulatedTimeSinceLastUpdate -= 10;
  }
  display();
}
这意味着,如果您的计算机正在运行super duper fast display(),它将被多次调用,并且会时不时地调用updatePositions()。如果您的计算机更新速度非常慢,则每次调用display()时,可能会多次调用位置

下面是另一本好书(除了梅森·布利尔的):


它只是做动画的任何函数的占位符。所以delta是我应用于所有动画的一个值,所以它们在任何地方都以相同的速度工作?是的。典型调用中delta的值因机器而异,具体取决于每台机器可以挤出的帧速率。将增量应用到动画的大小将消除差异。谢谢,我可以只做一次并重用相同的值吗?或者它需要在每个循环上计算吗?它是在每个帧上计算的,就像在示例代码中一样。我记得我在20世纪80年代的游戏中遇到过这个问题。尽管当时PC机上有时钟,但并不是所有的游戏开发者都在使用它们,我们称之为固定时间步循环。
accumulatedTimeSinceLastUpdate = 0;
while(gameIsRunning)
{
  accumulatedTimeSinceLastUpdate += timeSinceLastFrame();
  while(accumulatedTimeSinceLastUpdate >= 10) // or another value
  {
    updatePositions();
    accumulatedTimeSinceLastUpdate -= 10;
  }
  display();
}