Search code examples
javaswing2dspritetile

Incorrect sprite graphic is assigned to tiles


I'm now following a series of video tutorials on YouTube, to be specific a Game Programming tutorial by TheChernoProject. I got to episode 36, which is about rendering a level from tiles. I won't get into too much detail on that, but I encountered a strange problem that no one has encountered (at least no one asked for help with it).
To be more precise: I have a Sprite class, a Tile class (with two classes extending it: GrassTile and VoidTile) and a Level class. Level cosists of Tiles, which are made of sprite. You can see the tile here:

public static Tile grass = new GrassTile(Sprite.grass);
public static Tile voidTile = new VoidTile(Sprite.voidSprite);

And the sprite is created like that:

public static Sprite grass = new Sprite(16, 0, 0, Spritesheet.tileset);
public static Sprite voidSprite = new Sprite(16, 0x00AAFF);

Two constructors for sprites: these are

(int size, int x, int y, Spritesheet sheet)
(int size, int colour)

And the level is randomly generated with fields ranging from 0-3 (0 is grass, the rest is currently just VoidTile. But something is wrong with the way it displays graphics. I did check it with the use of printlns, and I'm sure most of it works (it does assign correct Tiles, depending on ID). You can see it there:

ID: 0 |   Tile: com.ekhart.game.level.tile.GrassTile@73d74138 |   Sprite: com.ekhart.game.gfx.Sprite@3d0c51ef
ID: 2 |   Tile: com.ekhart.game.level.tile.VoidTile@3ba0d916 |   Sprite: com.ekhart.game.gfx.Sprite@3d0c51ef
ID: 3 |   Tile: com.ekhart.game.level.tile.VoidTile@3ba0d916 |   Sprite: com.ekhart.game.gfx.Sprite@3d0c51ef
ID: 1 |   Tile: com.ekhart.game.level.tile.VoidTile@3ba0d916 |   Sprite: com.ekhart.game.gfx.Sprite@3d0c51ef

And you might notice, that the Sprite is the same, even though when I create the grass and voidTile classes, they have different sprites assigned to them. And the weird part is that the sprite assigned depends on the order in which I create them. Now all tiles have a voidSprite graphic, because I created VoidTile last. When I swap them around (making GrassTile last), they all have grass sprite. I tried everything I could think of to make this work, but it doesn't. I have uploaded the project folder, so you can import it and check the code, maybe I've missed something.

Project url: https://dl.dropboxusercontent.com/u/18909657/TheGame.rar


Solution

  • OK, I lied and did look at your rar file, and you are using static inappropriately as I suspected:

    public class Tile {
    
    public int x;
    public int y;
    
    public static Sprite sprite;
    
    public static Tile grass = new GrassTile(Sprite.grass);
    public static Tile voidTile = new VoidTile(Sprite.voidSprite);
    
    public Tile(Sprite sprite) {
        Tile.sprite = sprite;
    }
    
    public void render(int x, int y, Screen screen) {
    }
    
    public boolean solid() {
        return false;
    }
    
    }
    

    By making the sprite field static, it is the now the same for all Tile instances.

    Solution:

    • don't use static inappropriately. The sprite Sprite variable should not be static.
    • Do post appropriate code on this site so we don't have to do the scut work for you that you should be doing yourself, such as digging for the error.
    • Don't mix AWT and Swing components unnecessarily.

    Note that if your compile complains at you when you change sprite to be non-static, then you must fix the other code that uses the sprite field, not make sprite static again.