0

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?

0 Answers0