So I'm trying to make a 2d shooting scroller.
I set up a scrolling background that has different levels for a parallax effect. I have it all set up and working. But as soon as I try to set a viewport to follow the player. It messes up the positions of the backgrounds and they no longer stay seamless and continue on as they should. Why is it when I try to use the viewport and scroll it along, it also changes the positions of the background images?
The way I'm doing this is by having two sprites and assigning the same texture to them both. Having the first sprite the size of the screen. And the second sprite the same size but to the right of the first one. Then as the player presses right or left, I scroll the sprite either left or right. And as one sprite goes off screen, I am redrawing it on the other side of the other sprite to make it seem like its continuous. I repeated this step with different speeds for each layer. And it works (if you don't move the viewport). But as soon as I use the viewport everything goes strange and the backgrounds dont join up anymore.
I am a bit of a beginner and don't really understand why this happens. Can anyone help by explaining why this is happening or how I can stop it from happening? it's as if the viewport changes the global positioning of everything?
const int screenWidth = 1920;
const int screenHeight = 1080;
static shared_ptr<Entity> player;
Texture mage;
Texture skele;
Texture skeletArcher;
Texture skeletChief;
Sprite skeleton;
Sprite bckSprites[12];
Texture bckTextures[6];
View view;
void Level2Scene::Load() {
cout << "Scene 2 Load" << endl;
ls::loadLevelFile("res/level_2.txt", 40.0f);
//Set Viewport for scrolling screen
view.reset(sf::FloatRect(0, 0, screenWidth, screenHeight));
view.setViewport(sf::FloatRect(0, 0, 1.0f, 1.0f));
//Background
// *********************************
if (!bckTextures[0].loadFromFile("res/layer1.png"))
{
cout << "Couldn't load Background1!" << endl;
}
if (!bckTextures[1].loadFromFile("res/layer2.png"))
{
cout << "Couldn't load Background2!" << endl;
}
if (!bckTextures[2].loadFromFile("res/layer3.png"))
{
cout << "Couldn't load Background3!" << endl;
}
if (!bckTextures[3].loadFromFile("res/layer4.png"))
{
cout << "Couldn't load Background4!" << endl;
}
if (!bckTextures[4].loadFromFile("res/layer5.png"))
{
cout << "Couldn't load Background5!" << endl;
}
if (!bckTextures[5].loadFromFile("res/layer6.png"))
{
cout << "Couldn't load Background6!" << endl;
}
bool t = true;
int j = 0;
for (int i = 0; i < 12; i++)
{
if (t == true)
{
bckSprites[i].setTexture(bckTextures[j]);
bckSprites[i].setPosition(0, 0);
t = !t;
}
else if (t == false)
{
bckSprites[i].setTexture(bckTextures[j]);
bckSprites[i].setPosition(screenWidth, 0);
t = !t;
j++;
}
}
// *********************************
// Create player
{
// *********************************
player = makeEntity();
player->setPosition(ls::getTilePosition(ls::findTiles(ls::START)[0]));
auto s = player->addComponent<ShapeComponent>();
s->setShape<sf::RectangleShape>(Vector2f(20.f, 30.f));
mage.loadFromFile("res/mage.png");
s->getShape().setTexture(&mage);
s->getShape().setOrigin(10.f, 15.f);
player->addTag("player");
player->addComponent<PlayerMovementComponent>();
player->setHealth(100);
}
// *********************************
// Add physics colliders to level tiles.
{
// *********************************
auto walls = ls::findTiles(ls::WALL);
for (auto w : walls) {
auto pos = ls::getTilePosition(w);
pos += Vector2f(20.0f, 20.0f); // offset to centre
auto e = makeEntity();
e->setPosition(pos);
e->addComponent<PhysicsComponent>(false, Vector2f(40.0f, 40.0f));
}
// *********************************
}
cout << " Scene 2 Load Done" << endl;
setLoaded(true);
}
void Level2Scene::UnLoad() {
cout << "Scene 2 UnLoad" << endl;
player.reset();
ls::unload();
Scene::UnLoad();
}
void Level2Scene::Update(const double& dt) {
//scroll screen as player reaches middle
//*****************************************************
Vector2f position(0, 0);
position.x = player->getPosition().x + 10 - (screenWidth / 2);
position.y = player->getPosition().y + 10 - (screenHeight / 2);
if (position.x < 0)
{
position.x = 0;
}
if (position.y < 0)
{
position.y = 0;
}
view.reset(FloatRect(position.x, position.y, screenWidth, screenHeight));
//*****************************************************
#pragma region Background Speeds
if(Keyboard::isKeyPressed(Keyboard::Right))
{
bckSprites[0].move(Vector2f(-600 * dt,0));
bckSprites[1].move(Vector2f(-600 * dt, 0));
}
if (Keyboard::isKeyPressed(Keyboard::Left))
{
bckSprites[0].move(Vector2f(600 * dt, 0));
bckSprites[1].move(Vector2f(600 * dt, 0));
}
if (Keyboard::isKeyPressed(Keyboard::Right))
{
bckSprites[2].move(Vector2f(-500 * dt, 0));
bckSprites[3].move(Vector2f(-500 * dt, 0));
}
if (Keyboard::isKeyPressed(Keyboard::Left))
{
bckSprites[2].move(Vector2f(500 * dt, 0));
bckSprites[3].move(Vector2f(500 * dt, 0));
}
if (Keyboard::isKeyPressed(Keyboard::Right))
{
bckSprites[4].move(Vector2f(-400 * dt, 0));
bckSprites[5].move(Vector2f(-400 * dt, 0));
}
if (Keyboard::isKeyPressed(Keyboard::Left))
{
bckSprites[4].move(Vector2f(400 * dt, 0));
bckSprites[5].move(Vector2f(400 * dt, 0));
}
if (Keyboard::isKeyPressed(Keyboard::Right))
{
bckSprites[6].move(Vector2f(-300 * dt, 0));
bckSprites[7].move(Vector2f(-300 * dt, 0));
}
if (Keyboard::isKeyPressed(Keyboard::Left))
{
bckSprites[6].move(Vector2f(300 * dt, 0));
bckSprites[7].move(Vector2f(300 * dt, 0));
}
if (Keyboard::isKeyPressed(Keyboard::Right))
{
bckSprites[8].move(Vector2f(-200 * dt, 0));
bckSprites[9].move(Vector2f(-200 * dt, 0));
}
if (Keyboard::isKeyPressed(Keyboard::Left))
{
bckSprites[8].move(Vector2f(200 * dt, 0));
bckSprites[9].move(Vector2f(200 * dt, 0));
}
if (Keyboard::isKeyPressed(Keyboard::Right))
{
bckSprites[10].move(Vector2f(-100 * dt, 0));
bckSprites[11].move(Vector2f(-100 * dt, 0));
}
if (Keyboard::isKeyPressed(Keyboard::Left))
{
bckSprites[10].move(Vector2f(100 * dt, 0));
bckSprites[11].move(Vector2f(100 * dt, 0));
}
#pragma endregion
#pragma region Move Backgrounds
if (bckSprites[0].getPosition().x < -1920)
{
bckSprites[0].setPosition(bckSprites[1].getPosition().x + 1920, 0);
}
if (bckSprites[0].getPosition().x > 1920)
{
bckSprites[0].setPosition(bckSprites[1].getPosition().x - 1920, 0);
}
cout << "PlayerPos: " << position << " spritePos: " << bckSprites[0].getPosition().x << endl;
if (bckSprites[1].getPosition().x < -1920)
{
bckSprites[1].setPosition(bckSprites[0].getPosition().x + 1920, 0);
}
if (bckSprites[1].getPosition().x > 1920)
{
bckSprites[1].setPosition(bckSprites[0].getPosition().x - 1920, 0);
}
if (bckSprites[2].getPosition().x < -1920)
{
bckSprites[2].setPosition(bckSprites[3].getPosition().x + 1920, 0);
}
if (bckSprites[2].getPosition().x > 1920)
{
bckSprites[2].setPosition(bckSprites[3].getPosition().x - 1920, 0);
}
if (bckSprites[3].getPosition().x < -1920)
{
bckSprites[3].setPosition(bckSprites[2].getPosition().x + 1920, 0);
}
if (bckSprites[3].getPosition().x > 1920)
{
bckSprites[3].setPosition(bckSprites[2].getPosition().x - 1920, 0);
}
if (bckSprites[4].getPosition().x < -1920)
{
bckSprites[4].setPosition(bckSprites[5].getPosition().x + 1920, 0);
}
if (bckSprites[4].getPosition().x > 1920)
{
bckSprites[4].setPosition(bckSprites[5].getPosition().x - 1920, 0);
}
if (bckSprites[5].getPosition().x < -1920)
{
bckSprites[5].setPosition(bckSprites[4].getPosition().x + 1920, 0);
}
if (bckSprites[5].getPosition().x > 1920)
{
bckSprites[5].setPosition(bckSprites[4].getPosition().x - 1920, 0);
}
if (bckSprites[6].getPosition().x < -1920)
{
bckSprites[6].setPosition(bckSprites[7].getPosition().x + 1920, 0);
}
if (bckSprites[6].getPosition().x > 1920)
{
bckSprites[6].setPosition(bckSprites[7].getPosition().x - 1920, 0);
}
if (bckSprites[7].getPosition().x < -1920)
{
bckSprites[7].setPosition(bckSprites[6].getPosition().x + 1920, 0);
}
if (bckSprites[7].getPosition().x > 1920)
{
bckSprites[7].setPosition(bckSprites[6].getPosition().x - 1920, 0);
}
if (bckSprites[8].getPosition().x < -1920)
{
bckSprites[8].setPosition(bckSprites[9].getPosition().x + 1920, 0);
}
if (bckSprites[8].getPosition().x > 1920)
{
bckSprites[8].setPosition(bckSprites[9].getPosition().x - 1920, 0);
}
if (bckSprites[9].getPosition().x < -1920)
{
bckSprites[9].setPosition(bckSprites[8].getPosition().x + 1920, 0);
}
if (bckSprites[9].getPosition().x > 1920)
{
bckSprites[9].setPosition(bckSprites[8].getPosition().x - 1920, 0);
}
if (bckSprites[10].getPosition().x < -1920)
{
bckSprites[10].setPosition(bckSprites[11].getPosition().x + 1920, 0);
}
if (bckSprites[10].getPosition().x > 1920)
{
bckSprites[10].setPosition(bckSprites[11].getPosition().x - 1920, 0);
}
if (bckSprites[11].getPosition().x < -1920)
{
bckSprites[11].setPosition(bckSprites[10].getPosition().x + 1920, 0);
}
if (bckSprites[11].getPosition().x > 1920)
{
bckSprites[11].setPosition(bckSprites[10].getPosition().x - 1920, 0);
}
#pragma endregion
Scene::Update(dt);
const auto pp = player->getPosition();
if (ls::getTileAt(pp) == ls::END) {
Engine::ChangeScene((Scene*)&level3);
} else if (!player->isAlive()) {
Engine::ChangeScene((Scene*)&gameOver);
}
}
void Level2Scene::Render() {
for (int i = 11; i > -1; i--)
{
Engine::GetWindow().draw(bckSprites[i]);
}
ls::render(Engine::GetWindow());
Engine::GetWindow().setView(view);
Scene::Render();
}