我正在制作一个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;
}
}