Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (512)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (576)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
   Home   Help   Search   Login   Register   
  Show Posts
Pages: [1]
1  Game Development / Newbie & Debugging Questions / Re: Memory leak(?) and inefficient buffering problem on: 2012-02-01 22:38:13
First of all, thank you for your time and help.

@Magn919
Going point by point, most of the silencing(?) was done because it was shown as error unless something was done about it.
Like I said I'm very new to programming, so what do you suggest as best course of action for the exceptions?
Should I just call System.exit(0); line?

Organizational skill is something I need to improve on and quickly. Thank you for pointing that out.
I can fix the commenting habit by myself, but in terms of actual code I think I need more knowledge to really keep things tidy.
What I plan on doing along my long term project is to tidy up all the code everytime I reach certain "checkpoints".

The last point I didn't quite understand. It would be more helpful if you could be more detailed about the bufferstrategy.

@ra4king
I'm missing a huge chuck of programming knowledge to see how that create new Image loop is happening.
What I had in mind was that loadTileImage() method will only get called once in GameBoard class' default constructor.
Could you please write out a simple explanation of how and why the Images are being continuously created?
2  Game Development / Newbie & Debugging Questions / Memory leak(?) and inefficient buffering problem on: 2012-02-01 19:25:01
Just for quick self introduction, I'm fairly new to computer programming.
My background is just a semester of single CS introductory class. (I was majoring mechanical engineering back then a year ago.)
This semester I decided upon a personal long term project, and you might have guessed that it is making a game.
I delved into some forums such as this and watched tutorial videos, and I got "something" going on for now.
However there seems to be few problems with my program.

First thing is that the program seems to have a memory leakage.
Currently, the only task it does is to perpetually update steady, unchanging game state.
However, I checked on the task manager and the program kept on hogging more memory space.
It had some occassional memory drops, but it just kept on increaseing in the long run.
The parts that I coded by myself didn't seem to have problems, but I'm not sure of some parts that I got from "follow-along"s.

Second probem is that its image buffering sucks.
I'm using a double buffering method from a video tutorial of user "thejavahub", but I don't see much effect.
Also it takes more than 20ms just to do the task I mentioned above, which I believe will cause the game to go lower than 50 fps.
Below I'm posting two classes of my program that should hold enough source code for those willing to help.

/*EDIT
I forgot to mention what my questions were:
1) What's causing the memory leak? How do I prevent it? (Or is it even a memory leak?)
2) How do I get a smooth panning mechanism instead of the current ugly one?
3) What do you think about the program's "drawing algorithm"? Any improvement and/or criticism?
3) Any other criticism that is not related to my questions?

I want to learn programming well and from lots of perspective.
Harsh criticisms (criticisms, not insults) or even minor details such as missed programming convention is welcomed.

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  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

@SuppressWarnings("serial")
public class GameBoard extends JPanel implements Runnable {
   // Dependent to tile image size.
   private final int SCALE = 16;
   private final long PERIOD = 20 * 1000000; // Milliseconds to Nanoseconds
   
   private static int uIndex = 0;
   private static int vIndex = 0;
   private static int wIndex = 1;
   long beforeTime;
   long afterTime;
   long difference;
   long sleepTime;
   private Image TILE_0;
   private Image TILE_0_TOP;
   private Image TILE_A;
   private Image TILE_A_TOP;
   private Image TILE_B;
   private Image TILE_B_TOP;
   
   private Graphics bufferGraphics;
   private Image bufferImage;
   private Thread game;
   private volatile boolean running = false;
   
   private GameTile tileGrid;
   
   public GameBoard() {
      loadTileImage();
      tileGrid = new GameTile(2);
      setBackground(Color.WHITE);
      setFocusable(true);
      requestFocus();
     
      addKeyListener(new KeyAdapter() {
         @Override
         public void keyPressed(KeyEvent e) {
            switch(e.getKeyCode()) {
            default:
               break;
            case KeyEvent.VK_UP:
               if(uIndex < tileGrid.getU() / 2)
                  uIndex++;
               break;
            case KeyEvent.VK_DOWN:
               if(uIndex > -(tileGrid.getU() / 2))
                  uIndex--;
               break;
            case KeyEvent.VK_LEFT:
               if(vIndex < tileGrid.getV() / 2)
                  vIndex++;
               break;
            case KeyEvent.VK_RIGHT:
               if(vIndex > -(tileGrid.getV() / 2))
                  vIndex--;
               break;
            case KeyEvent.VK_PAGE_UP:
               if(wIndex < tileGrid.getW() - 2)
                  wIndex++;
               break;
            case KeyEvent.VK_PAGE_DOWN:
               if(wIndex > 2)
                  wIndex--;
               break;
            case KeyEvent.VK_SPACE:
               uIndex = 0;
               vIndex = 0;
               break;
            case KeyEvent.VK_ESCAPE:
               System.exit(0);
               break;
            }
         }
         @Override
         public void keyReleased(KeyEvent e) {}
         @Override
         public void keyTyped(KeyEvent e) {}
      });
   }
   
   public void addNotify() {
      super.addNotify();
      startGame();
   }
   private void startGame() {
      if(game == null || !running) {
         game = new Thread(this);
         game.start();
         running = true;
      }
   }
   public void stopGame() {
      if(running) {
         running = false;
      }
   }
   @SuppressWarnings("static-access")
   public void run() {
      while(running) {
         beforeTime = System.nanoTime();
         gameUpdate();
         gameRender();
         paintScreen();
         afterTime = System.nanoTime();
         difference = afterTime - beforeTime;
         if(difference < PERIOD) {
            sleepTime = PERIOD - difference;
            try {
               game.sleep(sleepTime / 1000000);
            } catch (InterruptedException e) {}
            System.out.printf("%d.%03d ms\n", difference / 1000000, difference % 1000000 / 1000);
         } else {
            System.out.printf("LAG! %d.%03d ms\n", difference / 1000000, difference % 1000000 / 1000);
         }
         
      }
   }
   private void gameUpdate() {
      if(running || game != null) {
         // TODO Update game board.
      }
   }
   private void gameRender() {
      if(bufferImage == null) {
         // Create the buffer.
         bufferImage = createImage(800, 600);
         if(bufferImage == null) {
            System.out.println("ERROR: Buffer image still does not exist!");
            return;
         } else {
            bufferGraphics = bufferImage.getGraphics();
         }
      }
      // Clear the screen.
      bufferGraphics.setColor(Color.WHITE);
      bufferGraphics.fillRect(0, 0, 800, 600);
      draw(bufferGraphics);
   }
   public void draw(Graphics g) {
      drawTile(g);
   }
   public void paintScreen() {
      Graphics g;
      try {
         g = this.getGraphics();
         if(bufferImage != null && g != null) {
            g.drawImage(bufferImage, 0, 0, null);
         }
         Toolkit.getDefaultToolkit().sync();
         g.dispose();
      } catch(Exception e) {}
   }
   
   private void loadTileImage() {
      TILE_0 = new ImageIcon("tile0.png").getImage();
      TILE_0_TOP = new ImageIcon("tile0top.png").getImage();
      TILE_A = new ImageIcon("tileA.png").getImage();
      TILE_A_TOP = new ImageIcon("tileAtop.png").getImage();
      TILE_B = new ImageIcon("tileB.png").getImage();
      TILE_B_TOP = new ImageIcon("tileBtop.png").getImage();
   }
   private void drawTileImage(int i, int j, int k, Graphics g) {
      if(tileGrid.getTileID(i, j, k) == 0)
         g.drawImage(TILE_0, toX(i, j), toY(i, j, k), null);
      else if(tileGrid.getTileID(i, j, k) == 1)
         g.drawImage(TILE_A, toX(i, j), toY(i, j, k), null);
      else if(tileGrid.getTileID(i, j, k) == 2)
         g.drawImage(TILE_B, toX(i, j), toY(i, j, k), null);
   }
   private void drawTileTopImage(int i, int j, int k, Graphics g) {
      if(tileGrid.getTileID(i, j, k) == 0)
         g.drawImage(TILE_0_TOP, toX(i, j), toY(i, j, k), null);
      else if(tileGrid.getTileID(i, j, k) == 1)
         g.drawImage(TILE_A_TOP, toX(i, j), toY(i, j, k), null);
      else if(tileGrid.getTileID(i, j, k) == 2)
         g.drawImage(TILE_B_TOP, toX(i, j), toY(i, j, k), null);
   }
   private void drawTile(Graphics g) {
      for(int i = 0; i < tileGrid.getU(); i++) {
         for(int j = 0; j < tileGrid.getV(); j++) {
            drawTileImage(i, j, wIndex - 1, g);
            drawTileImage(i, j, wIndex, g);
            drawTileTopImage(i, j, wIndex + 1, g);
         }
      }
   }
   private int toX(int i, int j) {
      return((getWidth() / 2 - SCALE) - SCALE * (i + uIndex) + SCALE * (j + vIndex));
   }
   private int toY(int i, int j, int k) {
      return((getHeight() / 2 - SCALE * tileGrid.getV() / 2) + SCALE * (i + uIndex + j + vIndex) / 2 - SCALE * (k - wIndex));
   }
}


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  
public class GameTile {
   private static int u;
   private static int v;
   private static int w;
   private static int[][][] tileGrid;
   public GameTile(int size) {
      if(size == 0)
         size = 1;
      u = (64 * size);
      v = (64 * size);
      w = (64 * size);
      tileGrid = new int[u][v][w];
      generateTileGrid();
   }
   private void generateTileGrid() {
      int test;
      for(int i = 0; i < u; i++) {
         for(int j = 0; j < v; j++) {
            for(int k = 0; k < w; k++) {
               test = ((i + j + k) % 4);
               if(test == 0)
                  tileGrid[i][j][k] = 1;
               else if(test == 1)
                  tileGrid[i][j][k] = 2;
               else
                  tileGrid[i][j][k] = 0;
            }
         }
      }
   }
   public void setTileID(int i, int j, int k, int tileID) {
      tileGrid[i][j][k] = tileID;
   }
   public int getU() {
      return u;
   }
   public int getV() {
      return v;
   }
   public int getW() {
      return w;
   }
   public int getTileID(int i, int j, int k) {
      return tileGrid[i][j][k];
   }
   public int[][][] getTileGrid() {
      return tileGrid;
   }
}
Pages: [1]
 

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

The first screenshot will be displayed as a thumbnail.

Longarmx (50 views)
2014-10-17 03:59:02

Norakomi (39 views)
2014-10-16 15:22:06

Norakomi (31 views)
2014-10-16 15:20:20

lcass (35 views)
2014-10-15 16:18:58

TehJavaDev (66 views)
2014-10-14 00:39:48

TehJavaDev (65 views)
2014-10-14 00:35:47

TehJavaDev (55 views)
2014-10-14 00:32:37

BurntPizza (72 views)
2014-10-11 23:24:42

BurntPizza (43 views)
2014-10-11 23:10:45

BurntPizza (84 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
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!