0
\$\begingroup\$

I"ve been making a snake game in C++ using SDL (first game and first time using SDL), and I've run into a bug. As the tail of the snake gets longer, the game slows down (snake gets slower), and eventually the game crashes (once the length of the tail reaches 29 pieces/parts). I went and deleted little bits of code until I found what was causing the problem, and I found that the problem is the snake's draw() method. It is responsible for drawing the head, and also for looping through each part of the tail and drawing it. Since the tail keeps getting longer, so does the loop, as it has more to draw. When I take out the loop that draws the tail, the game works fine. Is there anything I can do that is more efficient and that will stop the game from slowing down and crashing? Maybe the structure of the program is just bad. Here is some code with all the unnecessary stuff cut out:

snake.h

#pragma once

...

class Snake
{
...

private:
    void drawPart(SDL_Renderer *renderer); // snake is made up of individual parts
    ...

public:
    void draw(SDL_Renderer *renderer); // draws whole snake
    ...

private:
    SDL_Texture *texture = nullptr;
    int x = 0, y = 0; // initialized to something else later, irreverent
    std::vector<Snake> tail; // tail is made up of objects of this class
};

snake.cpp

...
void Snake::drawPart(SDL_Renderer *renderer) {
    auto surface = IMG_Load("part.png");
    texture = SDL_CreateTextureFromSurface(renderer, surface);
    SDL_FreeSurface(surface);
    SDL_Rect rect = { x, y, WIDTH, HEIGHT };
    SDL_RenderCopy(renderer, texture, nullptr, &rect);
}

void Snake::draw(SDL_Renderer *renderer) {
    drawPart(renderer);
    // the code below is what slows down the game until it crashes
    for (auto i = 0; i < tail.size(); ++i) {
        tail[i].drawPart(renderer);
    }
}
...

If any more code is necessary, please let me know. Thanks!

\$\endgroup\$
  • \$\begingroup\$ in addition to what @SurvivalMachine said, the crashing part might well be you creating new textures each time and never deleting them. \$\endgroup\$ – PeterT Jul 3 '16 at 15:31
  • \$\begingroup\$ Thanks, I totally forgot to call SDL_DestroyTexture. \$\endgroup\$ – Archie Gertsman Jul 3 '16 at 16:47
2
\$\begingroup\$

You are loading part.png and creating the surface for each tail part in a loop. That's incredibly slow. Instead you should load it once, at the program initialization and just use it in drawing. You should get rid of these in drawPart():

auto surface = IMG_Load("part.png");
texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.