Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (475)
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  
  Camera class in top view  (Read 2130 times)
0 Members and 1 Guest are viewing this topic.
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Posted 2010-09-10 21:28:30 »

I'm developing a top-down-view RPG-something game... Like Zelda  persecutioncomplex
I'm having my screen set to some absolute size (400x400 i think), and my "rooms" are the same size.
Each room is a map, but I dont want it excactly that way.

I see alot of you use a camera class to do this:
Scroll the screen with the camera, so I can make my rooms greater than just the frame..

Question is: how?
Can anyone give a detailed explanation on how it works?  Shocked

Mads  Smiley

Offline dime

Senior Newbie





« Reply #1 - Posted 2010-09-10 23:06:55 »

I have a Camera class that basically:

Divides screenwidth /2 and subtracts the player position (minutes half of players sprite width) and move screen by that.
Same with height.

A concrete example.  If screen is 640 wide and player is at 300 and player is 32 pixels wide.
640/2 = 320 [screen width /2] - 300 [player [pos] = 20 - 16 [sprite width /2] =4

that means I shift the map over by 4 pixels.

Basically, whatever the player is, the camera is centered on him.  If he moves left 32 pixels, the camera follows him over 32 pixels.

Or another way to look at it, the player is always perfectly centered in middle of the screen and map moves under him.

I like this approach because it isn't dependent on resolution.  The higher the resolution just means the player sees more of the map.
Maps can be as big or small as you like.
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #2 - Posted 2010-09-10 23:17:47 »

What? Weird post.. Clicked the wrong button.

@Topic:
I might be slow, and it is late. Why do you divide by two?
I dont quite understand the drawing, and imput part of your example :L

How should I approach placing buildings in a such environment? A different coordinate system?
^How?  Shocked

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

Senior Newbie





« Reply #3 - Posted 2010-09-10 23:56:24 »

> I might be slow, and it is late. Why do you divide by two?

To get the center point.

If you have a piece of paper that is 10 inches wide, if you fold it in half (that is divide by 2) you get the center point of paper.
Same with screen width, but measured in pixels.

Also depends on how you draw sprites.  When I draw them at x and y it draws 0,0 of the sprites at that location.
If that is the case, you have to divide your sprite image by 2 to get center of image.  If not, your sprite won't be true center, it'll be off by a bit.

What coordinate system are you using?  Either pixels or tiles (like a tiled map) will work with this.
Not sure what other type of cord system you'd be using other than one of those?
Offline Swattkidd7

Junior Member





« Reply #4 - Posted 2010-09-11 07:21:30 »

This should help you out
http://www.javacooperation.gmxhome.de/ScrollingEng.html
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #5 - Posted 2010-09-11 12:17:39 »

@Dime
Thanks, I got the idea of centering my character now. I'm using a pixel map.
Before I just used the java graphics coords to define where my entities in game were, but I cant do that now.
That leads to the question - how do I approach placing my entities now?

@Swattkidd
Thank you very much, I found it very useful.

I'm still not sure how to define positions for in-game-objects, since I can't use the graphics coordinates for that anymore  Undecided

Offline h3ckboy

JGO Coder


Medals: 5



« Reply #6 - Posted 2010-09-11 12:41:11 »

nothing changes, you still place it all the same.

you character is still at 700 700 or whatever, but everything is moved.

so basically all taht changes is how you paint stuff, and thats only by a little bit Smiley (if u do it right that is, hahah)
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #7 - Posted 2010-09-11 19:31:26 »

@H3ckboy
I don't know if it is as simple as that, unfortunately. All my logic (as of now) relies on the painting coordinates.
For instance, I have object teleporting my character to a different map. That activates once my character reaches the paint-coords of the teleport-object.
That makes me think of having a different coordinate system, that is not the painting coords  Undecided

Does that make any sence?  Tongue ...I don't like to realize it, but I might have built a semi-f**ked up engine  persecutioncomplex

Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11


Game Engineer


« Reply #8 - Posted 2010-09-11 20:00:42 »

You really don't need to get complicated.

I just have a scrollX and scrollY float, and when I draw the scene I draw every image at xPos+scrollX, yPos+scrollY. Or even simpler just translate your graphics context (in Graphics2D) or translate the transformation matrix (in OpenGL).

Then increment of decrement the scroll values based on where the player is, or even just scroll the screen to match how much the player moves, whenever they move.

The key thing to remember is that you're only drawing things different, the actual positions of each object should not be changed.

Really simple.

See my work:
OTC Software
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #9 - Posted 2010-09-12 10:42:09 »

I'm so annoyed at myself right now. I have tried, and tried, and tried to get this to work just with functionality for one direction. It doesn't work  Cry

I know I look so helpless when I ask, but can one of you please, please, provide just functionality for one direction? I'd be ever so grateful.
I just need to see this implemented simply  Undecided

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

Senior Newbie





« Reply #10 - Posted 2010-09-12 21:03:46 »

In my update():

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
   screenWidth = gc.getWidth();
      screenHeight = gc.getHeight();
     
           
      if (followPlayer) {
         playerTileOffsetX = player.getTileOffset().x;
         playerTileOffsetY = player.getTileOffset().y;
         playerX = screenWidth/2- player.getCordPosition().x-16 - playerTileOffsetX;
         playerY = screenHeight/2 - player.getCordPosition().y-16 - playerTileOffsetY;
      }


in render (I use slick)

1  
2  
3  
4  
5  
6  
   defaultBackground.draw(0,0, gc.getWidth(), gc.getHeight());
     
      // If we're following player
     if (followPlayer) {
         g.translate(playerX, playerY);
      }




PlayerTileOffsetXY doesn't matter.  It's just player offset in pixels from tiles.  This lets it "smooth scroll" 1 pixel at a time instead of jumping 32 (it gets jerky if you jump to many pixels to quick).

Translate just shifts to screen: http://slick.cokeandcode.com/javadoc/org/newdawn/slick/Graphics.html#translate%28float,%20float%29


Then on top of the above, I just draw player in center of screen.  Non translated.

Offline zoto

Senior Member


Medals: 4



« Reply #11 - Posted 2010-09-12 21:10:36 »

This page should be helpful http://fivedots.coe.psu.ac.th/~ad/jg/ Chapter 12 should answer any questions you have about 2d scrolling.
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #12 - Posted 2010-09-13 21:21:27 »

I decided to draw my character in the middle, and then draw all other object at the graphical point += Scroll.
Then I increase/decrease the scroll upon keypress.

Two problems rised: First of all, the centering of the character isn't working.
It looks like this:
1  
g2d.drawImage(craft.getImage(), Scroll.WIDTH_1/2-48/2, Scroll.HEIGHT_1/2-48/2, this);

Height_1 and width_1, are my frames variables. My character-sprite is 48 pixels high, and wide.
It draws like this:

Oh, yes.. I used a sprite from minecraft for the example...

The second problem is that the Scroll variable isn't changing correctly when the key is held down. There is a small delay, it goes like this upon keypress:
Change +1, delay, change that is constantly changing in the right direction.
What bothers me is the delay.
Here is my logic for that:
Board(canvas):
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
    public void actionPerformed(ActionEvent e) {
        craft.move();
        repaint();
    }


    private class TAdapter extends KeyAdapter {

        public void keyReleased(KeyEvent e) {
            craft.keyReleased(e);
        }

        public void keyPressed(KeyEvent e) {
            craft.keyPressed(e);
        }
    }


Craft (entity):
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  
public void keyPressed(KeyEvent e) {

        int key = e.getKeyCode();

        if (key == KeyEvent.VK_LEFT) {
            dx = -1;
            Board.ScrollX += -1;
        }

        if (key == KeyEvent.VK_RIGHT) {
            dx = 1;
            Board.ScrollX += 1;
        }

        if (key == KeyEvent.VK_UP) {
            dy = -1;
            Board.ScrollY += -1;
        }

        if (key == KeyEvent.VK_DOWN) {
            dy = 1;
            Board.ScrollY += 1;
        }
    }

    public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();

        if (key == KeyEvent.VK_LEFT) {
            dx = 0;
            //Board.ScrollX = 0;
       }

        if (key == KeyEvent.VK_RIGHT) {
            dx = 0;
            //Board.ScrollX = 0;
       }

        if (key == KeyEvent.VK_UP) {
            dy = 0;
            //Board.ScrollY = 0;
       }

        if (key == KeyEvent.VK_DOWN) {
            dy = 0;
            //Board.ScrollY = 0;
       }
    }
public void move() {
        x += dx;
        y += dy;
    }


What am I doing wrong?  Undecided

Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11


Game Engineer


« Reply #13 - Posted 2010-09-14 01:34:21 »

Probably your issue is that you're incrementing the scroll from within the key update, which means your scrolling is updating whenever the EDT is updating - the result is that it will look choppy and crap.

The solution is to store buttons that have been pressed in a list, then remove them from the list when they've been released. Factor all buttons pressed every update. This is good practice in general - you want absolutely everything that actually updates your entities to happen within the update function. Just like you don't draw anything outside of the draw function, don't update anything outside of the update function.

I made a quick scrolling demo for you. It's just my fixed timestep demo with some scrolling thrown on top. Press Start to have the ball bounce around, then scroll with the keyboard keys. The ball's position never changes from the scrolling - things are merely drawn offset from the scroll amount. If you're confused from the interpolation, that's just what to do to get an FPS higher than your game hertz.

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  
198  
199  
200  
201  
202  
203  
204  
205  
206  
207  
208  
209  
210  
211  
212  
213  
214  
215  
216  
217  
218  
219  
220  
221  
222  
223  
224  
225  
226  
227  
228  
229  
230  
231  
232  
233  
234  
235  
236  
237  
238  
239  
240  
241  
242  
243  
244  
245  
246  
247  
248  
249  
250  
251  
252  
253  
254  
255  
256  
257  
258  
259  
260  
261  
262  
263  
264  
265  
266  
267  
268  
269  
270  
271  
272  
273  
274  
275  
276  
277  
278  
279  
280  
281  
282  
283  
284  
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

public class ScrollTest extends JFrame implements ActionListener, KeyListener
{
   private GamePanel gamePanel = new GamePanel();
   private JButton startButton = new JButton("Start");
   private JButton quitButton = new JButton("Quit");
   private boolean running = false;
   private int fps = 60;
   private int frameCount = 0;
   
   private ArrayList<Integer> keysPressed;
   
   public ScrollTest()
   {
      super("Fixed Timestep Game Loop Test");
      Container cp = getContentPane();
      cp.setLayout(new BorderLayout());
      JPanel p = new JPanel();
      p.setLayout(new GridLayout(1,2));
      p.add(startButton);
      p.add(quitButton);
      cp.add(gamePanel, BorderLayout.CENTER);
      cp.add(p, BorderLayout.SOUTH);
      setSize(500, 500);
     
      keysPressed = new ArrayList<Integer>();
     
      startButton.addActionListener(this);
      quitButton.addActionListener(this);
      gamePanel.addKeyListener(this);
   }
   
   public static void main(String[] args)
   {
      ScrollTest st = new ScrollTest();
      st.setVisible(true);
   }
   
   public void actionPerformed(ActionEvent e)
   {
      Object s = e.getSource();
      if (s == startButton)
      {
         running = !running;
         if (running)
         {
            startButton.setText("Stop");
            runGameLoop();
         }
         else
         {
            startButton.setText("Start");
         }
      }
      else if (s == quitButton)
      {
         System.exit(0);
      }
   }
   
   public void keyPressed(KeyEvent e)
   {
      if (!keysPressed.contains(new Integer(e.getKeyCode())))
      {
         keysPressed.add(new Integer(e.getKeyCode()));
      }
   }
   public void keyReleased(KeyEvent e)
   {
      keysPressed.remove(new Integer(e.getKeyCode()));
   }
   public void keyTyped(KeyEvent e)
   {
      //Do nothing.
  }
   
   //Starts a new thread and runs the game loop in it.
  public void runGameLoop()
   {
      Thread loop = new Thread()
      {
         public void run()
         {
            gameLoop();
         }
      };
      loop.start();
   }
   
   //Only run this in another Thread!
  private void gameLoop()
   {
      //This value would probably be stored elsewhere.
     final double GAME_HERTZ = 30.0;
      //Calculate how many NS each frame should take for our target game hertz.
     final double TIME_BETWEEN_UPDATES = 1000000000 / GAME_HERTZ;
      //At the very most we will update the game this many times before a new render.
     final int MAX_UPDATES_BEFORE_RENDER = 5;
      //We will need the last update time.
     double lastUpdateTime = System.nanoTime();
      //Store the last time we rendered.
     double lastRenderTime = System.nanoTime();
     
      //If we are able to get as high as this FPS, don't render again.
     final double TARGET_FPS = 60;
      final double TARGET_TIME_BETWEEN_RENDERS = 1000000000 / TARGET_FPS;
     
      //Simple way of finding FPS.
     int lastSecondTime = (int) (lastUpdateTime / 1000000000);
     
      while (running)
      {
         double now = System.nanoTime();
         int updateCount = 0;
         
         //Do as many game updates as we need to, potentially playing catchup.
        while( now - lastUpdateTime > TIME_BETWEEN_UPDATES && updateCount < MAX_UPDATES_BEFORE_RENDER )
         {
            updateGame();
            lastUpdateTime += TIME_BETWEEN_UPDATES;
            updateCount++;
         }
         
         //If for some reason an update takes forever, we don't want to do an insane number of catchups.
        //If you were doing some sort of game that needed to keep EXACT time, you would get rid of this.
        if (lastUpdateTime - now > TIME_BETWEEN_UPDATES)
         {
            lastUpdateTime = now - TIME_BETWEEN_UPDATES;
         }
         
         //Render. To do so, we need to calculate interpolation for a smooth render.
        float interpolation = Math.min(1.0f, (float) ((now - lastUpdateTime) / TIME_BETWEEN_UPDATES) );
         drawGame(interpolation);
         lastRenderTime = now;
         
         //Update the frames we got.
        int thisSecond = (int) (lastUpdateTime / 1000000000);
         if (thisSecond > lastSecondTime)
         {
            fps = frameCount;
            frameCount = 0;
            lastSecondTime = thisSecond;
         }
         
         //Yield until it has been at least the target time between renders. This saves the CPU from hogging.
        while ( now - lastRenderTime < TARGET_TIME_BETWEEN_RENDERS && now - lastUpdateTime < TIME_BETWEEN_UPDATES)
         {
            Thread.yield();
            now = System.nanoTime();
         }
      }
   }
   
   private void updateGame()
   {
      gamePanel.factorKeyPresses(keysPressed);
      gamePanel.update();
   }
   
   private void drawGame(float interpolation)
   {
      gamePanel.setInterpolation(interpolation);
      gamePanel.repaint();
   }
   
   private class GamePanel extends JPanel
   {
      float interpolation;
      float ballX, ballY, lastBallX, lastBallY;
      int ballWidth, ballHeight;
      float ballXVel, ballYVel;
      float ballSpeed;
      float scrollX, scrollY, lastScrollX, lastScrollY;
     
      int lastDrawX, lastDrawY;
     
      public GamePanel()
      {
         ballX = lastBallX = 100;
         ballY = lastBallY = 100;
         ballWidth = 25;
         ballHeight = 25;
         ballSpeed = 25;
         ballXVel = (float) Math.random() * ballSpeed*2 - ballSpeed;
         ballYVel = (float) Math.random() * ballSpeed*2 - ballSpeed;
      }
     
      public void setInterpolation(float interp)
      {
         interpolation = interp;
      }
     
      public void update()
      {
         requestFocus();
         
         lastBallX = ballX;
         lastBallY = ballY;
         
         ballX += ballXVel;
         ballY += ballYVel;
         
         if (ballX + ballWidth/2 >= getWidth())
         {
            ballXVel *= -1;
            ballX = getWidth() - ballWidth/2;
            ballYVel = (float) Math.random() * ballSpeed*2 - ballSpeed;
         }
         else if (ballX - ballWidth/2 <= 0)
         {
            ballXVel *= -1;
            ballX = ballWidth/2;
         }
         
         if (ballY + ballHeight/2 >= getHeight())
         {
            ballYVel *= -1;
            ballY = getHeight() - ballHeight/2;
            ballXVel = (float) Math.random() * ballSpeed*2 - ballSpeed;
         }
         else if (ballY - ballHeight/2 <= 0)
         {
            ballYVel *= -1;
            ballY = ballHeight/2;
         }
      }
     
      public void paintComponent(Graphics g)
      {
         super.paintComponent(g);
         
         //Draw a box around the area so we can see scrolling.
        float thisXScroll = (scrollX - lastScrollX) * interpolation + lastScrollX;
         float thisYScroll = (scrollY - lastScrollY) * interpolation + lastScrollY;
         g.setColor(Color.BLACK);
         g.drawRect((int)scrollX, (int)scrollY, getWidth(), getHeight());
         
         //Draw the ball.
        g.setColor(Color.RED);
         int drawX = (int) ((ballX - lastBallX) * interpolation + lastBallX - ballWidth/2 + thisXScroll);
         int drawY = (int) ((ballY - lastBallY) * interpolation + lastBallY - ballHeight/2 + thisYScroll);
         g.fillOval(drawX, drawY, ballWidth, ballHeight);
         
         lastDrawX = drawX;
         lastDrawY = drawY;
         
         g.setColor(Color.BLACK);
         g.drawString("FPS: " + fps, 5, 10);
         
         frameCount++;
      }
     
      public void factorKeyPresses(ArrayList<Integer> presses)
      {
         lastScrollX = scrollX;
         lastScrollY = scrollY;
         for (int i = 0; i < presses.size(); i++)
         {
            int key = presses.get(i).intValue();
           
            if (key == KeyEvent.VK_LEFT)
            {
               scrollX -= 5;
            }
            else if (key == KeyEvent.VK_RIGHT)
            {
               scrollX += 5;
            }
            else if (key == KeyEvent.VK_UP)
            {
               scrollY -= 5;
            }
            else if (key == KeyEvent.VK_DOWN)
            {
               scrollY += 5;
            }
         }
      }
   }
}

See my work:
OTC Software
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 742
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #14 - Posted 2010-09-17 22:41:27 »

Probably your issue is that you're incrementing the scroll from within the key update, which means your scrolling is updating whenever the EDT is updating - the result is that it will look choppy and crap.

It's actually not the EDTs fault. This is (intended and well thought through) OS behavior, try it by holding a key down in a textarea.

The suggested fix works almost everywhere: Linux (or Sun's AWT for Linux) seems to forget some key-release events every now and then...

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

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #15 - Posted 2010-09-17 23:22:55 »

It's actually not the EDTs fault. This is (intended and well thought through) OS behavior, try it by holding a key down in a textarea.

The suggested fix works almost everywhere: Linux (or Sun's AWT for Linux) seems to forget some key-release events every now and then...

Actually, on a side note that is so true! I have the problem all the time. ..I was beginning to think my computers keyboard was broke or something..

@Thread: I decided to let this be for now. I learned some important things with this, and I figuered I'd scratch all the work I have done now.
I need a proper way of dealing with games, because my regular loop (holding a steady 100ms loop, and doing things in the breaks without causing delay) didn't seem to be enough. I need some more advanced timing..
I'll have a look at slick when I feel for developing something again  Tongue persecutioncomplex

Thanks for the imformative answers guys.

Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11


Game Engineer


« Reply #16 - Posted 2010-09-18 01:25:25 »

It's actually not the EDTs fault. This is (intended and well thought through) OS behavior, try it by holding a key down in a textarea.

The suggested fix works almost everywhere: Linux (or Sun's AWT for Linux) seems to forget some key-release events every now and then...
That's just wonderful. What do you do about these Linux people, then? Make press re-press keys to unstick them?

I guess it's a moot point because I always use JInput in my games, but still...

See my work:
OTC Software
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 (9 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 (49 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!