package net.caraus.labyrinth; import com.badlogic.gdx.ApplicationListener; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL32; import com.badlogic.gdx.graphics.PerspectiveCamera; import com.badlogic.gdx.graphics.VertexAttributes.Usage; import com.badlogic.gdx.graphics.g3d.Material; import com.badlogic.gdx.graphics.g3d.Model; import com.badlogic.gdx.graphics.g3d.ModelBatch; import com.badlogic.gdx.graphics.g3d.ModelInstance; import com.badlogic.gdx.graphics.g3d.attributes.BlendingAttribute; import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute; import com.badlogic.gdx.graphics.g3d.utils.MeshPartBuilder; import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import static com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.utils.ScreenUtils; public class Main implements ApplicationListener { public ModelBatch modelBatch; public Model model; public ModelInstance instance; public MazeInputProcessor camController; public ShapeRenderer shapeRenderer; public Maze maze; private static final float WALL_SIZE = 5; @Override public void create() { this.modelBatch = new ModelBatch(); this.shapeRenderer = new ShapeRenderer(); var cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); cam.position.set(0f, 0f, 0f); cam.lookAt(0, WALL_SIZE, 0); cam.near = 1f; cam.far = 300f; cam.update(); this.maze = new KruskalMaze(15, 9).generate(); this.camController = new MazeInputProcessor(this.maze, cam, WALL_SIZE); Gdx.input.setInputProcessor(camController); ModelBuilder worldBuilder = new ModelBuilder(); worldBuilder.begin(); for (var x = 0; x < this.maze.width(); ++x) { for (var y = 0; y < this.maze.height(); ++y) { buildLocation(worldBuilder, x, y); } buildLocation(worldBuilder, new Location(false, true), new Vector3(x * WALL_SIZE * 2, this.maze.height() * WALL_SIZE * 2, 0), String.format("lx%dy%d", x, this.maze.height())); } for (var y = 0; y < this.maze.height(); ++y) { buildLocation(worldBuilder, new Location(true, false), new Vector3(this.maze.width() * WALL_SIZE * 2, y * WALL_SIZE * 2, 0), String.format("lx%dy%d", this.maze.width(), y)); } buildFloor(worldBuilder); this.model = worldBuilder.end(); this.instance = new ModelInstance(this.model); } private static Vector3 makeTranslation(int x, int y) { return new Vector3(x * WALL_SIZE * 2, y * WALL_SIZE * 2, 0); } // Пол. private void buildFloor(ModelBuilder worldBuilder) { MeshPartBuilder meshBuilder = worldBuilder.part("floor", GL32.GL_TRIANGLES, Usage.Position | Usage.Normal, new Material(ColorAttribute.createDiffuse(Color.ORANGE))); var farX = -WALL_SIZE + this.maze.width() * WALL_SIZE * 2; var farY = -WALL_SIZE + this.maze.height() * WALL_SIZE * 2; meshBuilder.rect(new MeshPartBuilder.VertexInfo().setPos(-WALL_SIZE, -WALL_SIZE, -WALL_SIZE), new MeshPartBuilder.VertexInfo().setPos(farX, -WALL_SIZE, -WALL_SIZE), new MeshPartBuilder.VertexInfo().setPos(farX, farY, -WALL_SIZE), new MeshPartBuilder.VertexInfo().setPos(-WALL_SIZE, farY, -WALL_SIZE)); } private static void buildLocation(ModelBuilder worldBuilder, Location builtLocation, Vector3 translation, String partName) { var corner00 = new Vector3(); var corner10 = new Vector3(); var corner11 = new Vector3(); var corner01 = new Vector3(); MeshPartBuilder meshBuilder = worldBuilder.part(partName, GL32.GL_TRIANGLES, Usage.Position | Usage.Normal, new Material(new BlendingAttribute(0.9f))); if (builtLocation.leftWall()) { meshBuilder.rect(corner00.set(-WALL_SIZE, -WALL_SIZE, -WALL_SIZE).add(translation), corner10.set(-WALL_SIZE, WALL_SIZE, -WALL_SIZE).add(translation), corner11.set(-WALL_SIZE, WALL_SIZE, WALL_SIZE).add(translation), corner01.set(-WALL_SIZE, -WALL_SIZE, WALL_SIZE).add(translation), null); meshBuilder.rect(corner01.set(-WALL_SIZE, -WALL_SIZE, WALL_SIZE).add(translation), corner11.set(-WALL_SIZE, WALL_SIZE, WALL_SIZE).add(translation), corner10.set(-WALL_SIZE, WALL_SIZE, -WALL_SIZE).add(translation), corner00.set(-WALL_SIZE, -WALL_SIZE, -WALL_SIZE).add(translation), null); } if (builtLocation.upWall()) { meshBuilder.rect(corner00.set(-WALL_SIZE, -WALL_SIZE, -WALL_SIZE).add(translation), corner10.set(WALL_SIZE, -WALL_SIZE, -WALL_SIZE).add(translation), corner11.set(WALL_SIZE, -WALL_SIZE, WALL_SIZE).add(translation), corner01.set(-WALL_SIZE, -WALL_SIZE, WALL_SIZE).add(translation), null); meshBuilder.rect(corner01.set(-WALL_SIZE, -WALL_SIZE, WALL_SIZE).add(translation), corner11.set(WALL_SIZE, -WALL_SIZE, WALL_SIZE).add(translation), corner10.set(WALL_SIZE, -WALL_SIZE, -WALL_SIZE).add(translation), corner00.set(-WALL_SIZE, -WALL_SIZE, -WALL_SIZE).add(translation), null); } } private void buildLocation(ModelBuilder worldBuilder, int x, int y) { var translation = new Vector3(x * WALL_SIZE * 2, y * WALL_SIZE * 2, 0); buildLocation(worldBuilder, this.maze.at(x, y), translation, String.format("lx%dy%d", x, y)); } @Override public void render() { this.camController.update(); Gdx.gl.glClear(GL32.GL_COLOR_BUFFER_BIT | GL32.GL_DEPTH_BUFFER_BIT); ScreenUtils.clear(0.15f, 0.15f, 0.2f, 1f); Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); this.modelBatch.begin(this.camController.getCamera()); this.modelBatch.render(this.instance); this.modelBatch.end(); this.shapeRenderer.begin(ShapeType.Line); this.shapeRenderer.setColor(Color.BLUE); this.maze.draw(this.shapeRenderer); this.shapeRenderer.end(); } @Override public void dispose() { this.modelBatch.dispose(); this.model.dispose(); this.shapeRenderer.dispose(); } @Override public void resume() { } @Override public void resize(int width, int height) { } @Override public void pause() { } }