当前位置: 首页 > 知识库问答 >
问题:

在地图上画一个精灵,而不是在屏幕上

高海阳
2023-03-14

我正在使用libgdx,我有一个平铺的地图,我想把精灵画在上面。然而,精灵被绘制到实际的窗口上,所以当我移动相机时,精灵保持在原来的位置?我想让精灵在地图上移动。

这就是我当前渲染对象的方式

    @Override
    public void render(float delta) {
        translateCamera();

        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

        camera.update();

        renderer.setView(camera);

        renderer.render(bgLayers);
        batch.begin();

        batch.draw(splayerSprite, Gdx.graphics.getWidth() / 2,
                Gdx.graphics.getHeight() / 2);

        batch.end();
        renderer.render(fgLayers);

    }

它总是在屏幕的中间,但是我想能够像移动相机一样移动它们(例如,W,A,S,D),并用方向键移动我的播放器。然后,如果我想把相机锁定在播放器上,但从另一方面来说,它是免费的。

我是libgdx的新手,所以请容忍我,谢谢

共有2个答案

晏晨朗
2023-03-14

批处理。draw(splayerSprite,Gdx.graphics.getWidth()/2,Gdx。图样getHeight()/2)

您每次都在告诉代码将其绘制到屏幕中央。您需要更改Gdx。图样getWidth()/2Gdx。图样getHeight()/2转换为根据您的输入更改的实际值。

编辑#2:行批处理。setProjectionmatrix(camera.combined)是必需的除了我提到的所有内容之外,我都没有注意到我的代码中已经有特定的行(它包含在默认的libGDX项目中),也没有尝试在删除该行的情况下运行我的演示。我希望这能消除我可能引起的任何困惑。

编辑:显然没人喜欢我的答案,所以我用干净的libGDX游戏中指定的控件编写了一个演示。无论相机瞄准何处(因为它正在被平移),精灵总是在全局屏幕的中心进行渲染。在批处理中使用精灵的位置是非常必要的。draw()。

package com.me.mygdxgame;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector2;

public class MyGdxGame implements ApplicationListener {
    private OrthographicCamera camera;
    private SpriteBatch batch;
    private Texture texture;
    private Sprite sprite;
    private Sprite background;

    private boolean lockToSprite;
    private Vector2 vecCamera;
    private Vector2 vecSprite;

    @Override
    public void create() {      
        float w = Gdx.graphics.getWidth();
        float h = Gdx.graphics.getHeight();

        camera = new OrthographicCamera(w, h);
        batch = new SpriteBatch();

        lockToSprite = true;
        vecCamera = new Vector2();
        vecSprite = new Vector2();

        texture = new Texture(Gdx.files.internal("data/libgdx.png"));
        texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);

        TextureRegion region = new TextureRegion(texture, 0, 0, 512, 275);

        sprite = new Sprite(region);
        sprite.setSize(0.1f * sprite.getWidth(), 0.1f * sprite.getHeight());
        sprite.setOrigin(sprite.getWidth()/2, sprite.getHeight()/2);
        sprite.setPosition(-sprite.getWidth()/2, -sprite.getHeight()/2);

        background = new Sprite(region);
        background.setOrigin(background.getWidth() / 2, background.getHeight() / 2);
        System.out.println(background.getOriginX());
        background.setPosition(-background.getWidth() / 2, -background.getHeight() / 2);
    }

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

    @Override
    public void render() {
        camera.translate(vecCamera);

        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

        camera.update();

        camera.translate(vecCamera.cpy().mul(-1));

        float moveSensitivity = 0.9f;

        Vector2 vecInputSprite = new Vector2();
        if (Gdx.input.isKeyPressed(Keys.UP))
            vecInputSprite.y += moveSensitivity;
        if (Gdx.input.isKeyPressed(Keys.DOWN))
            vecInputSprite.y -= moveSensitivity;
        if (Gdx.input.isKeyPressed(Keys.LEFT))
            vecInputSprite.x -= moveSensitivity;
        if (Gdx.input.isKeyPressed(Keys.RIGHT))
            vecInputSprite.x += moveSensitivity;
        if (Gdx.input.isKeyPressed(Keys.N))
            vecSprite.set(new Vector2());

        Vector2 vecInputCamera = new Vector2();
        if (Gdx.input.isKeyPressed(Keys.W))
            vecInputCamera.y += moveSensitivity;
        if (Gdx.input.isKeyPressed(Keys.S))
            vecInputCamera.y -= moveSensitivity;
        if (Gdx.input.isKeyPressed(Keys.A))
            vecInputCamera.x -= moveSensitivity;
        if (Gdx.input.isKeyPressed(Keys.D))
            vecInputCamera.x += moveSensitivity;

        if (Gdx.input.isKeyPressed(Keys.R)) {
            vecCamera.set(new Vector2());
            lockToSprite = false;
        }

        if (vecInputCamera.len2() != 0)
            lockToSprite = false;
        else if (Gdx.input.isKeyPressed(Keys.L))
            lockToSprite = true;

        if (lockToSprite) {
            vecCamera.set(vecSprite);
        } else {
            vecCamera.add(vecInputCamera);
        }

        vecSprite.add(vecInputSprite);

        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        background.draw(batch);
        sprite.setPosition(vecSprite.x, vecSprite.y);
        sprite.draw(batch);
        //batch.draw(sprite, vecSprite.x, vecSprite.y);
        batch.end();
    }

    @Override
    public void resize(int width, int height) {
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }
}

昌砚
2023-03-14

问题是SpriteBatch投影矩阵未设置为摄影机投影矩阵。这意味着精灵不会相对于相机进行渲染。这就是为什么相机在移动,而精灵没有;未使用正确的矩阵。

此外,精灵始终以屏幕宽度的一半和高度的一半进行渲染。来修复这个呼叫精灵。画这将使用精灵的内部位置。

通过批处理设置SpriteBatch投影矩阵。setProjectionMatrix(camera.combined)。这将导致精灵相对于相机进行渲染。

@Override
public void render(float delta) {
    translateCamera();

    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    camera.update();

    renderer.setView(camera);

    renderer.render(bgLayers);

    //here's the line that was missing.
    batch.setProjectionMatrix(camera.combined);
    batch.begin();

    //be sure to call this instead of specifying position yourself!
    splayerSprite.draw(batch);
    batch.end();
    renderer.render(fgLayers);

}

当按下WASD时,您仍然需要处理将相机的位置捕捉到精灵的位置,但这很琐碎。

//snap the camera to the sprite's center.
if(wasd_isDown){
    float centerX = sprite.getX()+sprite.getWidth()/2;
    float centerY = sprite.getY()+sprite.getHeight()/2;
    camera.position.set(x,y, 0);
}

如果按下方向键,只需通过Vector3平移相机的位置向量。加上:

if(!wasd_isDown){
    float deltaX = 0;
    float deltaY = 0;
    float MOVE_DIST = 10;//or whatever you need.

    if(leftPressed) deltaX = -MOVE_DIST;
    else if(rightPressed) deltaX = MOVE_DIST;

    if(upPressed)deltaY = MOVE_DIST;
    else if(downPressed)deltaY = -MOVE_DIST;

    camera.position.add(deltaX, deltaY, 0);
}

这将允许相机仅在玩家使用方向键时独立移动,并允许角色相对于相机的方向进行渲染。当按下WASD时,它还会立即将相机捕捉回角色。

 类似资料:
  • 我正在尝试在Android上显示谷歌地图。当我加载活动时,我会看到一个灰色屏幕,左下角显示的是Google徽标。使用虚拟仿真器和真实设备也会发生这种情况。我试过使用不同的Api键,但得到同样的问题。我正在使用Android Studio提供的地图活动。 Build.Gradle(模块:应用程序) AndroidManifest.xml Logcat处于错误模式

  • 当我在基于pygame的游戏中使用精灵时,它们似乎不能正常工作——正如你在屏幕截图上看到的那样,它们的形状不正确,并且上部有一些奇怪的变形。 黑色方块顶部有变形;中间的精灵一定是箭头形状的东西。 加载图像时涉及的一段代码(从pygame的教程中复制粘贴): 我在MacOSX上的Python2.7.11和3.4.2上做了我的项目,发现了这个问题。但当我在Windows上的Python3.1上测试它时

  • 这可能是我处理布局的方式有问题。对Java和Android软件开发工具包来说有点新鲜。我正在使用Android Studio。 我在这一点上的目标是有一个应用程序,屏幕底部显示一个带有图标的导航栏,顶部有一个带有“关闭”按钮和“保存”按钮的工具栏。工具栏和导航栏之间应该是一个空白的白色屏幕。 但是我很难让工具栏停留在屏幕的顶部。灰色背景占据了白色背景前面的整个屏幕。下面是截图。 这是我所知道的:

  • 我一直在努力跟进https://github.com/airbnb/react-native-maps教程我尝试了他们说的一切,但在我的android studio模拟器上得到了一个空白屏幕。 我的代码: AndroidManifest。xml文件:

  • 在过去一周左右的时间里,我一直在开发一款太空入侵者类型的游戏,它进展得非常顺利,但由于某种原因,当我在我的Windows电脑上运行游戏时(我更喜欢在它上面编写代码),大多数精灵都不会出现,或者只有当它们在屏幕上朝某个方向移动时才会出现。当我在Mac上运行完全相同的代码时,一切都会完美地闪烁和更新。这是pygame无法与Windows相处的已知问题吗?事实上,我的Mac电脑上的一切都正常工作,这让我

  • 我想让应用程序像“简易屏幕录制器”。我必须从哪里开始,因为我搜索了很多,但没有找到任何开始的链接。有任何用于创建屏幕录制器的api,而不是屏幕截图。我不想使用javacv从屏幕截图创建视频。我只想让用户启动应用程序,点击开始录制按钮,然后用户在手机上所做的一切来录制这些内容。 1) Android系统中是否有相关的api。 2) 如何在android中创建屏幕录制器应用程序。 3)是没有任何api