Vector 中的 1000 多个游戏对象太慢了吗?我的错误是什么?
1000+ Game-Objects in Vector too slow? What is my mistake?
我目前正在开发一款游戏,需要跟踪很多对象。
我有一个游戏对象class,它保存了对象的所有必要信息并在 update() 上处理 AI();
我决定,只有有大脑的物体才需要每一帧更新。所以我分离了向量以节省时间。但是,我在绘制对象时似乎找不到类似的解决方案。所以我得到了
std::vector<cOBJECT*> LivingObjects;
和
std::vector<cOBJECT*> WorldObjects;
绘制所有对象时,我首先将所有对象放在一个RenderList中:
//Add World and Living Objects into one list of RenderObjects
RenderObjects = WorldObjects;
RenderObjects.insert(RenderObjects.end(), LivingObjects.begin(), LivingObjects.end());
然后我按Y排序:
//Sort all Objects by Y (bottom) Coordiante
sort(RenderObjects.begin(), RenderObjects.end(), cmd);
这是它的代码(也许这也很慢?:
//Sorts by Y-Coordinaté
bool cmd(cOBJECT* obj1, cOBJECT* obj2)
{
return obj1->getrect().y + obj1->getrect().h < obj2->getrect().y + obj2->getrect().h;
}
然后我画它们。绘图功能将检查它们是否在屏幕上!所以我只画可见的物体:
//DRAW OBJECTS and
for (std::vector<cOBJECT*>::size_type i = 0; i != RenderObjects.size(); i++)
{
RenderObjects[i]->render(Renderer, CameraX, CameraY, SCREEN_WIDTH, SCREEN_HEIGHT);
}
这是实际的绘制函数´:
int cTEXTURES::renderAnimation(int targetX, int targetY, double angle, SDL_Point* center, SDL_RendererFlip flip, SDL_Renderer* Renderer, int row, int speed, int offX, int offY, int SCREEN_HEIGHT, int SCREEN_WIDTH)
{
//Draw if part of it shown on screen
if (targetX - offX >= -FrameWidth && targetX - offX <= SCREEN_WIDTH + FrameWidth && targetY - offY >= -FrameHeight && targetY - offY <= SCREEN_HEIGHT + FrameHeight)
{
SDL_Rect SourceRect;
SDL_Rect TargetRect;
TargetRect = { targetX - offX, targetY - offY, FrameWidth, FrameHeight };
SourceRect.x = (CurrentFrame - 1) * FrameWidth;
SourceRect.y = (row - 1) * FrameHeight;
SourceRect.w = FrameWidth;
SourceRect.h = FrameHeight;
if (OldTime + speed > SDL_GetTicks()) { SDL_RenderCopyEx(Renderer, TheTextureManager::Instance()->TextureList[TexturePath], &SourceRect, &TargetRect, angle, center, flip); return 0; }
OldTime = SDL_GetTicks();
//SDL_RenderCopyEx(Renderer, TheTextureManager::Instance()->TextureList[TexturePath], &SourceRect, &TargetRect, angle, center, flip);
TheTextureManager::Instance()->draw(TexturePath, Renderer, &SourceRect, &TargetRect, angle, center, flip);
CurrentFrame++;
if (CurrentFrame == (Frames + 1))
{
CurrentFrame = 1;
return 1; // returns 1 if one row is finished
}
return 0; // returns 0 if animation is not finished
}
return 0;
}
现在我得到了 1000 多个对象,以后可能会达到 2000 多个。只是运行通过for-loop来检查是否需要绘制对象是很耗时的吧?
我错过了什么?如果 CPU 没有如此大量的工作,我如何才能跟踪 1000 多个对象并知道是否要绘制它们?特别是因为我需要很多空间来容纳很多 AI
谢谢,这让我抓狂。
为了在调试构建中加速 stl 容器的迭代器(以及由于 header 解析而产生的编译时间)在第一个 header(或预编译的 header)之前包含以下行包括任何其他内容(例如 "windows.h" header):
#ifdef _WIN32
# define _CRT_SECURE_NO_WARNINGS // disable the Microsoft specific warnings about _s buffer underrun security issues for ISO methods (fopen, strcpy etc..)
# define VC_EXTRALEAN // cut down includes
# define WIN32_LEAN_AND_MEAN // cut down includes
# undef _SECURE_SCL // iterators generate less overhead code in debug
# if _ITERATOR_DEBUG_LEVEL > 0
# define _SECURE_SCL 1
# else
# define _SECURE_SCL 0
# endif
#endif
如果您 link 到具有不同 iterator_debug_levels.
的其他库,_iterator_debug_level 设置可能会有点棘手
这将使您的调试构建 运行 快很多,但如果需要性能,通常需要重新审视容器的使用情况,最后滚动自己的容器是最后的选择如果您的操作复杂或具体。
我目前正在开发一款游戏,需要跟踪很多对象。
我有一个游戏对象class,它保存了对象的所有必要信息并在 update() 上处理 AI();
我决定,只有有大脑的物体才需要每一帧更新。所以我分离了向量以节省时间。但是,我在绘制对象时似乎找不到类似的解决方案。所以我得到了
std::vector<cOBJECT*> LivingObjects;
和
std::vector<cOBJECT*> WorldObjects;
绘制所有对象时,我首先将所有对象放在一个RenderList中:
//Add World and Living Objects into one list of RenderObjects
RenderObjects = WorldObjects;
RenderObjects.insert(RenderObjects.end(), LivingObjects.begin(), LivingObjects.end());
然后我按Y排序:
//Sort all Objects by Y (bottom) Coordiante
sort(RenderObjects.begin(), RenderObjects.end(), cmd);
这是它的代码(也许这也很慢?:
//Sorts by Y-Coordinaté
bool cmd(cOBJECT* obj1, cOBJECT* obj2)
{
return obj1->getrect().y + obj1->getrect().h < obj2->getrect().y + obj2->getrect().h;
}
然后我画它们。绘图功能将检查它们是否在屏幕上!所以我只画可见的物体:
//DRAW OBJECTS and
for (std::vector<cOBJECT*>::size_type i = 0; i != RenderObjects.size(); i++)
{
RenderObjects[i]->render(Renderer, CameraX, CameraY, SCREEN_WIDTH, SCREEN_HEIGHT);
}
这是实际的绘制函数´:
int cTEXTURES::renderAnimation(int targetX, int targetY, double angle, SDL_Point* center, SDL_RendererFlip flip, SDL_Renderer* Renderer, int row, int speed, int offX, int offY, int SCREEN_HEIGHT, int SCREEN_WIDTH)
{
//Draw if part of it shown on screen
if (targetX - offX >= -FrameWidth && targetX - offX <= SCREEN_WIDTH + FrameWidth && targetY - offY >= -FrameHeight && targetY - offY <= SCREEN_HEIGHT + FrameHeight)
{
SDL_Rect SourceRect;
SDL_Rect TargetRect;
TargetRect = { targetX - offX, targetY - offY, FrameWidth, FrameHeight };
SourceRect.x = (CurrentFrame - 1) * FrameWidth;
SourceRect.y = (row - 1) * FrameHeight;
SourceRect.w = FrameWidth;
SourceRect.h = FrameHeight;
if (OldTime + speed > SDL_GetTicks()) { SDL_RenderCopyEx(Renderer, TheTextureManager::Instance()->TextureList[TexturePath], &SourceRect, &TargetRect, angle, center, flip); return 0; }
OldTime = SDL_GetTicks();
//SDL_RenderCopyEx(Renderer, TheTextureManager::Instance()->TextureList[TexturePath], &SourceRect, &TargetRect, angle, center, flip);
TheTextureManager::Instance()->draw(TexturePath, Renderer, &SourceRect, &TargetRect, angle, center, flip);
CurrentFrame++;
if (CurrentFrame == (Frames + 1))
{
CurrentFrame = 1;
return 1; // returns 1 if one row is finished
}
return 0; // returns 0 if animation is not finished
}
return 0;
}
现在我得到了 1000 多个对象,以后可能会达到 2000 多个。只是运行通过for-loop来检查是否需要绘制对象是很耗时的吧?
我错过了什么?如果 CPU 没有如此大量的工作,我如何才能跟踪 1000 多个对象并知道是否要绘制它们?特别是因为我需要很多空间来容纳很多 AI
谢谢,这让我抓狂。
为了在调试构建中加速 stl 容器的迭代器(以及由于 header 解析而产生的编译时间)在第一个 header(或预编译的 header)之前包含以下行包括任何其他内容(例如 "windows.h" header):
#ifdef _WIN32
# define _CRT_SECURE_NO_WARNINGS // disable the Microsoft specific warnings about _s buffer underrun security issues for ISO methods (fopen, strcpy etc..)
# define VC_EXTRALEAN // cut down includes
# define WIN32_LEAN_AND_MEAN // cut down includes
# undef _SECURE_SCL // iterators generate less overhead code in debug
# if _ITERATOR_DEBUG_LEVEL > 0
# define _SECURE_SCL 1
# else
# define _SECURE_SCL 0
# endif
#endif
如果您 link 到具有不同 iterator_debug_levels.
的其他库,_iterator_debug_level 设置可能会有点棘手这将使您的调试构建 运行 快很多,但如果需要性能,通常需要重新审视容器的使用情况,最后滚动自己的容器是最后的选择如果您的操作复杂或具体。