java图像渲染导致fps下降

时间:2015-10-25 13:35:33

标签: java render draw bufferedimage sprite-sheet

我正在制作一个2d平台游戏我正在使用16px到16px的网格块。我试图用5 for循环加载这些所有10000px宽示例问题是,每个块从精灵表中加载自己的纹理。我不知道该怎么做。问题是我从4000 fps变为200/300。我需要稍后使用随机地形生成器加载更多块。

我发现你可以将所有瓷砖缓存在一起,但我不知道如何做到这一点, How do prevent my FPS dropping when loading spritesheet in java?

我发现一篇帖子说我应该只加载屏幕上可见的纹理。这可能是更好的选择,我仍然不知道我将如何做到这一点。其中一个原因是因为我希望地图是随机生成的,所以我必须在至少加载时加载它?

游戏类

public class Game extends Canvas implements Runnable{

private boolean running = false;
private Thread thread;

// Object
Handler handler;
Camera cam;

private void init() {   
    tex = new Texture();

    handler = new Handler();

    handler.createTerrain();

    handler.addObject(new Player(0, 300, handler, ObjectId.Player));

    this.addKeyListener(new KeyInput(handler));
}

public synchronized void start() {  
    if(running)
        return;

    running = true;
    thread = new Thread(this);
    thread.start();
    }

// runs the main loop
public void run() {
    // get all game objects into the game
    init();
    this.requestFocus();

    // very fun math to calculate frame and tick :/ * leave it as it is *
    long lastTime = System.nanoTime();
    double amountOfTicks = 60.0;
    double ns = 1000000000 / amountOfTicks;
    double delta = 0;
    long timer = System.currentTimeMillis();
    int updates = 0;
    int frames = 0;

    while(running){
        long now = System.nanoTime();
        delta += (now - lastTime) / ns;
        lastTime = now;
        while(delta >= 1){
            tick();
            updates++;
            delta--;
        }
        render();
        frames++;

        if(System.currentTimeMillis() - timer > 1000){
            timer += 1000;
            System.out.println("FPS: " + frames + " TICKS: " + updates);
            frames = 0;
            updates = 0;
        }
    }
}

private void tick() {
    handler.tick();
}

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

    Graphics g = bs.getDrawGraphics();
    Graphics2D g2d = (Graphics2D) g;

    g.setColor(Color.black);
    g.fillRect(0, 0, getWidth(), getHeight());

    handler.render(g);

    g.dispose();
    bs.show();
}

public static Texture getInstance() {
    return tex;

}

public static void main(String args[]) {
    new Window(800, 600, "#", new Game());
}

}

处理程序类

public class Handler {

    public ArrayList<GameObject> object = new ArrayList<GameObject>();

    public void tick() {
        // get a item out the array list
        for(GameObject o: object) {

            o.tick(object);
        }
    }

    public void render(Graphics g) {
        // get a item out the array list
        for(GameObject o: object) {

            o.render(g);
        }
    }

    public void createTerrain() {       
        //floor grass
        for(int xx = -10000; xx < Game.WIDTH * 2; xx += 16) {
            addObject(new Block(xx, Game.HEIGHT - 32, 0,ObjectId.Block));
        }
        //floor dirt
        for(int xx = -10000; xx < Game.WIDTH * 2; xx += 16) {
            addObject(new Block(xx, Game.HEIGHT - 16, 1,ObjectId.Block));
        }
        //floor stone
        for(int xx = -10000; xx < Game.WIDTH * 2; xx += 16) {
            addObject(new Block(xx, Game.HEIGHT - 0, 2,ObjectId.Block));
        }
        // sand
        for(int xx = -10000; xx < Game.WIDTH * 2; xx += 16) {
            addObject(new Block(xx, Game.HEIGHT + 16, 3,ObjectId.Block));
        }
        //floor water
        for(int xx = -10000; xx < Game.WIDTH * 2; xx += 16) {
            addObject(new Block(xx, Game.HEIGHT + 32, 4,ObjectId.Block));
        }
    }
}

纹理类

public class Texture {

    SpriteSheet bs, ps;
    private BufferedImage block_sheet = null;
    private BufferedImage player_sheet = null;

    public BufferedImage[] block = new BufferedImage[5];
    public BufferedImage[] player = new BufferedImage[9];
    public BufferedImage[] player_jump = new BufferedImage[1];

    public Texture() {

        BufferedImageLoader loader = new BufferedImageLoader();

        try {
            block_sheet = loader.loadImage("/Block.png");
            player_sheet = loader.loadImage("/Player.png");
        }catch(Exception e) {
            e.printStackTrace();
        }

        bs = new SpriteSheet(block_sheet);
        ps = new SpriteSheet(player_sheet);

        getTextures();
    }

    private void getTextures() {
        block[0] = bs.grabImage(1, 1, 16, 16); // grass not broken
        block[1] = bs.grabImage(1, 2, 16, 16); // dirt not broken
        block[2] = bs.grabImage(1, 3, 16, 16); // stone not broken
        block[3] = bs.grabImage(1, 4, 16, 16); // sand not broken
        block[4] = bs.grabImage(1, 5, 16, 16); // water

        // right
        player[0] = ps.grabImage(1, 1, 32, 64); // player standing
        player[1] = ps.grabImage(2, 1, 32, 64); // player move right
        player[2] = ps.grabImage(3, 1, 32, 64); // player move right
        player[3] = ps.grabImage(4, 1, 32, 64); // player move right

        // left
        player[4] = ps.grabImage(1, 2, 32, 64); // player standing
        player[5] = ps.grabImage(2, 2, 32, 64); // player move left
        player[6] = ps.grabImage(3, 2, 32, 64); // player move left
        player[7] = ps.grabImage(4, 2, 32, 64); // player move left

        // jump
        player_jump[0] = ps.grabImage(1, 3, 32, 64); // player jumps
    }   
}

阻止类

public class Block extends GameObject{

    Texture tex = Game.getInstance();
    private int type;

    public Block(float x, float y, int type ,ObjectId id) {
        super(x, y, id);
        this.type = type;
    }

    public void tick(ArrayList<GameObject> object) {

    }

    public void render(Graphics g) {

        if(type == 0) /* grass */ {
            g.drawImage(tex.block[type], (int)x, (int)y, null);
        }

        if(type == 1) /* dirt */ {
            g.drawImage(tex.block[type], (int)x, (int)y, null);
        }

        if(type == 2) /* stone */ {
            g.drawImage(tex.block[type], (int)x, (int)y, null);
        }

        if(type == 3) /* sand */ {
            g.drawImage(tex.block[type], (int)x, (int)y, null);
        }

        if(type == 4) /* water */ {
            g.drawImage(tex.block[type], (int)x, (int)y, null);
        }

    }

    public Rectangle getBounds() {
        return new Rectangle((int)x, (int)y, 16, 16);
    }
}

SpriteSheet类 问题应该在这里,因为所有图像都有自己的纹理

public class SpriteSheet {

    private BufferedImage image;

    public SpriteSheet(BufferedImage image) {
        this.image = image;
    }

    public BufferedImage grabImage(int col, int row, int width, int height) {
        BufferedImage img = image.getSubimage((col * width) - width, (row * height) - height, width, height);
        return img;
    }   
}

0 个答案:

没有答案