Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (494)
Games in Android Showcase (114)
games submitted by our members
Games in WIP (563)
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  
  Game structure and design  (Read 608 times)
0 Members and 1 Guest are viewing this topic.
Offline jakethesnake

Junior Newbie





« Posted 2014-08-03 05:39:56 »

Hello!

Firstly, I'm making a game using slick. I'm going for a top down strategy/rpg style, kind of like "dungeon keeper". I have two questions.

1. I'm trying to organize it and give it a good design. In the main class (which is a state) i have update() and render() method and I have references to all Images and objects which I'm using. Right now I'm working on the map, which is an array of tiles, 16*16 pixels big. The update method updates the tiles that are on screen and the render fills them on the screen. However, to get a good design, I'd like for the update and rendering of the map take place in the map class itself, so that my core only has:

update(){
map.update();
//update map, minimap, gamepanel, etc.

}

render(){
map.render();
//etc.

}

So that it is clean, just acting as a spider in the wed.

But when I implement this I get funny results. I suspect that it has to do with threading. My core is runnable, but my map class isn't. It doesn't implement or extend anything.


2. I'm also worried about my FPS. With an empty screen I get 5000FPS. When I fill my screen with my 1000 tiles I get 1000FPS. I'm then going to put in tons more logic, loops animations, objects, effects and so forth, will it be enough, or shall I have to abandon the large-scale tilesystem?
Offline SHC
« Reply #1 - Posted 2014-08-03 05:50:13 »

First, try to use the code tags for any code you post in the forum for example,



renders as

1  
2  
3  
4  
public void foo()
{
    System.out.println("bar");
}

And second, never worry about your FPS, 1000 FPS is very huge that is not at all necessary. You can't really notice any difference between a scene with 1000 fps and the same scene with 120 fps. Monitors do limit the fps to their refresh rate.

Offline BurntPizza
« Reply #2 - Posted 2014-08-03 05:56:17 »

So you went from 0.2 milliseconds to 1 millisecond per frame, you still have over 15 left to make 60 FPS, which is enough.

For 2D games, as long as you aren't either 1) going massive scale (i.e. 1000s of things on screen at any time) or 2) doing very dumb things (i.e. loading from file every frame), you'll be fine.

Rules of optimization state that you should not worry about performance until you need to. As long as it plays at 60+ FPS, don't bother.
In fact you should limit framerate to a maximum of 60, as most everyone's monitor can't refresh any faster than that anyway.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline jakethesnake

Junior Newbie





« Reply #3 - Posted 2014-08-03 06:08:14 »

Thanks!

I am aiming for and going to limit to 60-50 FPS in the end. I'm just worried since drawing the map ate up 2000FPS, and I'm going to add so many more things to the game - objects entities, etc.

But anyway. How do you guys manage to get a clean core class? Do you have render methods in other classes, like in a map class or an object class?

I'll post some code.

This is my current render method in my core class. It's working fine.

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  
public void render(GameContainer gc, StateBasedGame sbg, Graphics g)
         throws SlickException {
      //draw tiles  
     int type = 0;
      int firstTileX = upperLeftScreenX /Global.TILESIZE;
      int firstTileY = upperLeftScreenY /Global.TILESIZE;
      int firstX = - (upperLeftScreenX & 0x0F);
      int firstY = - (upperLeftScreenY & 0x0f);
      for (int height = 0; height <= tilesOnScreenY/zoom+1; height++){
         for (int width = 0; width <= tilesOnScreenX/zoom+1; width++){
            type = map.getType(firstTileX+width, firstTileY+height);
            switch (type){
            case 1: im.draw(firstX*zoom+width*Global.TILESIZE*zoom,
                  firstY*zoom +height*Global.TILESIZE*zoom,
                  zoom);
            break;
            case 2: //much more coming
           break;
            default: im.draw(50, 50, zoom);
            }

         }
      }      

   }


however, I'd like this:

1  
2  
3  
4  
public void render(GameContainer gc, StateBasedGame sbg, Graphics g)
         throws SlickException {
      map.draw(gc,sbg,g,);
   }


and the in the map class:

1  
2  
3  
4  
5  
6  
7  
8  
   void draw (GameContainer gc, StateBasedGame sbg, Graphics g){
      for (int height = 0; height <= tilesToUpdateX; height++){
         for (int width = 0; width <= tilesToUpdateY; width++){
            im.draw(getX(), getY());
         }

      }
   }


It works, but there is flickering sometimes. Like if it's jumping in and out of the method. I've tried synchronized, but it doesn't help.
Offline trollwarrior1
« Reply #4 - Posted 2014-08-03 06:57:37 »

Try drawing a single tile on the whole screen. It will take 2000fps also (a little bit less). Its not the amount of tiles you are drawing, it the amount of screen you are filling.
Offline jakethesnake

Junior Newbie





« Reply #5 - Posted 2014-08-03 08:41:03 »

I figured it out!

For what i suspect to be threading reasons, the update method in my map-class is sometimes called while I'm in the draw-method. Therefore I needed to create temp variables in my draw-method, point them to my update-variables and then work with them.

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  
package play;

import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

public class SettlementMap {
   
   private Image im;
   
   private Tile tiles[][];
   //for drawing
  private int firstTileX;
   private int firstTileY;
   private int firstX;
   private int firstY;
   private int tilesToUpdateX;
   private int tilesToUpdateY;
   private float zoom;
   private int tileSize;
   private int renderJump;
   private int tilesToRender;
   private int xCount;
   private int yCount;
   private int maxWidth = 800;
   private int maxHeight = 400;

   public SettlementMap () throws SlickException{
     
      im = new Image("res/menu/path.png", false, Image.FILTER_NEAREST);
      tileSize = Global.TILESIZE;
      tilesToUpdateX = 0;
      tilesToUpdateY = 0;
      firstTileX = 0;
      firstTileY = 0;
      tiles = new Tile[Global.MAPSIZE][Global.MAPSIZE];
      for (int height = 0; height < Global.MAPSIZE; height++){
         for (int width = 0; width < Global.MAPSIZE; width++){
            tiles[height][width] = new Tile (1);
            }
         }
      tiles[5][0].setType(2);
      tiles[10][0].setType(2);
      tiles[50][50].setType(2);
      tiles[75][75].setType(2);
      tiles[100][100].setType(2);
   }
   
   int getType (int width, int height){
      return tiles[height][width].getType();
   }
   
   void update (int upperLeftScreenX, int upperLeftScreenY, float zoom) {
      xCount = 0;
      yCount = 0;
      this.zoom= zoom;
      firstTileX = upperLeftScreenX/tileSize;
      firstTileY = upperLeftScreenY/tileSize;
      firstX = (int) (- (upperLeftScreenX & 0x0F)*zoom);
      firstY = (int) (- (upperLeftScreenY & 0x0f)*zoom);
      renderJump = (int) (tileSize*zoom);
      for (int height = 0; height <= tilesToUpdateY; height++){
         for (int width = 0; width <= tilesToUpdateX; width++){
            tiles[height][width].update();
         }
      }
   }
   
   int getX (){
      return firstX + xCount*renderJump;
   }
   
   int getY (){
      return firstY + yCount*renderJump;
   }
   
   void count (){
      xCount ++;
      if (xCount > tilesToUpdateX){
         xCount = 0;
         yCount ++;
      }
   }
   
   int getTilesToRender(float zoom){
      return tilesToRender;
   }
   
   void draw (Graphics g){
      int tempX;
      int tempY = firstTileY;
      int tempTile;
      for (int y = firstY; y <= maxHeight; y = y + renderJump){
         tempX = firstTileX;
         for (int x = firstX; x <= maxWidth; x = x + renderJump){
            tempTile = tiles[tempY][tempX].getType();
            switch (tempTile){
               case 1: im.draw(x, y,zoom);
            break;
               case 2:
            break;
            default:
            }
            tempX++;
         }
         tempY++;
      }

      g.drawString("tilesToUpdateX =" + tilesToUpdateX, 200, 100);
      g.drawString("tilesToUpdateY =" + tilesToUpdateY, 200, 200);
      g.drawString("tilesToRender =" + tilesToRender, 200, 300);
   }
   
   
}
 

p.s. Do you think it's wise to use the switch-statement when choosing which image to draw. I'm planning on making many, many tiles, perhaps 200 of them (gonna use spritesheet). I've read somewhere about some kind of ID-thing. Should I look it to that?
Offline BurntPizza
« Reply #6 - Posted 2014-08-03 15:43:43 »

Tile drawing is where you'd use the flyweight pattern: each Tile has a either a reference Image tileImage; or an index int textureIndex; which points to a certain image in a master list of images, known as a spritesheet if it's one large image that you draw sections of.
Note that the image reference is shared, so all tiles with the same image point to the same image object, you don't want to allocate 200 identical images when you can just share the reference. That is the flyweight pattern.

Google some of those words to find out more.

It becomes something like this:

1  
2  
3  
4  
5  
6  
7  
void draw (Graphics g){
    <snip>
         for (int x = firstX; x <= maxWidth; x = x + renderJump){
            tileImage = tiles[tempY][tempX].getImage();
            tileImage.draw(...);
    <snip>
}


That said, I don't know enough about Slick to point you in the "best" direction on how to draw textures.

I am aiming for and going to limit to 60-50 FPS in the end. I'm just worried since drawing the map ate up 2000FPS, and I'm going to add so many more things to the game - objects entities, etc.

Don't think about it in FPS, think about it in time: 5000 FPS to 1000 FPS may be a "drop" of 4000 FPS, but it's only a difference of 0.8 ms. A drop of 40 FPS from 100 to 60 is a loss of 6.667 ms, which is actually 8.333 times more time lost, despite the FPS drop being 100x less.
You have a 16.6667 millisecond "budget" for each frame, drawing your 1000 (!) tiles uses only 4.8% of that budget, even if you lost 4000 FPS.
Pages: [1]
  ignore  |  Print  
 
 

 

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

The first screenshot will be displayed as a thumbnail.

Dwinin (22 views)
2014-09-12 09:08:26

Norakomi (55 views)
2014-09-10 13:57:51

TehJavaDev (67 views)
2014-09-10 06:39:09

Tekkerue (33 views)
2014-09-09 02:24:56

mitcheeb (55 views)
2014-09-08 06:06:29

BurntPizza (38 views)
2014-09-07 01:13:42

Longarmx (24 views)
2014-09-07 01:12:14

Longarmx (30 views)
2014-09-07 01:11:22

Longarmx (30 views)
2014-09-07 01:10:19

mitcheeb (37 views)
2014-09-04 23:08:59
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

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!