2017-05-11 13 views
0

私はlibgdxで主人公のキャラクターに光が当たっていて、光が届かない場所は暗くなければなりません。私はSpriteBashのsetBlendFunctionを使ってライトをエミュレートしています。私の問題は、私がどのように明るいテクスチャの周囲を暗くすることができるか分からないということです。私はライトテクスチャのサイズを画面全体に合わせることができますが、それはコードが不便で不便なものになります。誰にもアイデアはありますか?ありがとうございます。ここでLibGDXでテクスチャを囲む方法は?

は、なぜあなたはあなたの条件のためBox2dlightを使用dont't私の問題

enter image description here

答えて

0

これは典型的にはフレームバッファで行われます。

resize()メソッドで必要に応じてインスタンス化して再作成し、常に画面/ウィンドウのサイズと一致するようにします。

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(); 

そして、通常、あなたのゲームシーンを描く:

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()で、あなたのゲームで何かを描画する前に、あなたは最初のフレームバッファ上のシャドウマップを描く:resize()で。描画する前に、ブレンド関数を通常どおりに使う(デフォルトでは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(); 
+0

恐ろしい!それは完全に動作します、ありがとう。 – Joao

0

を示すゲームの写真です。私の意見では、照明のためにシェーダを使うことができますが、あなたが望む効果は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; 
    } 
} 

出力は、次のとおりです。

enter image description here

+0

ありがとうございますが、私はbox2dを避けようとしています。 – Joao

+0

あなたの要件はbox2dを使用して簡単に実現できます。box2dは適切な方法で物理的なボディで遊ぶなら、あまりにも悪くないです。 – Aryan

+1

私は同意しますが、今は別のルートに行きます。答えてくれてありがとう。 – Joao

関連する問題