At the moment I'm trying to make a simple videogame in Java, just for fun. But there seems to be lag, and I'm not sure why it's happening. I'll give the lowdown: The way it draws is using JFrame, and the actual drawing happens in the ImagePanel class. In ImagePanel, this is how I draw. It includes some things about debugging to show FPS and a timer to show length of run, but I'm not sure if that's important. It goes through multiple ArrayLists to show all the objects on the JFrame.
//Painting
public void paintComponent(Graphics g)
{
//Paint the background with its upper left corner at the upper left corner of the panel
g.drawImage(background, 0, 0, null);
//Paint each image in the foreground where it should go
for(MovingImage img : backgrounds)
{
g.drawImage(img.getImage(), (int)(img.getX()), (int)(img.getY()), null);
}
for(MovingImage img : foreground)
{
g.drawImage(img.getImage(), (int)(img.getX()), (int)(img.getY()), null);
}
if(g instanceof Graphics2D)
{
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.scale(2, 2);
g2.setColor(Color.WHITE);
String milSpace;
if(timer%100 < 10)
milSpace = "0";
else
milSpace = "";
String secSpace;
if(timer/100 < 10)
secSpace = "0";
else
secSpace = "";
g2.drawString(secSpace + timer/100 + ":" + milSpace + timer%100, 10, 20);
//Debug
if(debug)
{
long currentTime = System.currentTimeMillis();
if (currentTime > nextSecond)
{
nextSecond += 1000;
frameInLastSecond = framesInCurrentSecond;
framesInCurrentSecond = 0;
}
framesInCurrentSecond++;
//g2.drawString("LagMS:" + (-frameRate - 10) + " FPS:" + frameInLastSecond, 20, 40); <-includes "lag"
g2.drawString("FPS:" + frameInLastSecond, 20, 40);
}
}
}
//Replaces the list of foreground images with the one given, and repaints the panel
public void updateImages(ArrayList<MovingImage> newForeground, ArrayList<MovingImage> newBackgrounds)
{
foreground = newForeground;
backgrounds = newBackgrounds;
//time checking
long time = System.currentTimeMillis();
lastTime = time;
repaint(); //This repaints stuff... you don't need to know how it works
}
Inside the primary class I made that includes a tick system, which causes it to be painted in the first place.
public void tick()
{
long lastTime = System.currentTimeMillis();
int place = 0;
boolean go = true;
while(go)
{
long time = System.currentTimeMillis(); //The current time
if(time - 10 > lastTime) //Update every .01 seconds, or 1 TICK (if time - 10 > lastTime)
{
lastTime = time;
//Reset the last time
place++;
imagePanel.incTime();
for(MovingImage object : movingObjects)
{
if(object instanceof Building)
{
object.incrementPosition(); //Augment position by velocity
if(place%500 == 0)//If 5 seconds have passed...
{
((Building) object).speedUp();//make it go a little faster!
}
}
if(object instanceof Player)
{
if(jumpKeyOn)
((Player) object).jump();//Initiate jump class assuming key is pressed
object.incrementPosition();
((Player) object).constrainPlayerToObjects(movingObjects, yMax);
if(object.getY()>yMax + 1000)
{
go = false;
}
}
}
//Repaint all the things in their new positions, possibly faster
for(MovingImage bg : backgrounds)
{
bg.incrementPosition();
if(place%500 == 0)
bg.setVelocity(bg.getXvel() - 0.1, 0);
}
/*
* Acceleration
*/
//Removes buildings once left screen
int i = 0;
while(i < movingObjects.size())
{
if(movingObjects.get(i) instanceof Building)
{
if(movingObjects.get(i).getX() + movingObjects.get(i).getImage().getWidth(null) < 0)
movingObjects.remove(i);
else
i++;
}
else
i++;
}
imagePanel.updateImages(movingObjects, backgrounds);
}
}
gameOver();
}
It's an endless loop that essentially runs the program. I used multiple ArrayLists in order to put different layers down. What am I doing that's causing it to lag? I'm still fairly new, but I'll answer any questions about the code or provide more details. I couldn't find any other questions that helped.
EDIT: There are some odd things I should mention. Occasionally it runs at nearly the full FPS, but most of the time not. I also noticed that when I ran another java program at the same time, it ran at nearly full speed.
EDIT 2: Should I include the entire primary class code and ImagePanel?