Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (476)
Games in Android Showcase (106)
games submitted by our members
Games in WIP (530)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Scrolling 2D Image problem  (Read 1583 times)
0 Members and 1 Guest are viewing this topic.
Offline ChouChou

Senior Newbie





« Posted 2010-06-17 09:29:46 »

Dear JGO Members,


I'm having this weird problem when doing side scrolling at a fast speed, the rectangles drew with g.fillRec() start to have some sort of silhouette and images flashes, I have tried to use variable framerate game loop or increase fps in the fixed framerate loop but neither works. The following is an attempt to demonstrate the problem:

Flashing when moving 1
http://www.youtube.com/watch?v=aS6LF9GNkjM
Flashing when moving 2
http://www.youtube.com/watch?v=aS6LF9GNkjM

Picture to show where the silhouette is when scrolling:


Uploaded with ImageShack.us

I'm not exactly sure what the cause of the problem is since it looks fine if I scroll at slower speed, I'm guess the problem has to do with the game loop I'm using, note that I want to have a fixed framerate game loop. Below is the code of the loop, thanks in advance!

The loop is taken from here:
Fixed Framerate loop
http://wiki.games4j.com/wiki/en/Timing_in_main_loops

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
        private int fps;
   private long timeThen;

   /** Set FPS */
   private void setFPS() {
      fps = 60;
      timeThen = System.nanoTime();
   }

        /** Timer */
   public void sync() {
      long gapTo = 1000000000L / fps + timeThen;
      long timeNow = System.nanoTime();
     
      while (gapTo > timeNow) {
         try { Thread.sleep(1);
         } catch (InterruptedException e) {}
         timeNow = System.nanoTime();
      }
      timeThen = timeNow;
   }


       /** Fixed Framerate Game loop */
   private void gameLoop() {
      long currentUpdateTime = System.nanoTime();
      long lastUpdateTime;  
         
      while(gameRunning) {
         
         lastUpdateTime = currentUpdateTime;
         currentUpdateTime = System.nanoTime();
         long elapsedTime = (currentUpdateTime -    lastUpdateTime)/(1000*1000);
         
         /** Update Game */
         gameUpdate(elapsedTime);
         /** Render */
         gameRender();
         /** Run timer */
         sync();
      }
   }


Offline Riven
« League of Dukes »

JGO Overlord


Medals: 742
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #1 - Posted 2010-06-17 09:38:05 »

So what does gameRender() look like? Further, you really want to either paint on the component from the EDT, or paint to an offscreen image, and blit that to the Canvas from the EDT. Either way, do not grab the Graphics object from a component to start drawing from a 'random' thread. Having said that, I never saw a silhouette like that before.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline ChouChou

Senior Newbie





« Reply #2 - Posted 2010-06-17 09:41:21 »

Hey Riven,


Thanks for the fast reply, this is what the gameRender() looks like, sorry but what is EDT?

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
   GameCore() {
      Frame frame = new Frame("Side Scroller");
      frame.setLayout(null);
      setBounds(0,0,WINDOWS_WIDTH,WINDOWS_HEIGHT);
      frame.add(this);
      frame.setSize(WINDOWS_WIDTH,WINDOWS_HEIGHT);
      frame.setResizable(false);
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
      frame.addKeyListener(this);
      addKeyListener(this);
      //Exit windows
     frame.addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });
     

      /** create the strategy used for accelerated rendering. */
      createBufferStrategy(2);
      strategy = getBufferStrategy();

                 //Other code here
       
      setFPS();
      gameLoop();
   }


private void gameRender() {
      Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
     
      // clear the screen
     g.setColor(Color.WHITE);
      g.fillRect(0,0,WINDOWS_WIDTH,WINDOWS_HEIGHT);
      g.translate(0, 10);

      if(player.isAlive() && gameStart) {
         /** Paint map */
         map.paint(g);
         
         /** Paint enemies */
         spawn.paint(g);
         
         /** Pain Power Ups */
         powerUp.paint(g);
         
         /** Paint player */
         player.paint(g);
         
         /** Paint GUI */
         gui.paint(g);
      }

      /** Paint Scene */
      scene.paint(g);
     
      /** flip the buffer so we can see the rendering */
      g.dispose();
      strategy.show();
   }



Edit: I'm trying to keep the game single threaded to keep it as simple as possible. I'm not very good with multi-threading yet.

Edit 2: The silhouette only happens on the g.fillRect() Rectangles, the images don't have that effect and it only happens when I'm scrolling.

Edit 3: The paint(g) code is something like this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
   /** Draw Player */
   public void paint(Graphics2D g) {
      /** Paint spells */
      for(int i = spellList.size() - 1; i >= 0 ; i--) {
            spellList.get(i).paint(g);
      }
         
      /** Paint explosions */
      for(int i = explosion.size() - 1; i >= 0; i--) {
         if(explosion.get(i).Length() != 0) {
            explosion.get(i).paint(g);
         }
      }

      g.drawImage(anim.getCurrentImage(), xp + offsetX - 10, yp + offsetY, null);
   }

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ChouChou

Senior Newbie





« Reply #3 - Posted 2010-06-17 10:00:10 »

double posted by accident..
Offline adon_y_coya

Senior Newbie





« Reply #4 - Posted 2010-06-18 09:07:19 »

Put a panel in your frame (and set layout null) then put a canvas in that panel and setIgnoreRepaint(true) and have the canvas createBufferStrategy(2) and then request focus.
That solved all flickering issues I've had.
Offline ChouChou

Senior Newbie





« Reply #5 - Posted 2010-06-18 11:24:55 »

Put a panel in your frame (and set layout null) then put a canvas in that panel and setIgnoreRepaint(true) and have the canvas createBufferStrategy(2) and then request focus.
That solved all flickering issues I've had.

Thanks for the reply! I'll try that when I get home. I'm not using any swing components tho will that be fine?
Offline ChouChou

Senior Newbie





« Reply #6 - Posted 2010-06-19 08:26:45 »

EDIT: I found the problem, it has nothing to do with the game loop at all, there's something wrong with my scrolling offset, I'll try and fix it now. Thanks for the help!

I tried the method adon_y_coya suggested but the flickering is still there =/. I'm just curious, what are the possible causes that could cause flickering in java?

Here's the code for my frame:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
Frame frame = new Frame("Stone of Franks");
      Panel panel = new Panel();
      panel.setLayout(null);
     
      Canvas canvas = new Canvas();
      canvas.setBounds(0,0,WINDOWS_WIDTH,WINDOWS_HEIGHT);
      canvas.setIgnoreRepaint(true);
     
      panel.add(canvas);
      frame.add(panel);

      frame.setSize(WINDOWS_WIDTH,WINDOWS_HEIGHT);
      frame.setResizable(false);
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
     
      /** create the strategy used for accelerated rendering. */
      canvas.createBufferStrategy(2);
      strategy = canvas.getBufferStrategy();
     
      canvas.requestFocus();
     
      //Exit windows
     frame.addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });


         /** Add Key Listener */
      canvas.addKeyListener(this);
     
      /** Add Mouse Listener */
      canvas.addMouseListener(this);
      canvas.addMouseMotionListener(this);

Offline oskarillo

Junior Newbie





« Reply #7 - Posted 2010-06-20 21:30:08 »

im trying something similar and I think what we need is a way to do vsync, I asked for that in other post, I hope someone give an answer.  Cool
Offline ChouChou

Senior Newbie





« Reply #8 - Posted 2010-06-21 06:34:50 »

im trying something similar and I think what we need is a way to do vsync, I asked for that in other post, I hope someone give an answer.  Cool

Does vsync get rid of flickering? I'm using double buffering and I still get flickering. It would be really nice if someone can show me how to do scrolling properly, perhaps my way of doing it is just wrong. The way I scroll is to have screen follow this "camera(an invisible rectangle) and when I move mouse to the left/right edges of the screen it increments/decrements the X position of the camera and as an end result the map scrolls.

I noticed in my games when ever I scroll right my character "shifts back" a little bit when he's near the edge, perhaps this will lead to the root cause of my weird flickering bug.


Edit: I tried it, still doesn't get rid of flickering and I'm not sure whats wrong with my scrolling code.

Here's how I do scrolling in case anyone's interested:
I have 2 variables to tell where the camera is at now, lets forget about Y for now since I'm only doing horizontal scrolling. VisibleX is declared as    public static int visibleX = GameCore.WINDOWS_WIDTH / (8 * Map.TILE_SIZE);

Where WINDOWS_WIDTH is 1024(my screen width);
 and camera.x is camera's current position.

Cornershift is just to shift edges according to player's position so that things outside of the actual map won't be seen.

1  
2  
3  
mapPosX = Camera.visibleX - Camera.x;
mapPosY = Camera.visibleY - Camera.y;
cornerShift();


Then this is how I calculate the offset to be used for all scrolling

1  
2  
3  
4  
5  
6  
7  
8  
/** Offset X for Camera */
int offsetX = (int)((GameCore.mapPosX + GameCore.fixX)* Map.TILE_SIZE);

/** Offset Y for Camera */
int offsetY = (int)((GameCore.mapPosY + GameCore.fixY) * Map.TILE_SIZE);

// Somewhere in paint method I draw the rectangle with the offset
g.drawRect(xp + offsetX, yp + offsetY, width, height);



I've tried all sorts of game loop today, tried running the game in full screen/windowed application as well and different methods posted on forum to get rid of flickering. I can't really find any bugs/flaws in my scrolling method and none of the methods I tried work so far, any help would be greatly appreciated.
Offline ChouChou

Senior Newbie





« Reply #9 - Posted 2010-06-22 15:57:29 »

I think I got rid of flickering, can someone please be kind enough to check if you still get flickering when scrolling from my game? For some reason making it full screen seems to do the trick....I have no idea why...

Link to code, the zip file contains 3 jars, just different way of doing things:
http://www.mediafire.com/?mndtjmninzt

Here's the code highlight for each jar, note that my screen has a resolution of 1024 * 768, scrolling is done by moving mouse to left/right edge of the screen:

- Sof_FS.jar  is the first full screen method I tried
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
  GraphicsDevice gd;

        GraphicsEnvironment ge =
              GraphicsEnvironment.getLocalGraphicsEnvironment();
          gd = ge.getDefaultScreenDevice();
          GraphicsConfiguration gc = gd.getDefaultConfiguration();

         final int currentRefreshrate = gd.getDisplayMode().getRefreshRate();
         
         System.out.println("Reported Refreshrate=" + currentRefreshrate);
         targetFps = (currentRefreshrate==DisplayMode.REFRESH_RATE_UNKNOWN?60:currentRefreshrate);
           
      Frame frame = new Frame(gc);
      frame.setIgnoreRepaint(true);
      frame.setUndecorated( true );
      frame.setLayout(null);
      setIgnoreRepaint(true);
      setBounds(0,0,WINDOWS_WIDTH,WINDOWS_HEIGHT);
      frame.add(this);
      frame.setSize(WINDOWS_WIDTH,WINDOWS_HEIGHT);
      frame.setFocusTraversalKeysEnabled(false);
      frame.setResizable(false);
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
     
       // Change to full screen
      gd.setFullScreenWindow(frame);
       if( gd.isDisplayChangeSupported() ) {
         gd.setDisplayMode(
           new DisplayMode( WINDOWS_WIDTH, WINDOWS_HEIGHT, 32, DisplayMode.REFRESH_RATE_UNKNOWN )
         );
       }


- Sof_FS2.jar  is the second full screen method I tried:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
                Frame frame = new Frame("Test Scroller");
      frame.setLayout(null);
      setBounds(0,0,WINDOWS_WIDTH,WINDOWS_HEIGHT);
      frame.add(this);
      frame.setSize(WINDOWS_WIDTH,WINDOWS_HEIGHT);
      frame.setResizable(false);
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
     
//      Exit windows
     frame.addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });
     
      /** create the strategy used for accelerated rendering. */
      createBufferStrategy(2);
      strategy = getBufferStrategy();

            //I simply added these 2 lines to the original code
      GraphicsEnvironment.getLocalGraphicsEnvironment().
            getDefaultScreenDevice().setFullScreenWindow(frame);


- SoF.jar, the non-full screen mode:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
Frame frame = new Frame("Side Scroller");
      frame.setLayout(null);
      setBounds(0,0,WINDOWS_WIDTH,WINDOWS_HEIGHT);
      frame.add(this);
      frame.setSize(WINDOWS_WIDTH,WINDOWS_HEIGHT);
      frame.setResizable(false);
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
     
//      Exit windows
     frame.addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });
     
      /** create the strategy used for accelerated rendering. */
      createBufferStrategy(2);
      strategy = getBufferStrategy();


Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

pw (11 views)
2014-07-24 01:59:36

Riven (10 views)
2014-07-23 21:16:32

Riven (11 views)
2014-07-23 21:07:15

Riven (12 views)
2014-07-23 20:56:16

ctomni231 (42 views)
2014-07-18 06:55:21

Zero Volt (38 views)
2014-07-17 23:47:54

danieldean (32 views)
2014-07-17 23:41:23

MustardPeter (34 views)
2014-07-16 23:30:00

Cero (50 views)
2014-07-16 00:42:17

Riven (50 views)
2014-07-14 18:02:53
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!