3
\$\begingroup\$

I have encountered a problem during my first game development: I thought of a Array<Ground> groundArray that does groundArray.add when a new ground will appear on the screen, and removes oldest ground when it will no longer be seen, if player only moves to the right, like in flappy bird.

enter image description here

The perfect structure would be a queue for such a mechanic, but libgdx doesnt have one. Using libgdx's Array is not intuitive too - i have to reverse the order of elements. It has a method pop() that removes the last element, but no such method to use on the first element.

What are my options here?

  • extend Array class and add something?
  • writing my own queue-like class?

UPDATE 18/8/2014

i actually found a way to do it with the default Array:

private void checkGround() {
    for (Ground ground : groundArray){
        if (ground.x  + 500 < camera.position.x){
            groundArray.removeValue(ground, true);
        }
    }

    if (groundArray.peek().x < camera.position.x + 500){
        groundArray.add(new Ground(groundX, -150));
        groundX +=50; //my ground texture is 50 pixels wide
    }
}

Only question left now - will it affect performance when there will be 10000 empty elements before the 10 actual ground elements? In my render method i use:

for (Ground ground : groundArray){
        batch.draw(ground.getTextureRegion(), ground.x, ground.y);
    }

If yes - i will have to make a re-sort method that shifts all the grounds to the beginning of the array.

Will doing so improve this?:

for (Ground ground : groundArray){
        if (ground != null) {
            batch.draw(ground.getTextureRegion(), ground.x, ground.y);
        }
    }

After checking apparently the array size doesnt boost , it size is always equals the number of actual ground objects in it, but i thought that it will count also the null values that were ground objects before. But then surely there would be nullpointers when i tried to draw those null's, so the problem looks fully resolved.

\$\endgroup\$
  • 1
    \$\begingroup\$ These notes explain how to implement a queue from an array. A linked list would work here too, as adding or removing from its ends is a cheap operation. \$\endgroup\$ – Anko Aug 18 '14 at 12:45
  • \$\begingroup\$ Use a doubly linked list like Anko suggests if available, it is fine for a small number of elements. \$\endgroup\$ – wolfdawn Aug 18 '14 at 15:58
1
\$\begingroup\$

Use Array (or regular java [] array!) (Ground[] grounds = initialize all;) with index that points to the first visible Ground in that array (int first = 0;). Keep some counter (float x = 0;) which will hold progress to the next index.

void update(float delta) {
  x += delta * speed;
  if(x > groundWidth){
    x -= groundWidth;
    grounds[first].generateNew();
    first = (first + 1) % grounds.length;
  }
}

void render(){
  float renderX = -x;
  int tile = first;
  for(int i = 0; i < grounds.length; i++){ //Code in this loop just needs to be called grounds.length times
    grounds[tile].renderAtX(renderX);
    tile = (tile + 1) % grounds.length;
    renderX += groundWidth;
  }
}

Something like that.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.