我尝试玩一下灯光,但很快我就发现了我不理解的奇怪行为。谁能向我解释一下为什么会发生这种情况,如果是故意的,或者我做错了什么。
在第一张图片中,光线几乎穿过障碍物(这也很奇怪)。
当屏幕尺寸更改为更窄的宽度时,光线会更多地穿过障碍物。
红色背景是“黑条”,因为我使用FitViewport。 “真实”世界到处都是 badlogic.jpg。
在接下来的图片中,您可以看到它在没有光渲染的情况下如何工作 - 无论屏幕尺寸如何(仅缩放),屏幕都会渲染相同的世界。这就是我期望它即使在有照明的情况下也能工作的方式。
该项目是标准的,由libgdx项目生成器生成。我所有的代码只是一个类,所以我可以在这里上传:
package com.gobanit.sandbox.main;
import com.badlogic.ashley.core.Engine;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
import box2dLight.PointLight;
import box2dLight.RayHandler;
public class SandboxTestGame extends ApplicationAdapter {
SpriteBatch batch;
World world;
Engine engine;
Viewport viewport;
Box2DDebugRenderer debugRenderer;
Texture texture;
RayHandler rayHandler;
Body playerBody;
@Override
public void create () {
batch = new SpriteBatch();
texture = new Texture(Gdx.files.internal("badlogic.jpg"));
engine = new Engine();
world = new World(new Vector2(0, 0), true);
viewport = new FitViewport(1000, 500);
viewport.getCamera().position.set(new Vector3(0, 0, 0));
debugRenderer = new Box2DDebugRenderer();
rayHandler = new RayHandler(world);
rayHandler.setShadows(true);
createPlayerBody();
createObstacleBody();
PointLight l1 = new PointLight(rayHandler, 100, null, 500, 0, 0);
l1.attachToBody(playerBody);
//l1.setSoft(true);
//new PointLight(rayHandler, 100, null, 500, 0, 200);
}
private void createObstacleBody() {
BodyDef bodyDef = new BodyDef();
bodyDef.position.add(new Vector2(-10000, 100));
bodyDef.type = BodyType.StaticBody;
Body body = world.createBody(bodyDef);
FixtureDef fixDef = new FixtureDef();
PolygonShape shape = new PolygonShape();
shape.set(new float[] {0f,0f,0f,40f,20000f,40f,20000f,0f});
fixDef.shape = shape;
body.createFixture(fixDef);
body.setActive(true);
}
private void createPlayerBody() {
BodyDef bodyDef = new BodyDef();
bodyDef.position.add(new Vector2(100, 50));
bodyDef.type = BodyType.DynamicBody;
Body body = world.createBody(bodyDef);
FixtureDef fixDef = new FixtureDef();
CircleShape circle = new CircleShape();
circle.setRadius(20);
fixDef.shape = circle;
body.createFixture(fixDef);
body.setActive(true);
playerBody = body;
}
@Override
public void render () {
update();
draw();
}
private void draw() {
Gdx.gl.glClearColor(100, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
viewport.update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch.setProjectionMatrix(viewport.getCamera().combined);
batch.begin();
batch.draw(texture, -1000, -1000, 2000, 2000);
batch.end();
debugRenderer.render(world, viewport.getCamera().combined);
rayHandler.setCombinedMatrix((OrthographicCamera) viewport.getCamera());
rayHandler.render();
}
private void update() {
world.step(1f/60f, 8, 3);
rayHandler.update();
if(Gdx.input.isKeyPressed(Keys.D)) {
//viewport.getCamera().position.add(new Vector3(1,0,0));
playerBody.applyForceToCenter(100, 0, true);
}
if(Gdx.input.isKeyPressed(Keys.A)) {
//viewport.getCamera().position.add(new Vector3(-1,0,0));
playerBody.applyForceToCenter(-100, 0, true);
}
if(Gdx.input.isKeyPressed(Keys.W)) {
//viewport.getCamera().position.add(new Vector3(0,1,0));
playerBody.applyForceToCenter(0, 100, true);
}
if(Gdx.input.isKeyPressed(Keys.S)) {
//viewport.getCamera().position.add(new Vector3(0,-1,0));
playerBody.applyForceToCenter(0, -100, true);
}
viewport.getCamera().position.set(new Vector3(playerBody.getPosition().x, playerBody.getPosition().y, 0));
}
@Override
public void dispose () {
batch.dispose();
texture.dispose();
world.dispose();
debugRenderer.dispose();
rayHandler.dispose();
}
}
非常感谢。如果需要更多信息,请告诉我,我将编辑问题。
确认@Mikhail Churbanov 所说的话并带来更多的知名度。文档提到我们有责任在调整大小时更新视口。我认为这是适合视口的点。我很困惑。
无论如何,我最终在 resize() 中使用了这个函数,如下所示:
if(viewport.getRightGutterWidth() > 0){
rayHandler.useCustomViewport(viewport.getRightGutterWidth()-5,viewport.getBottomGutterHeight()-5, (int)(height*SCREEN_RATIO)+10,height+10);
}else{
rayHandler.useCustomViewport(viewport.getRightGutterWidth()-5,viewport.getBottomGutterHeight()-5, width+10,(int)(width/SCREEN_RATIO)+10);
}
这样做给我带来了复杂的感觉。我不太相信这是这样做的方法,嘿,它有效!