BEFORE YOU ANSWER, LOOK AT MY EDITS ^^
I don't exactly get you. I was already planning to use .push_front() and pop() to place in new snakeblocks in std::vector<snakeblock> snake, but I don't know how I could draw these on the screen, dir only serves me to know in which direction to move, not to know where I draw my snakeblocks (the exact coordinates x and y) on the screen. :/ aka "Calculate where the new snake's head will now be (using the 'dir' variable)".
I was planning to store the last coordinates of each snakeblock before those move, and draw each snakeblock at the position of those coordinates (by draw I mean set position by the way !). So in each if key pressed, make a :
for(int i = 1; i < snake.size(); i++)
{
snake
.snakeblock.setPosition(snake[i+1].snakeblock.getPosition())
}
Or something like that. Only thing I need is how could I get the coordinates for one sprite. I need to use globalbounds :/ If you know how I could easily get the coordinates of one sprite...
BTW, the Direction:: didn't work, because Direction is not a class/namespace but an enumeration.
EDIT1: just figured I could use vector 2f.x/y
EDIT2: Here is the code of my implementation, WHAT CAN I USE TO push_front() elements? vectors do not have this function. I let it in this code but I know I will have to change my vector to another list system.
Here is the code of how I would do it, if somebody can tell me if there is one error or if I should not do it like that..
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/Audio.hpp>
#include <deque>
void selfIncrement();
sf::Event event;
sf::Clock clockSnake;
sf::Time elapse;
enum Direction { Up, Down, Left, Right};
int dir = Up;
int n = 1;
class SnakeBlock
{
public:
SnakeBlock * next;
sf::Texture texture;
sf::Sprite snakeblock;
int lastX, lastY;
};
std::deque<SnakeBlock> Snake;
int main()
{
elapse = clockSnake.getElapsedTime();
sf::Music epicMusic;
epicMusic.openFromFile("epicmusic.wav");
epicMusic.play();
SnakeBlock snakeHead;
snakeHead.texture.loadFromFile("spritesheetsnake.png", sf::IntRect(0,0,25,22));
snakeHead.snakeblock.setTexture(snakeHead.texture);
SnakeBlock snakeBody1;
snakeBody1.snakeblock.setTexture(*(snakeHead.snakeblock.getTexture()));
SnakeBlock snakeBody2;
snakeBody2.snakeblock.setTexture(*(snakeHead.snakeblock.getTexture()));
Snake.push_front(snakeHead);
Snake.push_front(snakeBody1);
Snake.push_front(snakeBody2);
Snake[2].snakeblock.setPosition(500,350);
Snake[1].snakeblock.setPosition(475, 338);
Snake[0].snakeblock.setPosition(450, 316);
sf::RenderWindow window(sf::VideoMode(1028,768), "SFML Snake");
window.setFramerateLimit(30);
while(window.isOpen())
{
while(window.pollEvent(event))
{
switch(event.type)
{
case sf::Event::Closed:
epicMusic.stop();
window.close();
break;
default:
break;
}
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
dir = Left;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
dir = Right;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{
dir = Down;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
dir = Up;
}
if(dir == Up)
{
Snake[0].snakeblock.move(0,-5);
Snake[n].snakeblock.setPosition(Snake[n-1].snakeblock.getPosition().x, Snake[n-1].snakeblock.getPosition().y-22);
}
if(dir == Down)
{
Snake[0].snakeblock.move(0,5);
Snake[n].snakeblock.setPosition(Snake[n-1].snakeblock.getPosition().x, Snake[n-1].snakeblock.getPosition().y+22);
}
if(dir == Left)
{
Snake[0].snakeblock.move(-5,0);
Snake[n].snakeblock.setPosition(Snake[n-1].snakeblock.getPosition().x+25, Snake[n-1].snakeblock.getPosition().y);
}
if(dir == Right)
{
Snake[0].snakeblock.move(5,0);
Snake[n].snakeblock.setPosition(Snake[n-1].snakeblock.getPosition().x-25, Snake[n-1].snakeblock.getPosition().y);
}
window.clear(sf::Color::Green);
selfIncrement();
for(unsigned int m = 0; m < Snake.size(); m++)
{
window.draw(Snake[m].snakeblock);
}
window.display();
}
return 0;
}
void selfIncrement()
{
if(elapse.asSeconds() > 3)
{
n++;
clockSnake.restart();
}
if(n > Snake.size())
{
n = 1;
}
}
EDIT3: Figured that would not do the behaviour I wanted, aka have a snake that could eat himself. I guess to do what I want I would need to make a variable that would maybe increment itself after a tiny period of time... Don't really know how I could do it. Please help me
EDIT4: Just figured out what you said about deque. Here it is.
So I don't know how to do what I said, aka "make the snake movement to make it possible to bite himself". What I got now : each snakeblock will take the last snakeblock position, resulting in a perfectly straight snake. :/
Maybe I need to use one variable that auto increments over time, resulting to update the position of each snakeblock one by one, or maybe I need to use the enumeration Direction, or maybe I need to do both of that, but I don't really know how to practically do so.
Some ideas would greatly help me ! Thanks.
EDIT: new code, figured I would need to use direction to pop and then push back one new element with new position here is the new code but the sprite don't even move
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/Audio.hpp>
#include <deque>
void advanceStep();
sf::Event event;
sf::Clock clockSnake;
sf::Time elapse;
sf::Vector2f headpos;
enum Direction { Up, Down, Left, Right};
sf::Vector2i direction(0, 0);
int dir = Up;
int n = 1;
class SnakeBlock
{
public:
sf::Texture texture;
sf::Sprite snakeblock;
int dir;
int lastX, lastY;
};
std::deque<SnakeBlock> Snake;
int main()
{
elapse = clockSnake.getElapsedTime();
sf::Music epicMusic;
epicMusic.openFromFile("epicmusic.wav");
epicMusic.play();
SnakeBlock snakeHead;
snakeHead.texture.loadFromFile("spritesheetsnake.png", sf::IntRect(0,0,20,22));
snakeHead.snakeblock.setTexture(snakeHead.texture);
/*SnakeBlock snakeBody1;
snakeBody1.snakeblock.setTexture(*(snakeHead.snakeblock.getTexture()));
SnakeBlock snakeBody2;
snakeBody2.snakeblock.setTexture(*(snakeHead.snakeblock.getTexture()));*/
Snake.push_front(snakeHead);
// Snake.push_front(snakeBody1);
// Snake.push_front(snakeBody2);
/*Snake[2].snakeblock.setPosition(500,350);
Snake[1].snakeblock.setPosition(475, 338);*/
Snake[0].snakeblock.setPosition(450, 316);
sf::RenderWindow window(sf::VideoMode(1028,768), "SFML Snake");
window.setFramerateLimit(30);
while(window.isOpen())
{
while(window.pollEvent(event))
{
switch(event.type)
{
case sf::Event::Closed:
epicMusic.stop();
window.close();
break;
default:
break;
}
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
dir = Left;
direction.x = -1;
direction.y = 0;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
dir = Right;
direction.x = 1;
direction.y = 0;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{
dir = Down;
direction.x = 0;
direction.y = -1;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
dir = Up;
direction.x = 0;
direction.y = 1;
}
if(dir == Up)
{
Snake[0].snakeblock.move(0,-2);
}
if(dir == Down)
{
Snake[0].snakeblock.move(0,2);
}
if(dir == Left)
{
Snake[0].snakeblock.move(-2,0);
}
if(dir == Right)
{
Snake[0].snakeblock.move(2,0);
}
window.clear(sf::Color::Red);
advanceStep();
for(unsigned int m = 0; m < Snake.size(); m++)
{
window.draw(Snake[m].snakeblock);
}
window.display();
}
return 0;
}
void advanceStep()
{
headpos.x = Snake[0].snakeblock.getPosition().x;
headpos.y = Snake[0].snakeblock.getPosition().y;
headpos.x += 22 * direction.x;
headpos.y += 22 * direction.y;
SnakeBlock element;
element.snakeblock.setPosition(headpos);
//Snake.pop_back();
Snake.push_front(element);
}