【问题标题】:Adding an instance to an array LibGDX将实例添加到数组 LibGDX
【发布时间】:2015-09-23 03:32:15
【问题描述】:

我试图在关卡地图中做到这一点,只要有“g”,就会将一个新的Ground 实例附加到 ArrayList。当我使用.add() 方法时,似乎每次调用函数后数组列表都会重置。这是我的代码:

package com.mygdx.thetimetraveller;

import com.badlogic.gdx.graphics.g2d.SpriteBatch;

import java.util.ArrayList;
import java.util.List;

public class Game implements Screen {
    SpriteBatch batch = new SpriteBatch();

    List<Ground> groundList = new ArrayList<Ground>();

    String[] level = {
        "                    ",
        "                    ",
        "                    ",
        "                    ",
        "                    ",
        "                    ",
        "      g             ",
        "g                   ",
        "ggggggggggggg ggg gg",
        "g                   "
    };

    Game(SpriteBatch batch) {
        this.batch = batch;
        this.load();
    }

    @Override
    public void load() {
        for(int c = 0; c < level.length; c ++){
            for(int r = 0; r < level[c].length(); r ++){
                switch(level[c].charAt(r)) {
                    case 'g':
                        groundList.add(new Ground(r * 108, c * 108, this.batch));
                        break;
                }
            }
        }
    }

    @Override
    public void display() {
        for(int i = 0; i < groundList.size(); i ++) {
            groundList.get(i).Draw();
        }
    }
}

当我运行它时,只显示一个地面块,这是数组中的最后一个“g”(底行,第一个字符)。那么,我怎样才能将一个新实例推入arraylist?或者,我可以使用 arraylist 的替代方法吗?总体而言,我希望能够遍历所有列表,并在 load() 方法的嵌套 for 循环中附加的每个实例上调用 .Draw() 方法。我知道有很多人在 StackOverflow 论坛上询问如何在常规 java 中附加到数组列表,但是 LibGDX 的行为不同,所以我找不到任何帮助。提前致谢!

该代码在“Game.java”中。这是其余的代码: “Main.java”:

package com.mygdx.thetimetraveller;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

public class Main extends ApplicationAdapter {
    SpriteBatch batch;
    OrthographicCamera camera;
    Screen gameState;

    private int gameScene = 4;

    @Override
    public void create () {
        batch = new SpriteBatch();
        gameState = new Game(batch);
        camera = new OrthographicCamera();
        camera.setToOrtho(true, 1920, 1080);
        Assets.imagesLoad();
    }

    @Override
    public void dispose () {
        batch.dispose();
    }

    @Override
    public void render () {
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        switch (gameScene) {
            case 1:
                break;
            case 2:
                break;
            case 3:
                break;
            case 4:
                gameState = new Game(batch);
                break;
        }
        camera.update();
        batch.setProjectionMatrix(camera.combined);
        batch.begin();
            gameState.display();
        batch.end();
    }
}

“Ground.java”:

package com.mygdx.thetimetraveller;

import com.badlogic.gdx.graphics.g2d.SpriteBatch;

public class Ground extends GameBlock {
    Ground(double x, double y, SpriteBatch batch) {
        setX(x);
        setY(y);
        setBatch(batch);
    }

    @Override
    public void Draw() {
        batch.draw(Assets.simpleBlockTexture01_sprite, (float) x, (float) y);
    }
}

“GameBlock.java”:

package com.mygdx.thetimetraveller;

import com.badlogic.gdx.graphics.g2d.SpriteBatch;

public abstract class GameBlock {
    protected static double x;
    protected static double y;
    protected static SpriteBatch batch = new SpriteBatch();

    public void setX(double x) {
        this.x = x;
    }
    public void setY(double y) {
        this.y = y;
    }
    public double getX() {
        return this.x;
    }
    public double getY() {
        return this.y;
    }
    public void setBatch(SpriteBatch batch) {
        this.batch = batch;
    }
    public abstract void Draw();
}

“Screen.java”:

package com.mygdx.thetimetraveller;

public interface Screen {
    void load();
    void display();
}

对于这种情况,我仍然省略了不必要的类,例如其他对象类和资产类。

【问题讨论】:

  • 一个小提示:使用 libgdx Array 类而不是 ArrayList。 Libgdx 集合已针对 avoid garbage collection 进行了优化,因此它们可能会给您带来一点 FPS-Boost,至少在移动设备上是这样。
  • ArrayList 在 Libgdx 中的行为与在其他任何地方的行为相同。尝试将 toString 方法添加到 Ground 类并记录列表 toString() 以缩小错误范围。
  • 顺便说一句,你在类构造函数之外实例化了一个一次性的精灵批处理,它会泄漏内存,因为它从未被处理掉。
  • 这到底是什么意思?我应该处理 SpriteBatch 吗?我已经在主类中了,并且那个 spritebatch 被设置为每个使用它的类的 spritebatch。
  • 那么,谁能帮帮我?

标签: java android arrays arraylist libgdx


【解决方案1】:

为什么要将这些理由添加到列表中?为什么你不使用你的数组直接绘制你需要的东西?我也会选择多维数组。请看以下内容:

String[][] level = {
  {"g", "r", "g"},
  {" ", "x", "t"},
  //...
};

for (int y = 0; y < level[0].length; y++)
{
  for (int x = 0; x < level.length; x++)
  {
      if (level[x][y].equals("g"))
        draw(groundTile, x * tilewidth, y * tileheight);
      else if (level[x][y].equals("x"))
        draw(otherTile, x * tilewidth, y * tileheight);
  }
}

这在您有大关卡时特别方便。您可以根据相机位置、分辨率和图块大小确切地知道要绘制什么。现在你只需要遍历数组的必要部分而不是整个列表。

【讨论】:

  • 出于效率考虑,我将实例添加到列表中。
  • 那么,有没有办法按照我的要求去做?
  • 我不明白为什么你的方法会更有效。数组列表本质上是一个有点过热的数组。据我所知,您的代码应该可以正常工作。尝试调试并密切关注您的数组列表。
  • 我尝试了很多很多很多东西。如果我使用方法,那么我将不得不重复代码行。这就是我说它更有效的主要原因。另外,如果我采用您的方法,变量将无法更改。例如,我有一种情况,对象(如敌人)有一个 alive 布尔值。如果我说alive = false;,当发生杀死敌人的事情时,什么都不会发生。总的来说,我希望能够以最有效的方式添加敌人、boss、常规方块,也许还有一些熔岩方块或尖刺等。有什么建议吗?
  • 为什么普通数组中的对象不会/不会发生任何事情?显然我不知道你目标的大局,但map[x][y].setAlive(false) 将与map.get(mapWidth * y + x).setAlive 相同。我不明白为什么你必须重复代码行,或者你的意思。
猜你喜欢
  • 2021-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-16
  • 1970-01-01
  • 2015-02-27
相关资源
最近更新 更多