1

I am trying to make a scrolling game - where the player (in space) is constantly at the center of the screen. As he moves left right up and down, a background spritesheet will randomly generate coloured stars - so the moving stars will be an indication of which direction the player is moving in.

The problem I am now having is that the stars are not displaying when I run the game. Each tile is supposed to be 32x32, each containing at least one star, with the 'nostars' tile being empty. When I run the game, I just get a black screen.

RandomLevel.java:

protected void generateLevel() {
    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {
            bgtiles[x + y * width] = random.nextInt(4);
        }
    }
}

Level.java

public void render(int xScroll, int yScroll, Screen screen) {
    screen.setOffset(xScroll, yScroll);

    int x0 = xScroll >> 5;
    int x1 = (xScroll + screen.width + 32) >> 5;
    int y0 = yScroll >> 5;
    int y1 = (yScroll + screen.height + 32) >> 5;

    for(int y = y0; y < y1; y++) {
        for(int x = x0; x < x1; x++) {
            getTile(x, y).render(x, y, screen);
        }
    }
}
public Tile getTile(int x, int y) {
if(x < 0 || y < 0 || x >= width || y >= height) return Tile.nostars;
    if(bgtiles[x + y * width] == 0) return Tile.stars1;
    if(bgtiles[x + y * width] == 1) return Tile.stars2;
    if(bgtiles[x + y * width] == 2) return Tile.stars3;
    if(bgtiles[x + y * width] == 3) return Tile.stars4;

    else return Tile.nostars;
}

SpaceTile.java

public class SpaceTile extends Tile {

   public SpaceTile(Sprite sprite) {
    super(sprite);
}

public void render(int x, int y, Screen screen) {
    screen.renderTile(x << 5, y << 5, this);
}

}

SpriteSheet.java

public static SpriteSheet bgtiles = new SpriteSheet("/textures/bgsheet.png", 256);

Sprite.java

public static Sprite spaceSprite = new Sprite(32, 0, 0, SpriteSheet.bgtiles);
public static Sprite stars1 = new Sprite(64, 0, 0, SpriteSheet.bgtiles);
public static Sprite stars2 = new Sprite(96, 0, 0, SpriteSheet.bgtiles);
public static Sprite stars3 = new Sprite(128, 0, 0, SpriteSheet.bgtiles);
public static Sprite stars4 = new Sprite(160, 0, 0, SpriteSheet.bgtiles);

Tile.java

public class Tile {

public int x, y;
public Sprite sprite;

public static Tile nostars = new SpaceTile(Sprite.spaceSprite);
public static Tile stars1 = new SpaceTile(Sprite.stars1);
public static Tile stars2 = new SpaceTile(Sprite.stars2);
public static Tile stars3 = new SpaceTile(Sprite.stars3);
public static Tile stars4 = new SpaceTile(Sprite.stars4);

public Tile(Sprite sprite) {
    this.sprite = sprite;
}

public void render(int x, int y, Screen screen) {   
}

public boolean solid() {
    return false;
}

}

Game.java

public class Game extends Canvas implements Runnable { 
private static final long serialVersionUID = 1L;

public static int width = 300;
public static int height = width / 16 * 9;
public static int scale = 3;

public static String title = "Game";

private Thread thread;
private JFrame frame;
private Keyboard key;
private Level level;
private boolean running = false;

private Screen screen;

private BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();

public Game() {
    Dimension size = new Dimension(width * scale, height * scale);
    setPreferredSize(size);

    screen = new Screen(width, height);
    frame = new JFrame();
    key = new Keyboard();
    level = new RandomLevel(64, 64);

    addKeyListener(key);
}

public synchronized void start() {
    running = true;
    thread = new Thread(this, "Display");
    thread.start();
}

public synchronized void stop() {
    running = false;
    try {
        thread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public void run() {
    double ns = 1000000000.0 / 60.0;
    double delta = 0;

    int frames = 0;
    int updates = 0;

    long lastTime = System.nanoTime();
    long timer = System.currentTimeMillis();

    requestFocus();

    while (running) {
        long now = System.nanoTime();

        delta += (now - lastTime) / ns;
        lastTime = now;

        while(delta >= 1) {
            update();
            updates++;
            delta--;
        }

        render();
        frames++;

        if(System.currentTimeMillis() - timer >= 1000) {
            timer += 1000;
            frame.setTitle(title + "  |  " + updates + " ups, " + frames + " fps");
            frames = 0;
            updates = 0;
        }
    }

    stop();
}

int x, y = 0;

public void update() {
    key.update();
    if(key.up == true) y--;
    if(key.down == true) y++;
    if(key.left == true) x--;
    if(key.right == true) x++;
}

public void render() {
    BufferStrategy bs = getBufferStrategy();
    if (bs == null) {
        createBufferStrategy(3);
        return;
    }

    screen.clear();
    level.render(x, y, screen);

    for(int i = 0; i < pixels.length; i++) {
        pixels[i] = screen.pixels[i];
    }

    Graphics g = bs.getDrawGraphics();
    g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
    g.dispose();
    bs.show();
}

public static void main(String[] args) {
    Game game = new Game();
    game.frame.setResizable(false);
      game.frame.setTitle(Game.title);
      game.frame.add(game);
      game.frame.pack();
      game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      game.frame.setLocationRelativeTo(null);
      game.frame.setVisible(true);

    game.start();
}

}

bgsheet.png https://i.sstatic.net/SUIDS.png

In the generatelevel() I am only trying it out with the first 4 tiles, not all of the 64 tiles.

When I run the game, I expect to see 4 different stars scattered everywhere but instead I just get a black screen.

Thanks in advance for any help !

2
  • Can you please add some context? Are you building this in straight Java or are you using a library? If just Java, please list the code for the JComponent you are using to render. Commented Dec 23, 2014 at 15:24
  • Just Java - have added in the game class Commented Dec 23, 2014 at 15:28

3 Answers 3

1

From the code posted, it appears that you forgot to load the background into image. I placed this code into a new public method called loadAssets(). Call this before you call game.start().

public void loadAssets() {
    try {
        image = ImageIO.read(new URL("https://i.imgur.com/0yUKql2.png?1"));
    } catch (MalformedURLException ex) {
        Logger.getLogger(GameTwo.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
        Logger.getLogger(GameTwo.class.getName()).log(Level.SEVERE, null, ex);
    }
}

I also commented out the following code in render().

screen.clear();
level.render(x, y, screen);

for(int i = 0; i < pixels.length; i++) {
    pixels[i] = screen.pixels[i];
}
Sign up to request clarification or add additional context in comments.

5 Comments

I've had no luck with this so far - sorry to be a noob, but where exactly should this code be placed?
@Oliver I placed the entire try-block right after your call to addKeyListener. This is not the best place to add the code, but it did make it work. I would add a loadAssets method (see edited code) and call that before start.
That seems to make the stars appear, but not in tile form - the image has just been stretched and placed in the screen; they are not randomly being generated
@Oliver Use the width/height of the buffered image in the draw method. This should keep it from stretching.
But tiles still aren't being rendered. I'm trying to split the bgsheet.png into 64 tiles, i.e. 64 different stars, and randomly generate them across the screen - not simply draw the whole image on to the screen.
0

So from what I understand, you make a call to draw using BufferedImage image, however you have not actually loaded your image data into the variable image. I will provide a code snippet that you may need to tailor a bit

 File imageFile = new File("/path/to/image.file");
 BufferedImage image = ImageIO.read(imageFile);

There may be a faster way as you have already called

private BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

But as you can probably imagine, that doesn't actually connect you image variable to an image file. My best guess is that the code I provided will work, but honestly you'll have to try it.

Happy coding and leave a comment if you have any questions!

Comments

0

The problem turned out to be simply that I had the wrong co-ordinates for each sprite. Sorry for wasting your time and thanks for the help anyway!

public static Sprite spaceSprite = new Sprite(32, 0, 0, SpriteSheet.bgtiles);
public static Sprite stars1 = new Sprite(32, 1, 0, SpriteSheet.bgtiles);
public static Sprite stars2 = new Sprite(32, 2, 0, SpriteSheet.bgtiles);
public static Sprite stars3 = new Sprite(32, 3, 0, SpriteSheet.bgtiles);
public static Sprite stars4 = new Sprite(32, 4, 0, SpriteSheet.bgtiles);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.