2017-05-11 4 views
0

Ich mache ein Spiel in libgdx, wo der Hauptcharakter ein Licht auf ihn hat und wo das Licht es nicht erreichen sollte dunkel sein sollte, verwende ich die setBlendFunction von SpriteBash, um das Licht zu emulieren. Mein Problem ist, dass ich nicht weiß, wie ich die gesamte Lichtstruktur dunkel machen kann. Ich könnte die Lichtstruktur auf den ganzen Bildschirm anpassen, aber das wäre schlampig und eine Unbequemlichkeit im Code. Hat jemand irgendwelche Ideen? Danke.Wie zeichne ich eine Textur in LibGDX?

ist hier ein Bild des Spiels

mein Problem zeigt

enter image description here

Antwort

0

Dies wird in der Regel mit einem Framebuffer getan.

Sie möchten instanziieren und neu erstellen wie erforderlich in der resize() Methode, damit es immer die Größe des Bildschirms/Fensters entspricht. In 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); 
    } 
} 

Und in render(), bevor irgendetwas in Ihrem Spiel zeichnen, zeichnen Sie zunächst die Schattenkarte auf den 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(); 

Dann normalerweise Ihre Spielszene zeichnen. Vergessen Sie nicht, Ihre Überblendungsfunktion wieder auf das zu ändern, was Sie normalerweise verwenden (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA standardmäßig), bevor Sie diese zeichnen. Und schließlich zeichne die Schattenkarte über das Spiel:

// 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(); 
+0

Ehrfürchtig !. Es funktioniert perfekt, danke. – Joao

0

Warum Sie für Ihre Anforderung verwenden Box2dlight dont't. Meiner Meinung nach kann man Shader für die Beleuchtung verwenden, aber der gewünschte Effekt kann nur erreicht werden, wenn box2d body und box2dlight verwendet werden.

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; 
    } 
} 

Ausgabe lautet:

enter image description here

+0

Danke, aber ich versuche zu vermeiden box2d. – Joao

+0

Ihre Anforderung kann mit box2d leicht erfüllt werden, box2d ist nicht schlecht, wenn Sie mit Physik Körper in der richtigen Weise spielen. – Aryan

+1

Ich stimme zu, aber jetzt gehe ich die andere Route. Danke für die Antwort. – Joao

Verwandte Themen