Example #1
0
void sfml_loop(Snake &snake) {
  sf::Texture texture;
  texture.loadFromMemory(snake.get_raw_img(), snake.get_raw_img_size());
  sf::RenderWindow window({ texture.getSize().x, texture.getSize().y },
                          "Snakes & Flies",
                          sf::Style::Titlebar | sf::Style::Close);
  window.setVerticalSyncEnabled(true);

  sf::Sprite sprite;
  sprite.setTexture(texture);

  unsigned long snake_size = 0;
  std::vector<double> xs(snake_size), ys(snake_size);

  bool inited = false, play = false;
  std::vector<sf::Vertex> snake_scheme;
  snake_scheme.push_back(sf::Vertex({ 0, 0 }, sf::Color::Red));

  while (window.isOpen()) {
    // check all the window's events that were triggered since the last
    // iteration of the loop
    sf::Event event;
    while (window.pollEvent(event)) {
      if (event.type == sf::Event::Closed) {
        window.close();
      }

      if (event.type == sf::Event::MouseMoved) {
        if (!inited) {
          snake_scheme.back().position =
              sf::Vector2f(sf::Mouse::getPosition(window));
        }
      }

      if (event.type == sf::Event::MouseButtonPressed) {
        if (!inited) {
          snake_scheme.insert(
              snake_scheme.end() - 1,
              sf::Vertex(sf::Vector2f(sf::Mouse::getPosition(window)),
                         sf::Color::Red));
        }
      }

      if (event.type == sf::Event::KeyPressed) {
        if (event.key.code == sf::Keyboard::Escape) {
          window.close();
        }
        if (event.key.code == sf::Keyboard::Space) {
          play = !play;
        }
        if (event.key.code == sf::Keyboard::Left ||
            event.key.code == sf::Keyboard::Right) {
          bool direction = event.key.code == sf::Keyboard::Right;
          if (!snake.shift_frame(direction)) {
            window.close();
          }
          texture.loadFromMemory(snake.get_raw_img(), snake.get_raw_img_size());
        }
      }

      if (event.type == sf::Event::KeyPressed && snake_scheme.size() > 2) {
        if (!inited) {
          if (snake.is_closed()) {
            snake_scheme.back() = snake_scheme.front();
          } else {
            snake_scheme.pop_back();
          }

          int implicit_joints = snake.get_implicit();

          if (implicit_joints > 0) {
            snake_size = implicit_joints * (snake_scheme.size() - 1) + 1;
          } else {
            snake_size = snake_scheme.size();
          }
          xs.resize(snake_size);
          ys.resize(snake_size);

          if (implicit_joints > 0) {
            for (int k = 0; k < snake_scheme.size() - 1; ++k) {
              auto x_diff = (snake_scheme[k + 1].position.x -
                             snake_scheme[k].position.x) /
                            implicit_joints;
              auto y_diff = (snake_scheme[k + 1].position.y -
                             snake_scheme[k].position.y) /
                            implicit_joints;
              for (int j = 0; j < implicit_joints; ++j) {
                xs[k * snake.get_implicit() + j] =
                    snake_scheme[k].position.x + j * x_diff;
                ys[k * snake.get_implicit() + j] =
                    snake_scheme[k].position.y + j * y_diff;
              }
            }
          }
          xs.back() = snake_scheme[snake_scheme.size() - 1].position.x;
          ys.back() = snake_scheme[snake_scheme.size() - 1].position.y;
          snake_scheme.resize(snake_size, { { 0, 0 }, sf::Color::Red });
          snake.set_xs(xs);
          snake.set_ys(ys);
          snake.set_pentamat();
        }
        inited = true;
      }
    }

    if (inited && play) {
      bool local_minima = snake.update();
      if (local_minima) {
        window.close();
      }
      xs = snake.get_xs();
      ys = snake.get_ys();
      for (int k = 0; k < snake_size; ++k) {
        snake_scheme[k].position.x = xs[k];
        snake_scheme[k].position.y = ys[k];
      }
    }

    window.draw(sprite);
    window.draw(&snake_scheme[0], (unsigned)snake_scheme.size(),
                sf::LinesStrip);

    window.display();
  }
}