Display sliding white bars on a black background

Hi All,



This is my first post to the forum,



I had written the attached java application to display sliding white bars on a black background,

the height of each bar is the monitor height, the width varies , and the sliding speed of each bar increases/decreases by pressing Z/X.





The problem now is the tearing and flickering that my bars show specially  at high speed, I was wondering how to solve this problem, is it possible by using double buffering or page flipping, i read something that says it works, and some others saying swings already implement double buffering, thanks for your hints and code suggestions in advance.



is it possible with JME to develop such application and avoid flickering and tearing  effects  ? , based on the fact that JME uses openGL technologies



import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
 
class drawBar extends JFrame implements MouseMotionListener {
  int X, Y, timerUpdate;
  int width_In_Pixel;
  Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
  Color background, bar;
 
  public drawBar() {
    super();
    width_In_Pixel = 50;
    setSize(dim.width, dim.height);
    background = Color.BLACK;
    bar = Color.white;
    timerUpdate = 50;
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    addMouseMotionListener(this);
    setVisible(true);
  }
 
  public void paint(Graphics g) {
    Image offscreen = createImage(dim.width, dim.height);
    Graphics buff = offscreen.getGraphics();
  
    //buff.setColor(Color.black);
    //buff.fillRect(0,0,dim.width,dim.height);
    //buff.setColor(Color.white);
    //buff.fillRect(X,Y,width_In_Pixel,dim.height);
    //g.drawImage(offscreen ,0,0,this);
 
    buff.setColor(background);
    buff.fillRect(0, 0, dim.width, dim.height);
    buff.setColor(bar);
    for (int X = 0; X < dim.width + width_In_Pixel * 2;X += width_In_Pixel * 2) {
      buff.fillRect(X, 0, width_In_Pixel, dim.height);
    }
    g.drawImage(offscreen, 0, 0, this);
  }
 
  public void mouseMoved(MouseEvent eve) {
 
    /* if(background.equals(Color.BLACK)) background = Color.white;
       if(bar.equals(Color.white)) bar = Color.black;
       repaint(); */
  }
 
  public void mouseDragged(MouseEvent eve) {
  }
 
  public void delay() {
    ActionListener al = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
       if(background.equals(Color.BLACK))
         background = Color.white;
       else background = Color.black;
       if(bar.equals(Color.white))
         bar = Color.black;
       else bar = Color.white;
       repaint();
      }
    };
    new Timer(timerUpdate, al).start();
  }
 
  /*The update is always required for good double-buffering.*
   *This will cause the applet not to first wiping off      *
   *previous drawings but to immediately repaint.           *
   *the wiping off also causes flickering.                  *
   *Update is called automatically when repaint() is called.*/
 
  public void update(Graphics g) {
    paint(g);
  }
 
  public static void main(String agrs[]) {
    drawBar bar = new drawBar();
    bar.delay();
 
  }
}

setting vsync sorted out tearing when I was working with LWJGL, Havent used it in JME yet though.

DisplaySystem.getDisplaySystem().setVSyncEnabled(true);



setVSyncEnabled attempts to enable or disable monitor vertical synchronization. The method is a "best attempt" to change the monitor vertical refresh synchronization, and is not guaranteed to be successful. This is dependant on OS.


^^ from the javadoc

maybe manually displaying the backbuffer would work better

  DisplaySystem.getDisplaySystem().getRenderer().clearBuffers();
        DisplaySystem.getDisplaySystem().getRenderer().draw(scene);
        DisplaySystem.getDisplaySystem().getRenderer().displayBackBuffer();



displayBackBuffer swaps the back buffer with the currently displayed buffer. Swapping (page flipping) allows the renderer to display a prerenderer display without any flickering.


Not really sure because I haven't come accros issues with the vsync yet.

aarrgh my eyes !  :slight_smile:



Sure it is possible to create this in jme but it might be a bit of a overkill.



What do you want to do with the application, use it as a applet or desktop app?

I see you just switch colors of bars and background, why not actually move the white bars ?

Core-Dump said:

aarrgh my eyes !  :)

Sure it is possible to create this in jme but it might be a bit of a overkill.

What do you want to do with the application, use it as a applet or desktop app?



I want to create it as a desktop application , that would be used to test the vision system of babies until the age of 2 years.

Why am I not just moving the white bars ? , this is a good question, i already implemented the idea on that way but it did not work, attached is the code for that. I think the problem is the snychronizatipon with the monitir refresh rate but I do not know how to do this, in the previous version attached above , i tried to use double buffering but the result is as you see.



import java.awt.Toolkit;
import javax.swing.ScrollPaneConstants;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.Graphics;
import java.awt.Dimension;
import javax.swing.JFrame;
import java.awt.event.ActionListener;
import java.awt.Point;
import java.awt.event.ActionEvent;
import javax.swing.Timer;
import javax.swing.KeyStroke;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import java.awt.GraphicsConfiguration;
import java.awt.Frame;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.DisplayMode;
import java.awt.image.BufferStrategy;
import java.awt.Font;
import java.awt.BorderLayout;

public class DrawingBars {
    double[] width = {17.453, 13.864, 11.012, 8.747, 6.948, 5.519, 4.384, 3.482,
                     2.766, 2.197, 1.745, 1.386,

                     29.089, 23.106, 18.354, 14.579, 11.580, 9.199, 7.307,
                     5.804,4.610, 3.662, 2.909, 2.311, 1.835, 1.458, 1.158, 0.92,

                     58.178, 46.212, 36.708, 29.158, 23.161, 18.397, 14.614,
                     11.608,9.221, 7.324, 5.818, 4.621, 3.671, 2.916, 2.316, 1.840,
                     1.461, 1.161, 0.992};

    double[] snelling_ratio = {0.010, 0.013,0.016, 0.020, 0.025, 0.032, 0.040,0.050,
                             0.063,0.079,0.100,0.126,
                             0.010, 0.013, 0.016, 0.020, 0.025, 0.032, 0.040, 0.050,
                             0.063, 0.079, 0.100, 0.126, 0.158, 0.200, 0.251,0.316,

                             0.010,0.013,0.016,0.020,0.025,0.032,0.040,0.050,0.063,
                             0.079, 0.100, 0.126, 0.158, 0.200, 0.251, 0.316, 0.398,
                             0.501,0.631};

    int bar_index;
    int width_In_Pixel;
    int max_width_In_Pixel;
    int scrolling_delta;
    int max_scroll_time, min_scroll_time, timerUpdate;
    float scrolling_time;
    String direction, snellingANDgroup, snelling, group;
    BufferedImage image;
    JLabel label,snellingLabel;
    JScrollPane scrollPane;
    int dots_per_inch = Toolkit.getDefaultToolkit().getScreenResolution();
    Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
    JFrame frame;
    Graphics g;

    public DrawingBars() {
        this.bar_index = 0;
        max_width_In_Pixel = (int) ((width[28] * dots_per_inch) / 25.4);
        width_In_Pixel = (int) ((width[bar_index] * dots_per_inch) / 25.4);
        direction = "right";
        this.max_scroll_time = 5;
        this.min_scroll_time = 1;
        this.timerUpdate = 50;
        this.scrolling_time = this.max_scroll_time;
        this.scrolling_delta =  dim.width /
                               (int)(scrolling_time * 1000 / timerUpdate);
       this.snellingANDgroup = "Snelling Ratio : 0.010, Group : A";
       this.group = "A";
    }

    public void triggerBars() {
        image = new BufferedImage(dim.width + max_width_In_Pixel * 2,
                                  dim.height, BufferedImage.TYPE_INT_RGB);

        label = new JLabel(new ImageIcon(image));
        snellingLabel = new JLabel(snellingANDgroup);
        snellingLabel.setText("ooof");
        snellingLabel.setBackground( Color.BLACK );
        snellingLabel.setForeground( Color.YELLOW );
        snellingLabel.setOpaque( true );
        snellingLabel.setFont( new Font( "Dialog", Font.BOLD, 15 ) );
        snellingLabel.setHorizontalTextPosition( JLabel.CENTER );
        snellingLabel.setEnabled( true );

        drawImage();

        scrollPane = new JScrollPane(label);
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.
                                              VERTICAL_SCROLLBAR_NEVER);
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.
                                                HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.getViewport().setScrollMode(JViewport.
                                               BLIT_SCROLL_MODE);

        // GraphicsDevice screen = screenSetup();
        // DisplayMode dmode = new DisplayMode(dim.width, dim.height, 32, 60);
        // BufferStrategy bufstrat = frame.getBufferStrategy();
        // Graphics g = bufstrat.getDrawGraphics();
        // GraphicsConfiguration gc = device.getDefaultConfiguration();


        frame = new JFrame();
        frame.setUndecorated(true);
        //frame.createBufferStrategy(2);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(scrollPane);
        frame.getContentPane().add(snellingLabel,BorderLayout.SOUTH);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        GraphicsEnvironment env = GraphicsEnvironment.
                                  getLocalGraphicsEnvironment();
        GraphicsDevice device = env.getDefaultScreenDevice();

        device.setFullScreenWindow(frame);

        // screen.setFullScreenWindow(frame);
        // screen.setDisplayMode(dmode);

        ActionListener al = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JViewport vp = scrollPane.getViewport();
                int x = vp.getViewPosition().x;
                if (direction.equals("right")) {
                    x -= scrolling_delta;
                    if (x < 0) {
                        x += (-x+width_In_Pixel * 2-1)/(width_In_Pixel * 2) * width_In_Pixel * 2;
                    }
                } else if (direction.equals("left")) {
                    x += scrolling_delta;
                    if (x >= width_In_Pixel * 2) {
                        x -= x/(width_In_Pixel * 2) * width_In_Pixel * 2;
                    }
                }
                vp.setViewPosition(new Point(x, 0));
            }
        };
        new Timer(timerUpdate, al).start();
    }

    public void drawImage() {
        snellingLabel.setText(snellingANDgroup);
        g = image.getGraphics();
        g.setColor(Color.WHITE);
        g.clearRect(0, 0, dim.width + max_width_In_Pixel * 2, dim.height);
        for (int x = 0; x < dim.width + width_In_Pixel * 2;
                     x += width_In_Pixel * 2) {
            g.fillRect(x, 0, width_In_Pixel, dim.height);
        }
    }

    public void keyBoardListening() {
        scrollPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.
                getKeyStroke("DOWN"), "decreaseWidth");
        scrollPane.getActionMap().put("decreaseWidth",
                                      new AbstractAction("decreaseWidth") {
            public void actionPerformed(ActionEvent evt) {
                increaseBarIndex();
                setWidthInPixel();
                drawImage();
            }
        }
        );

        scrollPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.
                getKeyStroke("UP"), "increaseWidth");
        scrollPane.getActionMap().put("increaseWidth",
                                      new AbstractAction("increaseWidth") {
            public void actionPerformed(ActionEvent evt) {
                decreaseBarIndex();
                setWidthInPixel();
                drawImage();
            }
        }
        );

        scrollPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.
                getKeyStroke("A"), "GroupA");
        scrollPane.getActionMap().put("GroupA", new AbstractAction("GroupA") {
            public void actionPerformed(ActionEvent evt) {
                setBarIndex(0);
                setWidthInPixel();
                drawImage();
            }
        }
        );

        scrollPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.
                getKeyStroke("B"), "GroupB");
        scrollPane.getActionMap().put("GroupB", new AbstractAction("GroupB") {
            public void actionPerformed(ActionEvent evt) {
                setBarIndex(12);
                setWidthInPixel();
                drawImage();
            }
        }
        );

        scrollPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.
                getKeyStroke("C"), "GroupC");
        scrollPane.getActionMap().put("GroupC", new AbstractAction("GroupC") {
            public void actionPerformed(ActionEvent evt) {
                setBarIndex(28);
                setWidthInPixel();
                drawImage();
            }
        }
        );

        scrollPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.
                getKeyStroke("RIGHT"), "changeDirectionToRight");
        scrollPane.getActionMap().put("changeDirectionToRight",
                                      new AbstractAction(
                                              "changeDirectionToRight") {
            public void actionPerformed(ActionEvent evt) {
                setDirection("right");
                drawImage();
            }
        }
        );
        scrollPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.
                getKeyStroke("LEFT"), "changeDirectionToLeft");
        scrollPane.getActionMap().put("changeDirectionToLeft",
                                      new AbstractAction(
                                              "changeDirectionToLeft") {
            public void actionPerformed(ActionEvent evt) {
                setDirection("left");
                drawImage();
            }
        }
        );
        scrollPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.
                getKeyStroke("Z"), "increaseSpeed");
        scrollPane.getActionMap().put("increaseSpeed",
                                      new AbstractAction("increaseSpeed") {
            public void actionPerformed(ActionEvent evt) {
                increaseSpeed();
                drawImage();
            }
        }
        );

        scrollPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.
                getKeyStroke("X"), "decreaseSpeed");
        scrollPane.getActionMap().put("decreaseSpeed",
                                      new AbstractAction("decreaseSpeed") {
            public void actionPerformed(ActionEvent evt) {
                decreaseSpeed();
                drawImage();
            }
        }
        );
        scrollPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.
                getKeyStroke("ESCAPE"), "EXIT");
        scrollPane.getActionMap().put("EXIT",
                                      new AbstractAction("EXIT") {
            public void actionPerformed(ActionEvent evt) {
                System.exit(0);
            }
        }
        );

    }

    public void setBarIndex(int barIndex) {
        this.bar_index = barIndex;
        if(bar_index == 0)
            group = "A";
        else if(bar_index == 12)
            group = "B";
        else if(bar_index == 28)
            group = "C";
        snelling = " "+ snelling_ratio[bar_index];
        snellingANDgroup = snelling + "  " + group ;
    }

    public int getBarIndex() {
        return this.bar_index;
    }

    public void increaseBarIndex() {
        if (bar_index == 11) {
            bar_index = 11;
        } else if (bar_index == 27) {
            bar_index = 27;
        } else if (bar_index == 46) {
            bar_index = 46;
        } else {
            bar_index++;
        }
        snelling = " " + snelling_ratio[bar_index];
        snellingANDgroup = snelling + "  " + group ;
    }

    public void decreaseBarIndex() {
        if (bar_index == 0) {
            bar_index = 0;
        } else if (bar_index == 12) {
            bar_index = 12;
        } else if (bar_index == 28) {
            bar_index = 28;
        } else {
            bar_index--;
        }
        snelling = " " + snelling_ratio[bar_index];
        snellingANDgroup = snelling + "  " + group ;
    }

    public void setWidthInPixel() {

        this.width_In_Pixel = (int) ((width[bar_index] * dots_per_inch) /
                                     25.4);
    }

    public int getWidthInPixel() {
        return width_In_Pixel;
    }

    public void setDirection(String direction) {
        this.direction = new String(direction);
    }

    public void increaseSpeed() {
        if (scrolling_time == min_scroll_time) {
            scrolling_time = min_scroll_time;
        } else {
            scrolling_time -= 0.5;
            scrolling_delta =  dim.width /
                              (int)(scrolling_time * 1000 / timerUpdate);
            System.out.println("Speed increased, time is now " + scrolling_time +
                               " and delta is" + scrolling_delta );

        }
    }

    public void decreaseSpeed() {
        if (scrolling_time == max_scroll_time) {
            scrolling_time = max_scroll_time;
        } else {
            scrolling_time += 0.5;
            scrolling_delta =  dim.width /
                              (int)(scrolling_time * 1000 / timerUpdate);
            System.out.println("Speed decreased, time is now " + scrolling_time +
                               " and delta is" + scrolling_delta );
        }

    }

    private static GraphicsDevice screenSetup() {
        GraphicsEnvironment ge = GraphicsEnvironment.
                                 getLocalGraphicsEnvironment();
        GraphicsDevice[] gs = ge.getScreenDevices();
        GraphicsDevice gdev = gs[0];
        return gdev;
    }

}

package sliding_bars;

import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;

public class Sliding
{
        public static void main(String[] args)
        {
               DrawingBars drawingBars = new DrawingBars();
               drawingBars.triggerBars();
               drawingBars.keyBoardListening();
        }
}

I think doing it with simple awt would be more flexible, but i never used it, so i dn't know how to create a smooth movement.

.

The following is a small jME Test which also moves a few white bars around the screen.

As you see, its pretty small and easy to understand (i hope) :slight_smile:



The monitor itself could also cause visual tearing if hes slower than like 20ms.



import java.util.ArrayList;

import com.jme.app.SimpleGame;
import com.jme.renderer.Renderer;
import com.jme.scene.Spatial.CullHint;
import com.jme.scene.shape.Quad;
import com.jme.util.Timer;


public class TestSlidingBars2D extends SimpleGame {
    // width in pixels
    private int barWidth = 20;
    // speed in pixel per second
    private float barSpeed = 500;
    // Array of Bars to move
    private ArrayList<Quad> bars = new ArrayList<Quad>();
   
    @Override
    protected void simpleInitGame() {
        lightState.detachAll();
        rootNode.setRenderQueueMode(Renderer.QUEUE_ORTHO);
       
        // create a few bars and attach it to the scene
        for (int i = 0, xLoc = 0; xLoc < display.getWidth(); i++) {
            xLoc = barWidth*2*i;
            System.out.println(xLoc);
            Quad bar = new Quad("q" +i, barWidth, display.getHeight());
            // move the bar to the far left of the screen
            bar.setLocalTranslation(barWidth/2 +xLoc, display.getHeight()/2, 0);
            bar.setCullHint(CullHint.Never);
            // add the bar to the array of bars, to move them later
            bars.add(bar);
            // attach the bar to the screen
            rootNode.attachChild(bar);
        }
    }

    /**
     * Move the Bars to the right.
     */
    @Override
    protected void simpleUpdate() {
        // move all bars
        for (Quad bar : bars) {
            if (bar.getLocalTranslation().x >= display.getWidth()) {
                // move the bar back to the left side of the screen
                bar.getLocalTranslation().x = barWidth/2;
            }
            // move the bar to the right, independent of the current framerate
            bar.getLocalTranslation().x += barSpeed*Timer.getTimer().getTimePerFrame();
        }
    }
   
    public static void main(String[] args) {
        TestSlidingBars2D game = new TestSlidingBars2D();
        game.setConfigShowMode(ConfigShowMode.AlwaysShow);
        game.getNewSettings().setVerticalSync(true);
        game.start();
    }
}



edit: even created a small webstart app :)
(might need to download the jnlp and doubleclick it localy, somehow it wont open correctly)
TestSlidingBars2D

Thanks Core-Dump for the demo in web start application, it worked fine as a web start application. it is simple and understandable  :slight_smile: .



I tried to run it as an application, i added the jME_2.0.jar to my classpath, also the jars in the lib folder were added, but I got the following runtime error message.



C:BorlandJBuilder2006jdk1.5binjavaw -classpath "C:Documents and SettingsAhmedjbprojectswingsclasses;C:Documents and SettingsAhmedMy DocumentsgoodcodeFilthy-Rich-Clients-FadeInButtonlibAnimatedTransitions.jar;C:Documents and SettingsAhmedMy DocumentsgoodcodeFilthy-Rich-Clients-FadeInButtonlibswing-worker.jar;C:Documents and SettingsAhmedMy DocumentsgoodcodeFilthy-Rich-Clients-FadeInButtonlibTimingFramework-0.55.jar;C:Documents and SettingsAhmedMy DocumentsgoodcodeFilthy-Rich-Clients-FadeInButtonlibTimingFramework.jar;C:Documents and SettingsAhmedMy DocumentsgoodPhDjavajME_2.0_Complete_(r4093)jME_2.0.jar;C:Documents and SettingsAhmedMy DocumentsgoodPhDjavajME_2.0_Complete_(r4093)libgluegen-rt.jar;C:Documents and SettingsAhmedMy DocumentsgoodPhDjavajME_2.0_Complete_(r4093)libjinput.jar;C:Documents and SettingsAhmedMy DocumentsgoodPhDjavajME_2.0_Complete_(r4093)libjogl.jar;C:Documents and SettingsAhmedMy DocumentsgoodPhDjavajME_2.0_Complete_(r4093)libjorbis-0.0.17.jar;C:Documents and SettingsAhmedMy DocumentsgoodPhDjavajME_2.0_Complete_(r4093)liblwjgl_util_applet.jar;C:Documents and SettingsAhmedMy DocumentsgoodPhDjavajME_2.0_Complete_(r4093)liblwjgl_util.jar;C:Documents and SettingsAhmedMy DocumentsgoodPhDjavajME_2.0_Complete_(r4093)liblwjgl.jar;C:Documents and SettingsAhmedMy DocumentsgoodPhDjavajME_2.0_Complete_(r4093)libswt.jar;C:BorlandJBuilder2006jdk1.5jrelibplugin.jar;C:BorlandJBuilder2006jdk1.5jrelibrt.jar;C:BorlandJBuilder2006jdk1.5jrelibextdnsns.jar;C:BorlandJBuilder2006jdk1.5jrelibextsunpkcs11.jar;C:BorlandJBuilder2006jdk1.5jrelibextsunjce_provider.jar;C:BorlandJBuilder2006jdk1.5jrelibextlocaledata.jar;C:BorlandJBuilder2006jdk1.5jrelibimindicim.jar;C:BorlandJBuilder2006jdk1.5jrelibimthaiim.jar;C:BorlandJBuilder2006jdk1.5jrelibjavaws.jar;C:BorlandJBuilder2006jdk1.5jrelibdeploy.jar;C:BorlandJBuilder2006jdk1.5jrelibjsse.jar;C:BorlandJBuilder2006jdk1.5jrelibjce.jar;C:BorlandJBuilder2006jdk1.5jrelibcharsets.jar;C:BorlandJBuilder2006jdk1.5libtools.jar;C:BorlandJBuilder2006jdk1.5libjconsole.jar;C:BorlandJBuilder2006jdk1.5libhtmlconverter.jar;C:BorlandJBuilder2006jdk1.5libdt.jar"  swings.TestSlidingBars2D
Mar 15, 2009 8:24:08 PM com.jme.system.PropertiesGameSettings <init>
INFO: PropertiesGameSettings created
Mar 15, 2009 8:24:09 PM com.jme.system.PropertiesGameSettings load
WARNING: Could not load properties. Creating a new one.
Mar 15, 2009 8:24:09 PM com.jme.app.BaseGame start
INFO: Application started.
Mar 15, 2009 8:24:09 PM com.jme.system.PropertiesGameSettings <init>
INFO: PropertiesGameSettings created
Mar 15, 2009 8:24:09 PM com.jme.system.PropertiesGameSettings load
WARNING: Could not load properties. Creating a new one.
Mar 15, 2009 8:24:09 PM class swings.TestSlidingBars2D start()
SEVERE: Exception in game loop
java.lang.UnsatisfiedLinkError: no lwjgl in java.library.path
   at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)
   at java.lang.Runtime.loadLibrary0(Runtime.java:822)
   at java.lang.System.loadLibrary(System.java:992)
   at org.lwjgl.Sys$1.run(Sys.java:72)
   at java.security.AccessController.doPrivileged(Native Method)
   at org.lwjgl.Sys.doLoadLibrary(Sys.java:65)
   at org.lwjgl.Sys.loadLibrary(Sys.java:81)
   at org.lwjgl.Sys.<clinit>(Sys.java:98)
   at org.lwjgl.opengl.Display.<clinit>(Display.java:129)
   at com.jme.system.lwjgl.LWJGLPropertiesDialog$ModesRetriever.run(LWJGLPropertiesDialog.java:682)
   at com.jme.app.AbstractGame.getAttributes(AbstractGame.java:252)
   at com.jme.app.BaseGame.start(BaseGame.java:67)
   at swings.TestSlidingBars2D.main(TestSlidingBars2D.java:60)
Mar 15, 2009 8:24:09 PM com.jme.app.BaseSimpleGame cleanup
INFO: Cleaning up resources.
Mar 15, 2009 8:24:09 PM com.jme.system.lwjgl.LWJGLDisplaySystem <init>
INFO: LWJGL Display System created.
Mar 15, 2009 8:24:09 PM com.jme.app.BaseGame start
INFO: Application ending.


you need to set java.library.path=lib/natives somehow, but i dont know how in jbuilder

Hi,



I added this line

DisplaySystem.getDisplaySystem().setVSyncEnabled(true);

as suggested from Del to your nice simple working piece, core-dump, and all the flickering was completely removed.





I will work to add the following features to the software:



1- make the bar widths more accurate(because now there is some gaps).



2- changing the bar widths from the K.B key



3- Change the speed of the bars also from the K.B.



4- reversing the bars movement direction.



Thanks a lot ,

Any hints are appreciated,

Ahmed



package swings;

import java.util.ArrayList;

import com.jme.app.SimpleGame;
import com.jme.renderer.Renderer;
import com.jme.scene.Spatial.CullHint;
import com.jme.scene.shape.Quad;
import com.jme.util.Timer;


public class TestSlidingBars2D extends SimpleGame {
    // width in pixels
    private int barWidth = 20;
    // speed in pixel per second
    private float barSpeed = 800;
    // Array of Bars to move
    private ArrayList<Quad> bars = new ArrayList<Quad>();

    @Override
    protected void simpleInitGame() {
        lightState.detachAll();
        rootNode.setRenderQueueMode(Renderer.QUEUE_ORTHO);

        // create a few bars and attach it to the scene
        for (int i = 0, xLoc = 0; xLoc < display.getWidth(); i++) {
            xLoc = barWidth*2*i;
            System.out.println(xLoc);
            Quad bar = new Quad("q" +i, barWidth, display.getHeight());
            // move the bar to the far left of the screen
            bar.setLocalTranslation(barWidth/2 +xLoc, display.getHeight()/2, 0);
            bar.setCullHint(CullHint.Never);
            // add the bar to the array of bars, to move them later
            bars.add(bar);
            // attach the bar to the screen
            rootNode.attachChild(bar);
        }
    }

    /**
     * Move the Bars to the right.
     */
    @Override
    protected void simpleUpdate() {
        // move all bars
        for (Quad bar : bars) {
            if (bar.getLocalTranslation().x >= display.getWidth()) {
                // move the bar back to the left side of the screen
                bar.getLocalTranslation().x = barWidth/2;
            }
            // move the bar to the right, independent of the current framerate
            bar.getLocalTranslation().x += barSpeed*Timer.getTimer().getTimePerFrame();
        }
    }

    public static void main(String[] args) {
        TestSlidingBars2D game = new TestSlidingBars2D();
        game.setConfigShowMode(ConfigShowMode.AlwaysShow);
        com.jme.system.DisplaySystem.getDisplaySystem().setVSyncEnabled(true);
        game.getNewSettings().setVerticalSync(true);
        game.start();
    }
}


seems game.getNewSettings().setVerticalSync(true); didn't work as expected, just remove that and only use setVSyncEnabled() like you did.



i also modified the update part to reduce lag spikes (when starting the app) when moving the bars.


       tpf = Timer.getTimer().getTimePerFrame();
       if (tpf > 0.01f) {
           tpf = 0.01f;
       }




    private float tpf = 0;
    /**
     * Move the Bars to the right.
     */
    @Override
    protected void simpleUpdate() {
       tpf = Timer.getTimer().getTimePerFrame();
       if (tpf > 0.01f) {
           tpf = 0.01f;
       }
        // move all bars
        for (Quad bar : bars) {
            if (bar.getLocalTranslation().x - barWidth >= display.getWidth() ) {
                // move the bar back to the left side of the screen
                bar.getLocalTranslation().x = -barWidth/2;
            }
            // move the bar to the right, independent of the current framerate
            bar.getLocalTranslation().x += barSpeed*tpf;
        }
    }

I am trying to control the sliding speed of each bar,  the time each bar takes to move from right to left is maximum 5 seconds and minimum 1 second. I started with the 5 seconds speed and to make it real , I started using the real tpf, which seems equal exactly to the monitor refresh rate, but the updates are not stable,



protected void simpleUpdate() {
          tpf = Timer.getTimer().getTimePerFrame();
          System.out.println("Timer per frame is " + tpf);
        /*  if (tpf > 0.01f) {
           tpf = 0.01f;
         }*/
           // move all bars
           for (Quad bar : bars) {
               if (bar.getLocalTranslation().x - barWidth >= display.getWidth() ) {
                   // move the bar back to the left side of the screen
                   bar.getLocalTranslation().x = barWidth/2;
               }
             // move the bar to the right, independent of the current framerate
             //  bar.getLocalTranslation().x += barSpeed*tpf;
               bar.getLocalTranslation().x += ( display.getWidth()* tpf ) / Speed ;
           }
    }

Maybe look at the TimedLifeController to move your bars (you can set the amount of time you want it to run, and it updates based on a percent)…



Also, check out the test (specifically the TimedLifeControllerTest).