The problem I'm having is with my render loop. My application is a series of 'Tile' objects each with an x and y coordinate and image. When the program starts it creates a 10x10 grid of these tiles on screen. However, not all the squares can be seen at the same time, so you can use the arrow keys to pan around them. When the key is pressed it uses a for loop to cycle through all the currently rendered tile (stored in an ArrayList) and shifts them all 16 in the appropriate direction. The problem is some of the tiles flicker. I can see when scrolling that one half of the screen doesn't move in time to be rendered in the right spot, making a black gap between that and the other half of the tiles. how do I ensure that all tiles are moved before rendering?
render function from my Core class
public static void render()
{
while(true)
{
Graphics g = buffer.getDrawGraphics();
try
{
g.setColor(Color.black);
g.fillRect(0, 0, 1280, 720);
if(renderQueue != null)
{
for(int i = 0; i<renderQueue.size(); i++)
{
Tile t = renderQueue.get(i);
g.drawImage(t.getImage(), t.getX(), t.getY(), null);
}
}
if(!buffer.contentsLost())
{
buffer.show();
}
}
finally
{
if(g != null)
{
g.dispose();
}
}
}
}
And here's the movement update function from the Input class
public void keyPressed(KeyEvent ke)
{
int e = ke.getKeyCode();
switch(e)
{
case 38://up
if(scrollY > 0)
{
scrollY -= 16;
for(int i = 0; i<Core.renderQueue.size(); i++)
{
Core.renderQueue.get(i).incrementY(16);
}
}
break;
case 40://down
if(scrollY < 560)
{
scrollY += 16;
for(int i = 0; i<Core.renderQueue.size(); i++)
{
Core.renderQueue.get(i).incrementY(-16);
}
}
break;
case 37://right
if(scrollX < 0)
{
scrollX += 16;
for(int i = 0; i<Core.renderQueue.size(); i++)
{
Core.renderQueue.get(i).incrementX(16);
}
}
break;
case 39://left
if(scrollX > 0)
{
scrollX -= 16;
for(int i = 0; i<Core.renderQueue.size(); i++)
{
Core.renderQueue.get(i).incrementX(-16);
}
}
break;
}
Thanks in advance!
It sounds like the tiles are being rendered while the coordinates for some of the tiles still have to be changed by Input.keyPressed
. You could fix that by directly using scrollX
and scrollY
to draw the tile images in Core.render
, instead of changing the coordinates for each of the tiles. If you copy the scroll values to two local variables at the begin of the while loop in render
, the same values will be used for each tile.
Another option is to create a new list with tiles that have the modified coordinates (you could use the images from the current list). When the new list is complete, you could set a flag like newRenderQueue
which will be picked up in render
. When a new iteration of the while loop in render
starts, you can replace the render queue with the new list and reset the flag.
P.S. Welcome to Stack Overflow! As Andrew Thompson already mentioned, it's very helpful to provide a complete example of your problem. This way people can quickly investigate the issue and provide (hopefully useful) advice... ;-)