Hello there!
I've been writing simple tile map engine for fun and learning purposes. I's been going well till I decided to walk off path pointed by
tutorial I've been using and went and made diamond shaped map instead of staggered one. Some google'ing gave me decent
code to base on. It's all working well aside from fact that during scrolling(up and right mostly) there are spaces between tiles. They however are never there when scrolling stops.
Problem persists regardless of draw() method being ran in different thread or at the end of "game loop".
Same deal with Vsynch on and off.
I feel there is no need to post whole code as it would be just too much so I'll include only drawing and event handling(game) methods.
I've tried to clean up code a bit and add comments every now and then, there is a lot of temporary code, flagged with //temp comment or just empty one //
All help and tips and constructive critique will be appreciated. If it turns out whole code is needed let me know and I will include it.
Since its missing from included code and is not obviously named, "test" is sf::RectangleShape and is used to imitate window bounds to see how many tiles are drawn out of it.
Language: c++
SFML: 2.0 RC
void Game::Draw()
{
//temp fps
int counter=0;
int fps3 = 0;
sf::Text fpsText;
sf::Clock clk;
//
window.setActive(true);
window.setVerticalSyncEnabled(false);
//first tiles to draw
int startX, startY;
//futherest tiles to draw
int maxX, maxY;
//minimum X index to draw
int minX;
//check if futherest and min tiles were drawn
bool mGotXmax;
bool nGotXmin;
//increse before reaching min/max, decrese after(bump)
int nBuff, mBuff;
//delay
int n,m;
while(window.isOpen())
{
window.clear();
//initial values for every run
if(tempDrawChange==1)
{
//Fullscreen Calc here
minX = IndxFromIso(Cam->CameraPos.x, Cam->CameraPos.y).x-1;
maxX = IndxFromIso(Cam->CameraPos.x+window.getSize().x, Cam->CameraPos.y+window.getSize().y).x + 2;
maxY = IndxFromIso(Cam->CameraPos.x, Cam->CameraPos.y+window.getSize().y).y + 2;
startX = IndxFromIso(Cam->CameraPos.x+window.getSize().x, Cam->CameraPos.y).x+1;
startY = IndxFromIso(Cam->CameraPos.x+window.getSize().x, Cam->CameraPos.y).y;
}
else
{
//rect calc here
minX = IndxFromIso(Cam->CameraPos.x+test.getPosition().x, Cam->CameraPos.y+test.getPosition().y).x-1;
maxX = IndxFromIso(Cam->CameraPos.x+test.getPosition().x+test.getSize().x, Cam->CameraPos.y+test.getPosition().y+test.getSize().y).x+2;
maxY = IndxFromIso(Cam->CameraPos.x+test.getPosition().x, Cam->CameraPos.y+test.getPosition().y+test.getSize().y).y+2;
startX = IndxFromIso(Cam->CameraPos.x+test.getPosition().x+test.getSize().x, Cam->CameraPos.y+test.getPosition().y).x+1;
startY = IndxFromIso(Cam->CameraPos.x+test.getPosition().x+test.getSize().x, Cam->CameraPos.y+test.getPosition().y).y;
}
nBuff = 1;
mBuff = 1;
mGotXmax = false;
nGotXmin = false;
n=0;
m=3;
//drawing loops
for(int y=startY; y<maxY; y++)
{
for(int x=startX-nBuff; x<startX+mBuff; x++)
{
//Drawing, multiple layers
if(x>0 && x< Map->MapW-1 && y>0 && y< Map->MapH-1)
{
for(int i=0; i<Map->MapGrid[x][y].TileID.size(); i++)
{
sf::Vector2i position = IndxToIso(x, y);
TileSprite.setTextureRect(TileSet.GetSourceRectangle(Map->MapGrid[x][y].TileID[i]));
TileSprite.setPosition(position.x-Cam->CameraPos.x, position.y-Cam->CameraPos.y);
}
}
window.draw(TileSprite);
}
//bump mechanics
if(startX+mBuff==maxX)
mGotXmax = true;
if(startX-nBuff==minX)
nGotXmin = true;
if(mGotXmax)
{
if(m>0)
m--;
else
mBuff--;
}
else
{
mBuff++;
}
if(nGotXmin)
{
if(n>0)
n--;
else
nBuff--;
}
else
{
nBuff++;
}
}
//fps temp
counter++;
if(clk.getElapsedTime().asSeconds()>=1)
{
fps3 = counter/clk.getElapsedTime().asSeconds();
counter=0;
clk.restart();
std::string sss;
char tempB[20];
sprintf(tempB, "%d", fps3);
sss = tempB;
fpsText.setString(sss);
}
//
window.draw(fpsText);
window.draw(test);
window.display();
}
};
void Game::Run()
{
//temp pressed time
bool a = true;
sf::Clock clk;
//
window.setActive(false);
//new thread for draw function
sf::Thread RenderThread(&Game::Draw, this);
RenderThread.launch();
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
if(event.type == sf::Event::KeyPressed)
{
controls.KeyPressed[event.key.code] = true;
//temp pressed time
if(a)
{
a = false;
clk.restart();
}
}
if(event.type == sf::Event::KeyReleased)
{
controls.KeyPressed[event.key.code] = false;
//temp pressed time
std::cout<<"Pressed for "<<clk.getElapsedTime().asSeconds()<<std::endl;
a = true;
//temp draw mode
if(event.key.code == sf::Keyboard::F1)
tempDrawChange*=-1;
}
if(event.type == sf::Event::MouseButtonPressed)
{
//temp for debug
sf::Vector2i index = IndxFromIso(event.mouseButton.x+Cam->CameraPos.x, event.mouseButton.y+Cam->CameraPos.y);
std::cout<<"Index: "<<index.x<<" "<<index.y<<std::endl;
std::cout<<"Mouse: "<<event.mouseButton.x<<" | "<<event.mouseButton.y<<std::endl;
std::cout<<"Camera: "<<Cam->CameraPos.x<<" "<<Cam->CameraPos.y<<std::endl;
std::cout<<"M-C: "<<event.mouseButton.x+Cam->CameraPos.x<<" "<<event.mouseButton.y+Cam->CameraPos.y<<std::endl<<std::endl;
}
}
if(controls.isPressed(sf::Keyboard::Escape))
window.close();
if(controls.isPressed(sf::Keyboard::Right))
{
Cam->CameraPos.x++;
}
if(controls.isPressed(sf::Keyboard::Left))
{
Cam->CameraPos.x--;
}
if(controls.isPressed(sf::Keyboard::Down))
{
Cam->CameraPos.y++;
}
if(controls.isPressed(sf::Keyboard::Up))
{
Cam->CameraPos.y--;
}
}
};