繁体   English   中英

如何在LibGDX中绘制纹理?

[英]How to draw around a texture in LibGDX?

我正在libgdx中制作一个游戏,其中主角对他有灯光,而没有到达的灯光应该是暗的,我正在使用SpriteBash中的setBlendFunction来模拟灯光。 我的问题是我不知道如何使整个浅色纹理变暗,我可以调整浅色纹理的大小以适合整个屏幕,但这会很草率,并且给代码带来不便。 有人有什么想法吗? 谢谢。

这是显示我的问题的游戏图片

在此处输入图片说明

您为什么不使用Box2dlight满足您的要求。 我认为可以将着色器用于照明,但是只能通过使用box2d body和box2dlight来实现所需的效果。

public class MyGdxGame extends ApplicationAdapter implements InputProcessor{

    SpriteBatch batch;
    OrthographicCamera cam;

    RayHandler rayHandler;
    World world;
    Texture texture;
    PointLight box2d;

    Box2DDebugRenderer renderer;
    Vector3 vector3;
    Array<Body> bodies;

    @Override
    public void create() {

        Pixmap pixmap=new Pixmap(1, 1, Pixmap.Format.RGBA8888);
        pixmap.setColor(Color.WHITE);
        pixmap.fillRectangle(0,0, pixmap.getWidth(), pixmap.getHeight());

        world=new World(new Vector2(0,-9.8f),false);
        rayHandler=new RayHandler(world);

        renderer=new Box2DDebugRenderer();
        bodies=new Array<>();
        vector3=new Vector3();

        batch=new SpriteBatch();
        cam = new OrthographicCamera();
        cam.setToOrtho(true,40,64);

        texture=new Texture(pixmap);
        rayHandler.setAmbientLight(0,0,0,.5f);

        box2d=new PointLight(rayHandler, 100, new Color(1,1,1,1), 25, 10, 10);
        Gdx.input.setInputProcessor(this);


        {
            BodyDef bodyDef = new BodyDef();
            bodyDef.position.set(20, 10);
            bodyDef.type = BodyDef.BodyType.StaticBody;

            PolygonShape p = new PolygonShape();
            p.setAsBox(8, 1.5f);

            FixtureDef fixtureDef = new FixtureDef();
            fixtureDef.shape = p;

            Body body = world.createBody(bodyDef);
            body.createFixture(fixtureDef);

            Sprite sprite=new Sprite(texture);
            sprite.setSize(8*2,1.5f*2);
            body.setUserData(sprite);
        }

        {
            BodyDef bodyDef = new BodyDef();
            bodyDef.position.set(20, 40);
            bodyDef.type = BodyDef.BodyType.StaticBody;

            PolygonShape p = new PolygonShape();
            p.setAsBox(8, 1.5f);

            FixtureDef fixtureDef = new FixtureDef();
            fixtureDef.shape = p;

            Body body = world.createBody(bodyDef);
            body.createFixture(fixtureDef);

            Sprite sprite=new Sprite(texture);
            sprite.setSize(8*2,1.5f*2);

            body.setUserData(sprite);
        }
    }

    @Override
    public void render() {

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

        world.step(1/60f,4,6);

        renderer.render(world,cam.combined);
        batch.setProjectionMatrix(cam.combined);

        batch.begin();
        world.getBodies(bodies);

        for (Body body:bodies){
            Sprite sprite=(Sprite) body.getUserData();
            sprite.setPosition(body.getPosition().x-sprite.getWidth()/2,body.getPosition().y-sprite.getHeight()/2);
            sprite.draw(batch);
        }

        batch.draw(texture,100,100);
        batch.end();

        rayHandler.setCombinedMatrix(cam);
        rayHandler.updateAndRender();
    }

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

    }

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

    @Override
    public boolean keyDown(int keycode) {
        return false;
    }

    @Override
    public boolean keyUp(int keycode) {
        return false;
    }

    @Override
    public boolean keyTyped(char character) {
        return false;
    }

    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
        return false;
    }

    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button) {
        return false;
    }

    @Override
    public boolean touchDragged(int screenX, int screenY, int pointer) {

        vector3.set(screenX,screenY,0);
        Vector3 v=cam.unproject(vector3);
        box2d.setPosition(v.x,v.y);
        return false;
    }

    @Override
    public boolean mouseMoved(int screenX, int screenY) {
        return false;
    }

    @Override
    public boolean scrolled(int amount) {
        return false;
    }
}

输出是:

在此处输入图片说明

通常使用FrameBuffer完成此操作。

您想在resize()方法中根据需要实例化并重新创建,以便它始终与屏幕/窗口的大小匹配。 resize()

if (frameBuffer != null && (frameBuffer.getWidth() != width || frameBuffer.getHeight() != height)){
    frameBuffer.dispose();
    frameBuffer = null;
}
if (frameBuffer == null){
    try {
        frameBuffer = new FrameBuffer(Pixmap.Format.RGBA8888, width, height, false);
    } catch (GdxRuntimeException e){ // device doesn't support 8888
        frameBuffer = new FrameBuffer(Pixmap.Format.RGB565, width, height, false);
    }
}

然后在render() ,在游戏中绘制任何东西之前,首先在frameBuffer上绘制阴影贴图:

frameBuffer.begin();
Gdx.gl.glClearColor(/* ... */); // This will be your ambient color, a dark color, like gray
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

spriteBatch.setProjectionMatrix(camera.combined); // same camera as your game scene
spriteBatch.setBlendFunction(GL20.GL_ONE, GL20.GL_ONE); //additive blending
spriteBatch.begin();

// draw light sprites, such as a white circle where your character is standing

spriteBatch.end();
frameBuffer.end();

然后正常绘制游戏场景。 绘制之前,请不要忘记将混合功能更改回通常使用的功能(默认为GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)。 最后,在游戏上绘制阴影图:

// Use identity matrix so you don't have to worry about lining up the frame buffer texture
spriteBatch.setProjectionMatrix(spriteBatch.getProjectionMatrix().idt());

// Set multiplicative blending for shadows
spriteBatch.setBlendFunction(GL20.GL_ZERO, GL20.GL_SRC_COLOR); 

spriteBatch.begin();
spriteBatch.draw(frameBuffer.getColorBufferTexture(), -1, 1, 2, -2); //dimensions for full screen with identity matrix
spriteBatch.end();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM