C++ SDL和c++;——在玩家身后留下痕迹的更有效方法?

C++ SDL和c++;——在玩家身后留下痕迹的更有效方法?,c++,performance,sdl,trail,C++,Performance,Sdl,Trail,所以我是SDL的新手,我正在尝试做一个小型滑雪板游戏。当玩家下山时,我想在他身后留下一条褪色的雪迹。目前,我的工作方式是使用一个数组(包含1000个元素)来存储玩家的最后位置。然后每一帧,我有一个for循环,循环1000次,画出玩家最后1000个位置的轨迹纹理 我觉得这是非常低效的,我正在寻找一些更好的选择 守则: void Player::draw() { if (posIndex >= 1000) { posIndex = 0; } f

所以我是SDL的新手,我正在尝试做一个小型滑雪板游戏。当玩家下山时,我想在他身后留下一条褪色的雪迹。目前,我的工作方式是使用一个数组(包含1000个元素)来存储玩家的最后位置。然后每一帧,我有一个for循环,循环1000次,画出玩家最后1000个位置的轨迹纹理

我觉得这是非常低效的,我正在寻找一些更好的选择

守则:

void Player::draw()
{
    if (posIndex >= 1000)
    {
        posIndex = 0;
    }

    for (int i = 0; i < 1000; i++) // Loop through all the 1000 past positions of the player
    {
        // pastPlayerPos is an array of SDL_Rects that stores the players last 1000 positions
        // This line calculates teh location to draw the trail texture
        SDL_Rect trailRect = {pastPlayerPos[i].x, pastPlayerPos[i].y, 32, 8};
        // This draws the trail texture
        SDL_RenderCopy(Renderer, Images[IMAGE_TRAIL], NULL, &trailRect);
    }

    // This draws the player
    SDL_Rect drawRect = {(int)x, (int)y, 32, 32};
    SDL_RenderCopy(Renderer, Images[0], NULL, &drawRect);

    // This is storing the past position
    SDL_Rect tempRect = {x, y, 0, 0};
    pastPlayerPos[posIndex] = tempRect;

    posIndex++; // This is to cycle through the array to store the new position
void播放器::draw()
{
如果(posIndex>=1000)
{
posIndex=0;
}
for(int i=0;i<1000;i++)//遍历玩家过去的所有1000个位置
{
//pastPlayerPos是一个SDL矩形数组,存储玩家最后1000个位置
//这条线计算绘制轨迹纹理的位置
SDL_Rect trailRect={pastPlayerPos[i].x,pastPlayerPos[i].y,32,8};
//这将绘制轨迹纹理
SDL_RenderCopy(渲染器、图像[IMAGE_TRAIL]、NULL和trailRect);
}
//这吸引了玩家
SDL_Rect drawRect={(int)x,(int)y,32,32};
SDL_RenderCopy(渲染器、图像[0]、NULL和drawRect);
//这是存储过去的位置
SDL_Rect tempRect={x,y,0,0};
pastPlayerPos[posIndex]=tempRect;
posIndex++;//这是在数组中循环以存储新位置


这就是结果,这正是我想要实现的,但我只是在寻找一种更有效的方法。如果没有,我会坚持下去。

有多种解决方案。我给你两种

一,

创建屏幕大小的表面。用alpha填充。在每个玩家移动时,将其当前位置绘制到该表面-因此每次移动都会将额外数据添加到该面具。然后在屏幕上闪烁该表面(注意闪烁顺序)。在您的情况下,可以通过禁用alpha并首先用白色填充表面,然后在其他任何操作之前先对其进行闪烁来改进。顺便说一句,通过这种方法,您可以跳过翻转后的屏幕清理

我建议从这个开始

二,


不容易,但可能更有效(视情况而定)。将数组点保存在玩家实际更改移动方向的位置。之后,您需要在这些点之间绘制链线。但是SDL中没有用于绘制线的内置函数;可能在SDL_gfx中有,我从未尝试过。如果您以后使用OpenGL后端;使用SDL,这种方法可能会更好(或任何其他普通的2D绘图库),它不太有用。

第一个选项听起来可能对我有用。但我有点迷路了。什么是“将它的当前位置绘制到该曲面中”?您还说我可以通过“禁用alpha,并首先用白色填充曲面,然后闪烁它”跳过屏幕清除。这是怎么工作的?你是说我把它的当前位置画到表面上,然后再画到这个表面上?我想完成这个,但我有点困惑。你能详细说明一下吗?呃,刚刚意识到你在使用SDL2。如果你需要的话,它实际上有线条。但是回到第一个:如果是SDL2,你需要将纹理设置为渲染目标(使用
SDL\u SetRenderTarget
),因此,您的绘图功能将实际绘制到此纹理中。由于背景为白色,因此请使用白色填充。在每个帧上绘制具有当前播放器位置的矩形,就像您现在所做的那样。然后将渲染目标重置回屏幕,在屏幕上复制生成的纹理,并绘制树和其他所需内容。无需清除屏幕nymore,因为它已经是白色的了。如果它仍然不能给你一个想法,你可以上传你的源代码/图片到某个地方,这样我可以在有时间的时候看一下并修改它。如果它不是太凌乱或者是特定于windows的。啊,好吧,那就更有意义了!我想我应该可以用这种方式完成它。我明天会试试(我现在要学习一门化学考试:/)然后让你知道它是如何进行的!啊哈,我有一段艰难的时间…所以我创建了一个新的纹理,将其设置为渲染目标,将轨迹渲染到屏幕上,效果非常好,但背景是漆黑的。我尝试使用fillRect,但无论我是在轨迹之前还是之后绘制,它都会覆盖它们!有什么交易吗?