Game STOPS flickering when mouse Moves...

Hey everybody, :slight_smile:

I started making the beginning of a car game and setup the double buffer, game loop, and the code for the movement of all the sprites (based off of the spaceinvaders java tutorial) and ran it.

I looked alright (No vertical flickering) but it “stutters” or “skips” slightly unless I MOVE THE MOUSE (cursor) over the program?!

-It only runs SMOOTHLY if I move the mouse within the program (JFrame) and even if I resize it and move the mouse it will run smoothly.

Note: The cursor has to be in motion for the “skip” to stop, once I stop moving the cursor the skipping begins again.

Any Idea what this could be?

Thanks for the help!

Here’s the code without the Car Class, I can include that also if it helps…


package road;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Road extends Canvas {
    
     
        
     //Create 100 Car Spots 
        public ArrayList<Car> carlist = new ArrayList<Car>(); 
        public BufferStrategy bs;
        
    //Constructor: Initialize Everything here?
    //I think I should only initialze Road Stuff
    public Road(){
        JFrame frame = new JFrame("Road App");
        JPanel panel = (JPanel) frame.getContentPane();
        panel.setPreferredSize(new Dimension(1000,300));
        panel.setLayout(null);
		
        // setup our canvas size and put it into the content of the frame
        setBounds(0,0,1000,300);
        panel.add(this);
        
        
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       
       
       
       //Set the size of the canvas and add it to the frame via content pane
       //this.setPreferredSize(new Dimension(1000,300));
       //frame.getContentPane().add(this);
       
       frame.pack();
       frame.setResizable(false);
       frame.setVisible(true);
       setIgnoreRepaint(true);
       panel.setIgnoreRepaint(true);
       
       
       //Create Buffer Strategy for painting actively
       createBufferStrategy(2);
       bs = getBufferStrategy();
       
       
    }
    
    
    
    //Entry into Program
    public static void main(String[] args) {
        // TODO code application logic here
        Road road = new Road();
        
        road.init();
        road.programLoop(); // get out of main...
        
        
    }
    
    
    //
    //THIS IS THE MAIN LOOP
    //
    public void programLoop(){
        
       boolean isRunning = true; 
       long lastIterationTime = System.currentTimeMillis();// Initialize it
       long lastTimedIteration = System.currentTimeMillis();
       long startTime = System.currentTimeMillis();
       
        
         //
         while(isRunning){
             
            long change = System.currentTimeMillis() -lastTimedIteration;
            long delta = System.currentTimeMillis() -lastIterationTime;
            long runTime = System.currentTimeMillis() - startTime;
            System.out.println("delta is " + delta);
            
             lastIterationTime = System.currentTimeMillis();
             
             if (change>30){
                 //Update the last time we went through this loop
                 lastTimedIteration = System.currentTimeMillis();                 
                 //Print out delta value and current time
                 System.out.println(change + " " + lastTimedIteration);
                 
                 System.out.println("\n::Class Car Stats::" + Car.idcount + " " + Car.totalcars);
                 
                 //////////////////////////////////////////
                 //CarPlacer: Places New Cars on map at specified times
                 //////////////////////////////////////////
                 
                 for (int i = 0; i < carlist.size(); i++){
                     
                     //Is the current car active, do logic if so...
                    if (carlist.get(i).getActive() == false){
                         if (carlist.get(i).getStartTime() < runTime){
                             carlist.get(i).setActive(true);
                         }
                    }
                   
                    
                 }
                 
                 
                 
                 
                 ///////////////////////////////////////////
                 //DO LOGIC FOR ALL ACTIVE CARS
                 ///////////////////////////////////////////
                 
                 //Go through all cars in the list
                 for (int i = 0; i < carlist.size(); i++){
                 
                 //Is the current car active, do logic if so...
                 if (carlist.get(i).getActive()){
                 carlist.get(i).doLogic();
                 }
                 
                 
                 }
                 
                
                
                 
                
             }//End of timed Section
             //Beginning of code executed Every loop.
             for (int i = 0; i < carlist.size(); i++){
                     
                     //Is the current car active, do logic if so...
                    if (carlist.get(i).getActive()){
                         carlist.get(i).moveCar(delta);
                    }
                   
                    
                 }
             
                 ////////////////////////////////////
                 //Do all Drawing
                 /////////////////////////////////////
                 doDrawing();
            
           try {
                Thread.sleep(10);
            } catch (InterruptedException ex) {
                Logger.getLogger(Road.class.getName()).log(Level.SEVERE, null, ex);
            }
         }
        
       
        
    }
    
    
    public void init(){
       
        
        //Create a list of Cars to put into program
        Car c1 = new Car(75,0,0,150,0);
        Car c2 = new Car(75,0,1,75,500);
        Car c3 = new Car(75,0,0,100,100);
        
        
        //Create another car for kicks
        carlist.add(c1);
        carlist.add(c2);
        carlist.add(c3);
        
        
        
    }
    public void doDrawing(){
        Graphics2D g = (Graphics2D) bs.getDrawGraphics();
        //Draw Background
        g.setColor(Color.BLACK);
        g.fillRect(0,0,this.getWidth(),this.getHeight());
        
        
        //Draw the Road
        g.setColor(Color.GRAY);
        g.drawLine(0, 160, 1000, 160);
        g.setColor(Color.WHITE);
        g.drawLine(0, 135, 1000, 135);
        g.drawLine(0, 185, 1000, 185);
        
        //Draw all the cars that are ACTIVE
            for (int i = 0; i < carlist.size(); i++){
                     
                //Is the current car active, Draw it on Screen then.
                if (carlist.get(i).getActive()){
                    carlist.get(i).draw(g);
                }
                   
                    
            }
        
        //Throw away our container and flip buffer.
        g.dispose();
        bs.show();
        
        
    }
        
}

Use Toolkit.getDefaultToolkit().sync(); after you do bs.show();

Thanks!

What exactly was causing the stuttering?

Now I read up on Sync() to try and figure out when I should/should not use it and I got this:

[quote] Synchronizes this toolkit’s graphics state. Some window systems may do buffering of graphics events.

This method ensures that the display is up-to-date. It is useful for animation.
[/quote]
The way I see it (correct me) is that Toolkit interacts directly with the specific OS or windowing system and the subclasses of Toolkit are used to write higher level code (Where I wouldn’t have to worry about specific OSs). So, if I had run this program on another computer the stuttering might not have happened because they could have possible had a different windowing system that didn’t buffer graphics events? I’m running Mandriva Linux, but a different OS might not have had this problem?

So the reason it ran without stuttering when I moved the mouse was because the windowing system updated on a mouse move?

  • In the space invader game tutorial for java sync wasn’t used and it runs without stuttering on my machine, why is this?
  • If I had incorporated a mousemove listener or something that had to do with the mouse would it still stutter?
  • Is there another way to solve this problem without sync() or is sync the best way?

Sorry for all the questions, I’m just curious about how all the different components interact. I think I understand the coding process well, but when writing code for games knowledge of how different operating systems, gfx cards, etc… seems to be needed and I’ll take whatever I can get. If anyone could point me in the right direction where I could learn about theses processes I’d really appreciate it.

Thanks for the help!

I didn’t tested it but it seems it’s required at least for Linux, but probably not needed on Windows. Sometimes I see the problem on Java applets/apps, probably because author did test on only one platform. Maybe the BufferedStrategy synchronizes on other platforms but not on Linux. In this case, this could be considered as a bug in BufferedStrategy, as it’s clear what the intentions are when swapping buffers.

Probably because the events were flushed by other operations (eg. after filling up some buffer or time).

I don’t think that listeners matter to this issue.

I think it’s the correct solution. :slight_smile: It’s similiar to I/O operations, on different platforms it behaves differently, but according the specs. If you forgot to handle some case though, it will work on one system and crash/misbehave on another.

Many of these things are small nuances that can be found only at random or when you hit problem. It’s very important to test on all platforms you’re supporting. And even with that other people will still get problems in these details, like the issue with French’s AZERTY vs QWERTY keyboard layout mentioned in some other recent thread here.

Thanks for the help! That helps putting everything into perspective.