0
\$\begingroup\$

I am making a 2D tile based game. The tiles render fine from a spritesheet and a text file. However, I am using a for loop to draw the map to the screen. When it refreshes, it slows down the loop, and the bottom is black for a fraction of a second.

I was wondering if I could create a separate method to create a BufferedImage to hold the map, so I could render it continuously, and change it when needed.

Map Class:

package uk.co.madmonkeystudios.distortioner;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;

import javax.imageio.ImageIO;
import javax.swing.JOptionPane;

public class Map {

    static BufferedImage sheet;

    public static void SetSpriteSheet() throws IOException{
        sheet = ImageIO.read(new File("res/grid.png"));
    }

    public static BufferedImage GetTile(int id) throws IOException{
        if(sheet == null){SetSpriteSheet();}

        int across = 24;

        BufferedImage tile = null;
        int x = 0;
        int y = 1;
        int w = 31;
        int h = 31;
        for(int done = 0;done<id;done++){

            x= done * w;
            x += id;
            if(done >= across){
                y += h;
                y++;
            }

        }
        tile = sheet.getSubimage(x, y, w, h);

        return tile;
    }

    public static void DrawMap(int id) throws IOException{

        Graphics2D g = (Graphics2D)Core.myself.getGraphics();


        g.clearRect(0,0,640,480);

        int[][] map = ReadMap(0);

        int xsize = map.length;
        int ysize = map[0].length;
        System.out.println("Map Read, size (" +xsize + "," +ysize+")");

        int x = Player.x;
        int y = Player.y;

        for(int loopy = 0;loopy<ysize;loopy++){
            for(int loop = 0;loop<xsize;loop++){
                g.drawImage(GetTile(map[loop][loopy]),loop * 32 + x, loopy * 32 +y + 25,32,32,null);
            }
            }
    }

    public static int[][] ReadMap(int id){
        int [][] map = null;
        try{
        @SuppressWarnings("resource")
        Scanner s = new Scanner(new File("res/maps/area"+id+".map"));
        int [][] map1 = new int[Integer.parseInt(s.next())][Integer.parseInt(s.next())];
        String current;

        int xsize = map1.length;
        int ysize = map1[0].length;


        for(int loopy = 0;loopy<ysize;loopy++){
        for(int loop = 0;loop<xsize;loop++){
            current = s.next();
            map1[loop][loopy] = Integer.parseInt(current);
        }
        }
        map = map1;
        }catch(NullPointerException ex70){
            System.err.println("Cannot read map in area ID " +id);
            JOptionPane.showMessageDialog(null, "Couldn't read map...","",JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        }
        catch(FileNotFoundException ex71){
            System.err.println("Cannot find map in area ID " +id);
            JOptionPane.showMessageDialog(null, "Couldn't read map...","",JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        }
        catch(ArrayIndexOutOfBoundsException ex72){
            System.err.println("Cannot add map to array in area ID " +id);
            JOptionPane.showMessageDialog(null, "Couldn't send map...","",JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        }


        return map;
    }

}
\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

Why not add double buffering to everything drawn in your game?

This is the way I would do it...

you would declare 2 variables in your main game class like so:

private Graphics g;
private BufferStrategy bs;
//private YourTileMap map;

then in my main class I would have a render method which does exactly what it sounds like it does... It renders all of my components in the game.

Note: To use the "getBufferStrategy();" method; my main class extends Canvas

There are many ways to skin a cat and this is my take on it :)

public void render() {
    bs = getBufferStrategy(); // Gets BufferStrategy
    if (bs == null) { // If it = null
        createBufferStrategy(3); // Create 3 Buffer Strategies
        return;
    }

    try {
        g = bs.getDrawGraphics(); // Gets BufferStrategies draw graphics
        g.setColor(Color.BLACK); // Sets Color to black
        g.fillRect(0, 0, (int)SCREEN_SIZE.getWidth(), (int)SCREEN_SIZE.getHeight()); // Fills the background of window with black

        // Render Components Here
        //Example:
        // map.render(g);


    } finally {
        g.dispose(); // Disposes of the graphics once finished copying them
    }

    bs.show(); // Shows the image you just created behind the scenes

}

As I stated before, this is just one take on double buffering and I'm sure there are people who have different ways of doing it...

I find this the best way of doing :)

Dont forget to initialise your map either ;)

\$\endgroup\$

You must log in to answer this question.