我正在做一个小java游戏作为学校项目。我已经使用平铺工具创建了一个平铺地图,并且地图显示正确。在我的地图上,我想制作瀑布动画,为此,我将对象图层放置在图块地图中,然后在 Java 中检索(地图上的对象坐标、大小等)。
问题就在这里:我以纹理的形式加载图像,该图像也用于制作我的图块地图,我将其分割以获取正确的图块并将其放置在对象坐标处,但纹理显示在地图之外。出于测试目的,我尝试将纹理放置在鼠标的坐标处。
我在互联网上发现你必须使用camera.unproject,它确实可以工作,但只有在没有setToOrtho的情况下。
所以我向堆栈溢出寻求帮助,谢谢!
这里是 github 上的代码,供那些想要运行完整测试的人使用:
https://github.com/UniLasalle-Amiens/TP_JAVA-Boats-Management
其他:
public class MyGdxGame extends ApplicationAdapter {
private static final int TILESET_COLS = 26, TILESET_ROWS = 15, TILE_WIDTH = 32, TILE_HEIGHT = 32;
private AssetManager assetManager;
private TiledMap map;
private Texture tileSheet;
private OrthogonalTiledMapRenderer tilemapRenderer;
// Camera
private OrthographicCamera camera;
private SpriteBatch batch;
private BitmapFont font;
// Animation des chûtes d'eau
private Animation<TextureRegion> waterFallAnimation;
private List<Rectangle> waterFallRectangles = new LinkedList<Rectangle>();
private float _waterFallStateTime = 0;
@Override
public void create() {
batch = new SpriteBatch();
// Asset manager
assetManager = new AssetManager();
assetManager.setLoader(TiledMap.class, new TmxMapLoader(new InternalFileHandleResolver()));
assetManager.load("Map.tmx", TiledMap.class);
// Chargement de la texture 32x32.png
assetManager.setLoader(Texture.class, new TextureLoader(new InternalFileHandleResolver()));
assetManager.load("Tiles/32x32.png", Texture.class);
assetManager.finishLoading();
map = assetManager.get("Map.tmx");
tileSheet = assetManager.get("Tiles/32x32.png");
// Mise en place de la caméra dans la scène
camera = new OrthographicCamera();
camera.setToOrtho(false);
camera.update();
// Rendu de la map
tilemapRenderer = new OrthogonalTiledMapRenderer(map);
// Mettre la fenêtre en mode plein écran
Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode());
// Rendre le fenêtre redimensionnable
Gdx.graphics.setResizable(true);
// Animation des chûtes d'eau
TextureRegion[][] waterFallTmp = TextureRegion.split(tileSheet, TILE_WIDTH, TILE_HEIGHT);
TextureRegion[] waterFallFrames = new TextureRegion[3];
waterFallFrames[0] = waterFallTmp[10][14];
waterFallFrames[1] = waterFallTmp[10][15];
waterFallFrames[2] = waterFallTmp[10][16];
waterFallAnimation = new Animation<TextureRegion>(0.150f, waterFallFrames);
// Récupération du groupe d'object Layers
MapGroupLayer objectsGroupLayer = (MapGroupLayer) map.getLayers().get("ObjectsLayers");
// Récupération de l'object Layer "Waterfall"
MapLayer waterFallLayer = objectsGroupLayer.getLayers().get("Waterfall");
// Récupération des objets de l'object Layer "Waterfall"
MapObjects waterFallObjects = waterFallLayer.getObjects();
batch.begin();
for (MapObject object : waterFallObjects) {
// RectangleMapObject rectangleMapObject = (RectangleMapObject) object;
// waterFallRectangles.add(rectangleMapObject.getRectangle());
batch.draw(waterFallFrames[0], object.getProperties().get("x", Float.class),
object.getProperties().get("y", Float.class),
object.getProperties().get("width", Float.class),
object.getProperties().get("height", Float.class));
}
batch.end();
}
@Override
public void render() {
ScreenUtils.clear(0, 0, 0, 1);
camera.update();
// batch.setProjectionMatrix(camera.combined);
tilemapRenderer.setView(camera);
tilemapRenderer.render();
// Gestion de l'animation des chûtes d'eau
_waterFallStateTime += Gdx.graphics.getDeltaTime();
TextureRegion currentFrame = waterFallAnimation.getKeyFrame(_waterFallStateTime, true);
// Mouse position
Vector3 mousePosition = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
Vector3 vc = camera.unproject(mousePosition);
batch.begin();
batch.draw(currentFrame, vc.x, vc.y);
batch.end();
// batch.begin();
// for (Rectangle rectangle : waterFallRectangles)
// batch.draw(currentFrame, rectangle.x / 4, rectangle.y / 3, rectangle.width /
// 2, rectangle.height / 2);
// batch.end();
}
/**
* Called when the {@link Application} is destroyed. Preceded by a call to
* pause().
* <p>
* LibGDX recommends disposing of assets in this method.
* </p>
*/
@Override
public void dispose() {
map.dispose();
tilemapRenderer.dispose();
batch.dispose();
tileSheet.dispose();
}
}
我认为这是由于缩放问题,因为如果删除camera.setToOrtho,纹理会正确跟随图像,但是当添加这条线时,看起来坐标的比率乘以2、3甚至4 .
在
create
(ApplicationAdapter
) 的 MyGdxGame
方法中设置全屏模式会破坏这种情况,因为有些东西预计已经在那里初始化了。
如果删除
// Mettre la fenêtre en mode plein écran
Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode());
// Rendre le fenêtre redimensionnable
Gdx.graphics.setResizable(true);
从
create
方法中将 DesktopLauncher
更改为
Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
config.setForegroundFPS(60);
config.setTitle("Boats-Management");
config.setWindowIcon("icon.png");
// Add this line
config.setFullscreenMode(Lwjgl3ApplicationConfiguration.getDisplayMode());
new Lwjgl3Application(new MyGdxGame(), config);
当您点击
create
时,所有相关的事情都应该初始化。
除了这样做之外,我还会更改相机设置,以便它显示设定数量的图块宽度并保持纵横比:
// Mise en place de la caméra dans la scène
float aspectRatio = Gdx.graphics.getWidth() / (float) Gdx.graphics.getHeight();
float tilesWide = 65 * TILE_WIDTH;
camera = new OrthographicCamera(tilesWide, tilesWide / aspectRatio);
camera.position.set(camera.viewportWidth / 2.0f, camera.viewportHeight /2.0f, 1.0f);
camera.update();
将 65 更改为游戏中看起来不错的值。
最后,您应该告诉您的
SpriteBatch
在渲染时使用 render
方法中的投影:
// Add this line
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(currentFrame, vc.x, vc.y);
batch.end();