0
\$\begingroup\$

I'm working through a game in Slick2D and am now focusing on a lot of the graphical end. It's going pretty well other than a couple of issues with alignment. An image illustrating both of these issues here: enter image description here Firstly, the background. I have 2 Entity objects containing coordinates, velocity, and an image for the background. Both contain the same image (1600x600). For the first, x=0 and for the second, x=1600. They both move to the left at a speed of 1 pixel per frame. No matter if I make the offset smaller (like 1580), I am still left with a gap showing the background colour. I've put the two images together in photoshop and they blend together, so it's not an issue with the image. Here is some relevant code:

//in init block
Entity bg1 = new Entity("background",1600,600);
        bg1.setXVelocity(BACKGROUND_VELOCITY);
        Entity bg2 = new Entity("background",1600,600); //a second one is needed for endless background
        bg2.setXVelocity(BACKGROUND_VELOCITY);
        bg2.setX(1600);
        backgroundList = new ArrayList<Entity>();
        backgroundList.add(bg1);
        backgroundList.add(bg2);
...
//in update loop, running every frame
for (Entity bg : backgroundList){
    bg.update();
    if (bg.getX() < -1*bg.getSpriteWidth()){
        bg.setX(1600);
    }
}

In other words, what I expect my code to do is have both images move left one pixel each until the left image reaches -1600 (-1*bg.getSpriteWidth()), at which point the right image will be at 0, and with a width of 1600 the first image would be moved to 1600. This is, at least, how I expect my code to work. bg.update() calls a method which adjusts the position based on the velocity given, so it will move x backward by 1 each time for both backgrounds.

Secondly, the misaligned walls. As you can see in the image, the walls on the right are perfectly aligned. They move left together at the same velocity in the same way as above. For some reason, however, as the walls pass the mid-way mark (where the fish is), the upper wall's velocity slows for a slight second which misaligns it with the lower wall (though the velocity returns after and they stay that constant distance apart). I actually have found the code causing this (when commented out it stops), but I cannot see why it would do such a thing. The values still remain correct, but the graphical output is distorted.

for (int i = 0; i < wallList.size(); i++) {
    Wall wall = wallList.get(i);
    wall.update();
    if (wall.getX() < -1 * wall.getImageWidth()) {
        wallList.remove(i);
    }                       
}
...
if (wallList.get(wallList.size() - 1).getX() < WIDTH - DISTANCE_BETWEEN_WALLS) {
    createWalls();
}

...
private void createWalls() {
    Wall w1 = new Wall();
    Wall w2 = new Wall();
    int yPos = rand.nextInt(400) + 50 - w1.getImageHeight();
    w1.setLocation(WIDTH, yPos);
    w1.setXVelocity(WALL_VELOCITY);
    w1.setVisible(true);
    w2.setLocation(WIDTH, yPos + 11 * player.getImageHeight() / 3 + w2.getImageHeight());
    w2.setXVelocity(WALL_VELOCITY);
    w2.setVisible(true);
    wallList.add(w1);
    wallList.add(w2);
}

It's the wallList.remove(i); line that is causing this offset to happen. When I remove the line, the walls stay aligned as intended. Any ideas? Are these just imperfections of Slick2D? Perhaps there is a better way for me to do these things?

\$\endgroup\$
0
\$\begingroup\$
for (int i = 0; i < wallList.size(); i++) {
    Wall wall = wallList.get(i);
    wall.update();
    if (wall.getX() < -1 * wall.getImageWidth()) {
        wallList.remove(i);
    }                       
}

If you remove a wall then the next wall at index i but you skip it.

Decrement i after the remove or use an iterator based loop:

for (Iterator<Wall> i = wallList.iterator(); i.hasNext(); ) {
    Wall wall = i.next();
    wall.update();
    if (wall.getX() < -1 * wall.getImageWidth()) {
        i.remove();
    }                       
}
\$\endgroup\$
  • \$\begingroup\$ That was exactly what it was. Good eye! I figure out a better way to do the background that shouldn't cause conflict. So, my issue is resolved now. Though I don't seem to be privileged enough to mark it as such yet. \$\endgroup\$ – MattDs17 Jan 9 '15 at 18:30
  • \$\begingroup\$ Just remembered I shouldn't just say I resolved the issue without explanation. It makes more sense to have just a single image that, when its right edge reaches the right edge of the screen, resets to the position where its left edge is at the left edge of the screen (this means, of course, that the big image should have an identical 800px-wide section at the beginning and end) \$\endgroup\$ – MattDs17 Jan 9 '15 at 20:29

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.