8 Replies Latest reply: Jun 9, 2010 11:13 AM by 843853 RSS

    how to make my game scroll more smoothly ?

    843853
      Hello! I'm new at Java, however I have some programming experience.
      I would like to make a tile engine. On the following link is an example of what I have so far:
      [link-->|http://members.home.nl/bramdenhond/testjava/]
      If you move your mouse over the area, the world scrolls.

      However, I don't think it scrolls smoothly enough.
      In the tutorial I was following, this technique was recommended for double-buffering:
              //** Update - Method, implements double buffering */
              public void update (Graphics g)
              {
      
                    // initialize buffer
                    if (dbImage == null)
                    {
                          dbImage = createImage (this.getSize().width, this.getSize().height);
                          dbg = dbImage.getGraphics ();
                    }
      
                    // clear screen in background
                    dbg.setColor (getBackground ());
                    dbg.clearRect(0, 0, this.getSize().width, this.getSize().height);
                    //dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);
      
                    // draw elements in background
                    dbg.setColor (getForeground());
                    paint (dbg);
      
                    // draw image on the screen
                    g.drawImage (dbImage, 0, 0, this);
      
              }
      For the timing, I'm using a Thread, as recommended in the tutorial:
               public void start ()
               {
                    // define a new thread
                    Thread th = new Thread (this);
                    // start this thread
                    th.start ();
                }
      
                public void run ()
                {
      
                    // lower ThreadPriority
                    Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
      
                    // run a long while (true) this means in our case "always"
                    while (true)
                    {
                     
                          // repaint the applet
                          repaint();
      
                          try
                          {
                                // Stop thread for 20 milliseconds
                                Thread.sleep (2);
                          }
                          catch (InterruptedException ex)
                          {
                                // do nothing
                          }
      
                          // set ThreadPriority to maximum value
                          Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
                                              
                    } 
      
                 }
      I was wondering if someone if this is indeed the best approach, and if there are
      any alternatives.

      Thanks!
        • 1. Re: how to make my game scroll more smoothly ?
          843853
          I prefer the javax.swing.Timer and SWING with offscreen rendering to the threading method you have shown. With the timer you set it up to fire how ever many times per second you want your screen updated and you render everything off screen into a BufferedImage--you basically call a repaint() on your display container each time the timer fires, then do the offscreen rendering for the next time.
          • 2. Re: how to make my game scroll more smoothly ?
            843853
            Here is a basic scrolling background using SWING and a javax.swing.Timer. Put what ever image you want in there for the background and adjust this line: "if(upperLeft >= width) upperLeft = 38; // adjust to make rollover seemless" until you don't get a jump at the rollover when the subimage has to "go back to the start".
            import java.awt.event.ActionEvent;
            import java.awt.event.ActionListener;
            import java.awt.image.BufferedImage;
            import java.awt.Image;
            import java.awt.Dimension;
            import java.awt.Graphics;
            import java.awt.Graphics2D;
            import java.awt.MediaTracker;
            import java.awt.Toolkit;
            import javax.swing.JFrame;
            import javax.swing.JPanel;
            import javax.swing.Timer;
            public class JAniDemo {
              private BufferedImage biBackground = null;
              private Toolkit tk;
              private JFrame f;
              JAniDemo(){
                tk = Toolkit.getDefaultToolkit();
                f = new JFrame("AniDemo 1.0");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                loadBackground("background.jpg");
                myPanel p = new myPanel(biBackground);
                f.add(p);
                f.pack();
                f.setVisible(true);
              }
              private void loadBackground(String fn){
                Image im = tk.getImage(fn);
                MediaTracker mt = new MediaTracker(f);
                mt.addImage(im,0);
                try{
                  mt.waitForID(0);
                  biBackground = new BufferedImage(1024, 512, BufferedImage.TYPE_INT_RGB);
                  Graphics2D g2 = biBackground.createGraphics();
                  g2.drawImage(im, 0, 0, null);
                  g2.dispose();
                }catch(InterruptedException e){
                  System.out.println(e.toString());
                }
              }
              public static void main(String[] args) {
                new JAniDemo();
              }
              class myPanel extends JPanel implements ActionListener{
                private BufferedImage background;
                private BufferedImage bi = null;
                private int upperLeft = 0;
                int width;
                int height;
                myPanel(BufferedImage bg){
                  super();
                  background = bg;
                  width = background.getWidth()/2;
                  height = background.getHeight();
                  bi = background.getSubimage(upperLeft,0,width,height);
                  setPreferredSize(new Dimension(width, height));
                  Timer t = new Timer(5, this);
                  t.start();
                }
                public void actionPerformed(ActionEvent e){  
                  upperLeft += 1;
                  if(upperLeft >= width) upperLeft = 38;  // adjust to make rollover seemless
                  bi = background.getSubimage(upperLeft,0,width,height);
                  repaint();
                }
                public void paintComponent(Graphics g){
                  g.drawImage(bi, 0, 0, this);
                }
              }
            }
            • 3. Re: how to make my game scroll more smoothly ?
              843853
              Thanks! I'm looking into it.
              • 4. Re: how to make my game scroll more smoothly ?
                843853
                I forgot to say, the background image should be 2 times the width of the display and the 2nd half of the width should be the same as the first... and the first should transition into the second that way you get a seemingly circular background scroll.
                • 5. Re: how to make my game scroll more smoothly ?
                  843853
                  Thanks alot! I now understand. The timer made things much easier for me!
                  • 6. Re: how to make my game scroll more smoothly ?
                    843853
                    Hi all,
                    I've changed this source code so I can move the character from bottom to up but scrolling background is up to bottom. How I can change this class for scrolling background from up to down and not viceversa?

                    import java.awt.event.ActionEvent;
                    import java.awt.event.ActionListener;
                    import java.awt.image.BufferedImage;
                    import java.awt.Image;
                    import java.awt.Dimension;
                    import java.awt.Graphics;
                    import java.awt.Graphics2D;
                    import java.awt.MediaTracker;
                    import java.awt.Toolkit;
                    import javax.swing.JFrame;
                    import javax.swing.JPanel;
                    import javax.swing.Timer;
                    public class JAniDemo {
                      private BufferedImage biBackground = null;
                      private Toolkit tk;
                      private JFrame f;
                      JAniDemo(){
                        tk = Toolkit.getDefaultToolkit();
                        f = new JFrame("AniDemo 1.0");
                        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                        loadBackground("C:\\image.png");
                        myPanel p = new myPanel(biBackground);
                        f.add(p);
                        f.pack();
                        f.setVisible(true);
                      }
                      private void loadBackground(String fn){
                        Image im = tk.getImage(fn);
                        MediaTracker mt = new MediaTracker(f);
                        mt.addImage(im,0);
                        try{
                          mt.waitForID(0);
                          biBackground = new BufferedImage(800, 641, BufferedImage.TYPE_INT_RGB);
                          Graphics2D g2 = biBackground.createGraphics();
                          g2.drawImage(im, 0, 0, null);
                          g2.dispose();
                        }catch(InterruptedException e){
                          System.out.println(e.toString());
                        }
                      }
                      public static void main(String[] args) {
                        new JAniDemo();
                      }
                      class myPanel extends JPanel implements ActionListener{
                        private BufferedImage background;
                        private BufferedImage bi = null;
                        private int upperCorner = 0;
                        int width;
                        int height;
                        myPanel(BufferedImage bg){
                          super();
                          background = bg;
                          width = background.getWidth()/2;
                          height = background.getHeight();
                          bi = background.getSubimage(0,upperCorner,width,height);
                          setPreferredSize(new Dimension(width, height));
                          Timer t = new Timer(25, this);
                          t.start();
                        }
                        public void actionPerformed(ActionEvent e){  
                          upperCorner -= 1;
                          if(UpperCorner >= height) UpperCorner = 38;  // adjust to make rollover seemless
                          bi = background.getSubimage(0,UpperCorner,width,height);
                          repaint();
                        }
                        public void paintComponent(Graphics g){
                          g.drawImage(bi, 0, 0, this);
                        }
                      }
                    }
                    Please see this changes of original source code:
                    bi = background.getSubimage(0,upperCorner,width,height);
                    width = background.getWidth()/2;
                    if(UpperCorner >= height) // for vertical
                    upperCorner -= 1; // for up to down scrolling

                    Can you help me? Thanks.
                    Regards.

                    Edited by: Rapworld on Jun 9, 2010 11:19 AM
                    • 7. Re: how to make my game scroll more smoothly ?
                      843853
                      This is an anciant thread, and don't hijack it. Please post a new thread with your code and people will be glad to help.
                      • 8. Re: how to make my game scroll more smoothly ?
                        843853
                        ok, done.
                        Regards.