2017-05-11 3 views
0

주인공에 빛이 있고 그곳에 빛이 도달하지 않는 곳이 어두울 때 libgdx에서 게임을 만들고 있는데, 나는 빛을 에뮬레이트하기 위해 SpriteBash의 setBlendFunction을 사용하고 있습니다. 내 문제는 빛의 질감을 모두 어둡게 만드는 방법을 모르겠다. 전체 화면에 맞게 가벼운 텍스처의 크기를 조정할 수는 있지만 코드가 부주의하고 코드에 불편을 겪을 수있다. 누구든지 아이디어가 있습니까? 감사합니다. 여기 LibGDX에서 텍스처를 그리는 방법?

내 문제는 귀하의 요구에 대한 Box2dlight를 사용하지 말자 왜

enter image description here

답변

0

통상, 프레임 버퍼로 이루어진다.

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

굉장!. 일이 완벽 해, 고마워. – Joao

0

을 보여주는 게임의 사진입니다. 제 생각에는 조명을위한 쉐이더를 사용할 수 있지만 원하는 효과는 box2d 본문과 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

관련 문제