# Sprite library in a game

**URL:** <https://discourse.processing.org/t/sprite-library-in-a-game/12516>\
**Category:** Libraries\
**Created:** [July 5, 2019, 7:03am UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516 "2019-07-05T07:03:34Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Glowtube](https://avatars.discourse-cdn.com/v4/letter/g/e9bcb4/32.png) [@Glowtube](https://discourse.processing.org/u/Glowtube)\
**Post date:** [July 5, 2019, 7:03am UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/1 "2019-07-05T07:03:34Z")

</div>

Hello.  
I am currently working on a “little” game which will look something like Civ. First I drew all hexagons by myself but I found some nice sprites so I wanted to use the sprite library. But somehow it is unplayable with 5 fps. Are there some parts where I could have made a mistake that is crushing the performance? I did not wrote code because it is quite long and most of it may be useless for the problem. If there are parts I will send the code.

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [July 5, 2019, 7:50am UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/2 "2019-07-05T07:50:50Z")

</div>

The Sprite library has been arround a long time and no one else has reported a similar problem. It is impossible to say what the problem is wihout seeing some code.

One common issue is loading graphics in the draw() method, all graphics should be loaded in setup()

---

<div class="post-metadata">

**Author:** ![Glowtube](https://avatars.discourse-cdn.com/v4/letter/g/e9bcb4/32.png) [@Glowtube](https://discourse.processing.org/u/Glowtube)\
**Post date:** [July 5, 2019, 7:56am UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/3 "2019-07-05T07:56:02Z")

</div>

I am loading the Sprites here. The method is called in setup:

```auto
void setBiome(Dot d) {
        String terrain = "";
        boolean toElevate = true;
        
        if ( d.altitude >= 90 ) {
            terrain = "mountain";
            toElevate = false;
        } else if ( d.altitude <= 20 ) {
            terrain = "ocean";
            toElevate = false;
        } else if ( d.altitude <= 25 ) {
            terrain = "coast";
            toElevate = false;
        } else if ( d.altitude <= 30 ) {
            terrain = "desertdunes";
            toElevate = false;
        } else {
            if ( d.heat > 80 ) {
                if ( d.moisture < 20 ) {
                    if ( d.altitude > 85 ) {
                    terrain = "desertmountain";
                    toElevate = false;
                }
                    terrain = "desert";
                } else if ( d.moisture < 40 ) {
                    terrain = "savannah";
                    toElevate = false;
                } else if ( d.moisture < 70 ) {
                    terrain = "grassland";
                    toElevate = false;
                } else {
                    terrain = "rainforest";
                    toElevate = false;
                }
            } else if ( d.heat > 50 ) {
                if ( d.moisture < 20 ) {
                    terrain = "grassland";
                    toElevate = false;
                } else if ( d.moisture < 50 ) {
                    terrain = "plain";
                } else if ( d.moisture < 70 ) {
                    terrain = "plaintrees";
                } else {
                    switch ((int) random(3)) {
                        case 0: terrain = "swamp"; break;
                        case 1: terrain = "swamp2"; break;
                        case 2: terrain = "swampwater"; break;
                    }
                    toElevate = false;
                }
            } else if ( d.heat > 20 ) {
                if ( d.moisture < 30 ) {
                    terrain = "grassland";
                    toElevate = false;
                } else if ( d.moisture < 50 ) {
                    terrain = "plain";
                } else if ( d.moisture < 80 ) {
                    terrain = "plaintrees";
                } else {
                    switch ((int) random(3)) {
                        case 0: terrain = "swamp"; break;
                        case 1: terrain = "swamp2"; break;
                        case 2: terrain = "swampwater"; break;
                    }
                    toElevate = false;
                }
            } else {
                if ( d.moisture < 30 ) {
                    terrain = "snow";
                } else if ( d.moisture < 50 ) {
                    terrain = "snowtrees";
                    toElevate = false;
                } else if ( d.moisture < 80 ) {
                    terrain = "snowforest";
                } else {
                    terrain = "snow";
                    toElevate = false;
                }
            }
            
            if ( toElevate) {
                if ( d.altitude > 70 ) {
                    terrain += "hills";
                }
            }
        }
        
        terrain += ".png";
        hexagon = new Sprite(app, terrain, 10);
        hexagon.setXY(start + x * 24, start + ((x + 2) % 2) * 14 + y * 28);
        hexagon.setZorder(z);
    }

```

And this is my draw:

```auto
void setup() {
    fullScreen(P2D);
    setupMap();
    double deltaTime = timer.getElapsedTime();
    S4P.updateSprites(deltaTime);
}

void draw() {
    drawMap();
}

void drawMap() {
    background(255);
    translate(-xOff, -yOff);
    S4P.drawSprites();
}

```

---

<div class="post-metadata">

**Author:** ![Glowtube](https://avatars.discourse-cdn.com/v4/letter/g/e9bcb4/32.png) [@Glowtube](https://discourse.processing.org/u/Glowtube)\
**Post date:** [July 5, 2019, 7:58am UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/4 "2019-07-05T07:58:10Z")

</div>

I have a 200 \* 200 map of hexagons if it helps. But not every hexagon is in the screen.

---

<div class="post-metadata">

**Author:** ![Glowtube](https://avatars.discourse-cdn.com/v4/letter/g/e9bcb4/32.png) [@Glowtube](https://discourse.processing.org/u/Glowtube)\
**Post date:** [July 5, 2019, 9:36am UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/5 "2019-07-05T09:36:25Z")

</div>

I tried switching S4P.drawSprites(); to looping trough an ArrayList and drawing each Sprite if it is on the screen. The fps go up but the screen does not update or scale.

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [July 5, 2019, 4:23pm UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/6 "2019-07-05T16:23:19Z")

</div>

40,000 sprites might be doing it. Does the background have to be done as sprites?

---

<div class="post-metadata">

**Author:** ![InferNova](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/infernova/32/6009_2.png) [@InferNova](https://discourse.processing.org/u/InferNova)\
**Post date:** [July 5, 2019, 5:43pm UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/7 "2019-07-05T17:43:52Z")

</div>

Hey There!

You shouldn’t be using S4P.drawSprites !

You should only draw to he sprites that are in the boundary of the screen ! Because it is alot to render ! Also use P2D.

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [July 6, 2019, 12:32am UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/8 "2019-07-06T00:32:34Z")

</div>

> [@InferNova](#):
>
> You shouldn’t be using S4P.drawSprites !

can you help us out with a little argumentation WHY NOT?

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [July 6, 2019, 9:13am UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/9 "2019-07-06T09:13:25Z")

</div>

I suspect the problem is drawing the terrain of 40000 hexagons. If you think about it the hexagons have zero velocity and never move relative to each other you only need to recreate the background when you pan or zoom.

So here is my suggestions change the statement  
`hexagon = new Sprite(app, terrain, 10);`  
to  
`hexagon = new Sprite(app, terrain, 10, false);`

This will prevent the terrain hexagon sprite from being updated or drawn with  
`S4P.updateSprites(deltaTime);`  
and  
`S4P.drawSprites();`  
so you can manage these sprites yourself and S4P manages the moving sprites that appear on top.

---

<div class="post-metadata">

**Author:** ![InferNova](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/infernova/32/6009_2.png) [@InferNova](https://discourse.processing.org/u/InferNova)\
**Post date:** [July 6, 2019, 11:40am UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/10 "2019-07-06T11:40:21Z")

</div>

As stated above from @quark. It is so you canange their drawing yourself. I believe S4P  
Draw sprites draws all registered sprites with his amount that can be faxing but if he only draws the ones in the boundary of the screen with controlling the sprites with draw(). He wouldn’t face such low perfomance.

---

<div class="post-metadata">

**Author:** ![Glowtube](https://avatars.discourse-cdn.com/v4/letter/g/e9bcb4/32.png) [@Glowtube](https://discourse.processing.org/u/Glowtube)\
**Post date:** [July 7, 2019, 9:20am UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/11 "2019-07-07T09:20:53Z")

</div>

Thank you very much. Then I didnt understand the method right because I thought that it only renders the sprites that are on screen. But thats great, because the library is very helpful. I will try

---

<div class="post-metadata">

**Author:** ![Glowtube](https://avatars.discourse-cdn.com/v4/letter/g/e9bcb4/32.png) [@Glowtube](https://discourse.processing.org/u/Glowtube)\
**Post date:** [July 8, 2019, 1:10pm UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/12 "2019-07-08T13:10:26Z")

</div>

I changed my code so that i deregister every sprite except those which are on the screen. Now I have ~400 but I keep going down to 5 fps. I also thought about processing the background to one image after generation but it has to be updated every turn so it would be quite taxing. Will it help to draw the sprites with the draw() method inside them? Or are 400 sprites still too much? Thank you in advance

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [July 8, 2019, 1:33pm UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/13 "2019-07-08T13:33:42Z")

</div>

I suggested that you _did not register_ the hexagonal terrain Sprites when they were created, see my last post. Only register the game sprites e.g. tanks, bullets, players etc. because they move and there appearance changes.

You need to come up with something different with the background. You might try a PGrapics buffer, to store the background and copy this to the screen every frame. You then only update the buffer image if the background appearance changes.

400 hundred sprites is not a lot unless they are very large.

---

<div class="post-metadata">

**Author:** ![InferNova](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/infernova/32/6009_2.png) [@InferNova](https://discourse.processing.org/u/InferNova)\
**Post date:** [July 8, 2019, 4:45pm UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/14 "2019-07-08T16:45:37Z")

</div>

400 isn’t that much maybe your rendering method is messy ?

Have a look at my repo here [for a little project I was working on.](https://github.com/MarcinKrzykowski/HiScapes)

If you look at the **reworkGrid** class. I check and update what sprites are currently being featured on screen by:

```auto
public void update(int x, int y) {
    cellX = x/TILESIZE;
    cellXLong = (x/TILESIZE)+(width/TILESIZE)+TILEPUSH;
    cellY = y/TILESIZE;
    cellYLong=(y/TILESIZE)+(height/TILESIZE)+TILEPUSH;
  }
  public void show() {
    //Render only the most important tiles  
    for (int j = cellY; j<cellYLong; j++ ) {
      for (int i = cellX; i<cellXLong; i++) {
        if (j<buildWorld.length&&i<buildWorld.length&&j>=0&&i>=0)buildWorld[j][i].draw();
      }
    }

```

This is very quick because we don’t scroll through all tiles to calculate the range but just by simple mapping which saves from scrolling through the whole array to check which are on screen and which aren’t.

---

<div class="post-metadata">

**Author:** ![Glowtube](https://avatars.discourse-cdn.com/v4/letter/g/e9bcb4/32.png) [@Glowtube](https://discourse.processing.org/u/Glowtube)\
**Post date:** [July 9, 2019, 3:45pm UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/15 "2019-07-09T15:45:38Z")

</div>

As an update: I now handle the drawing of sprites by myself and draw them only if they are on screen. With a scale of 1 it works fine with 400 - 2000 sprites (only tested with 2000 but I think I could go higher) but when I set the scale something is messing with the fps. Im currently debugging to see where the problem is. If someone is interested in some code I will sent it. Maybe the game will be finished soon 🙂 Thank you for your help

---

<div class="post-metadata">

**Author:** ![InferNova](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/infernova/32/6009_2.png) [@InferNova](https://discourse.processing.org/u/InferNova)\
**Post date:** [July 9, 2019, 5:03pm UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/16 "2019-07-09T17:03:53Z")

</div>

If you are downscaling them aka more are on screen it gonna happen that the FPS drops. But if you just are upscaling them the FPS should increase.

---

<div class="post-metadata">

**Author:** ![Glowtube](https://avatars.discourse-cdn.com/v4/letter/g/e9bcb4/32.png) [@Glowtube](https://discourse.processing.org/u/Glowtube)\
**Post date:** [July 9, 2019, 5:41pm UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/17 "2019-07-09T17:41:01Z")

</div>

Yes I thought that too but even if I upscale the fps go down to 5. Im trying to put the drawing of the sprites inside a Thread. Maybe it helps.

---

<div class="post-metadata">

**Author:** ![InferNova](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/infernova/32/6009_2.png) [@InferNova](https://discourse.processing.org/u/InferNova)\
**Post date:** [July 9, 2019, 6:51pm UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/18 "2019-07-09T18:51:22Z")

</div>

Showing further code is going to allow us to fully understand what going on !

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [July 9, 2019, 6:52pm UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/19 "2019-07-09T18:52:11Z")

</div>

You cannot put drawing commands in a separate thread since all drawing must be done in the main Thread.

---

<div class="post-metadata">

**Author:** ![Glowtube](https://avatars.discourse-cdn.com/v4/letter/g/e9bcb4/32.png) [@Glowtube](https://discourse.processing.org/u/Glowtube)\
**Post date:** [July 9, 2019, 8:26pm UTC](https://discourse.processing.org/t/sprite-library-in-a-game/12516/20 "2019-07-09T20:26:46Z")

</div>

Hexagon is the sprite.  
Those are the methods responsible for drawing

```auto

void draw() {
    switch (currentScreen) {
        case "MapTest": 
            // scale(scale); 
            translate(-xOff, -yOff); 
            checkForCameraMovement(); break;
    }
}

// Drawing Tiles in order of their z value
void drawTiles() {
    for(int y = 0; y < size; y++) {
        ArrayList<Tile> temp = new ArrayList<Tile>();
        for(int x = 0; x < size; x++) {
            int z = (x+2) % 2;
            Tile current = mapGrid[x][y];
            if (z == 1) {
                temp.add(current);
            } else {
                current.drawIfOnScreen();
            }
        }
        for (Tile t : temp) {
            t.drawIfOnScreen();
        }
    }
}

 void drawIfOnScreen() {
        if (isOnScreen()) {
            hexagon.draw();
        }
    }
    
    boolean isOnScreen() {
        boolean b = (x * w > xOff - 50) && (x * w < xOff + width/scale + 50) && (y * h > yOff - 50) && (y * h < yOff + height/scale + 50);
        return b;
    }

```

[Next page](https://discourse.processing.org/t/sprite-library-in-a-game/12516.md?page=2)
