6
\$\begingroup\$

I'm creating a game that is similar to hill climb racing. I've generated the ground and now I want to add texture to the ground. Here is a screenshot of a gameenter image description here

Here is my code (I create ground using triginometry)

public class MyGdxGame extends ApplicationAdapter {
    private OrthographicCamera camera;
    private Box2DDebugRenderer renderer;
    private World world;
    private static final float width = 40;
    private static final float height = 30;
    private static final float camSpeed = 3.8f;
    private static final float SLICE_WIDTH = 2;
    private Body groundBody;
    private Body aa;
    private static final int PPM = 100;

    private EdgeShape slicePoly;
    private FixtureDef sliceFixture = new FixtureDef();

    float needToCreateStuff;

    private Car car;

    private QueryCallback deleteStuff = new QueryCallback() {
        @Override
        public boolean reportFixture(Fixture fixture) {
            final Body tmpBody = fixture.getBody();
            if (tmpBody == groundBody){
                groundBody.destroyFixture(fixture);
            }
            return true;
        }
    };

    @Override
    public void create() {
        renderer = new Box2DDebugRenderer();
        camera = new OrthographicCamera(width, height);
        camera.position.set(width / 2, 0, 0);
        camera.update();

        createPhysics();
    }

    @Override
    public void render() {
        update(Gdx.graphics.getDeltaTime());

        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        renderer.render(world, camera.combined);
    }

    private void update(float delta) {
        handleInput(delta);

        world.step(delta, 6, 2);

        final float posX = camera.position.x - width / 1.5f;
        final float posY = camera.position.y;
        world.QueryAABB(deleteStuff, posX, posY - height / 2f, posX + SLICE_WIDTH, posY + height / 2f);
    }

    private void handleInput(float dt){
        float cameraMovement = camSpeed * dt;
        camera.position.x += cameraMovement*1f;
        //camera.position.x = car.getBodyX() * dt;

        generateStuff(cameraMovement, true);
        if(Gdx.input.isKeyPressed(Input.Keys.Z)){
            camera.zoom += .01;
        } else if(Gdx.input.isKeyPressed(Input.Keys.X)){
            generateStuff(cameraMovement, false);
            camera.zoom -= .01;
        }
        //camera.update();
    }

    private void generateStuff(float cameraMovement, boolean direction){
        if(direction){
            needToCreateStuff += cameraMovement;
            if (needToCreateStuff > SLICE_WIDTH) {
                needToCreateStuff -= SLICE_WIDTH;
                createSlice(camera.position.x + width / 2f - needToCreateStuff);
            }
        }
        camera.update();
    }

    private void createPhysics() {
        world = new World(new Vector2(0, -8.91f), true);
        BodyDef bodyDef = new BodyDef();
        groundBody = world.createBody(bodyDef);

        aa = world.createBody(bodyDef);
        slicePoly = new EdgeShape();

        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.density = 5;
        fixtureDef.restitution = .3f;

        FixtureDef wheelFixtureDef = new FixtureDef();
        wheelFixtureDef.density = fixtureDef.density * 5.5f;
        wheelFixtureDef.friction = 0;
        wheelFixtureDef.restitution = .4f;

        car = new Car(world, fixtureDef, wheelFixtureDef, 0, 3, 3, 1.5f);
        Gdx.input.setInputProcessor(new InputMultiplexer(new InputAdapter(){}, car));

        for (float x = 0; x <= width; x += SLICE_WIDTH){
            createSlice(x);
        }
    }

    private float nextY;

    private void createSlice(float x) {
        float y = nextY;
        int high = 5;
        float nelygumas = 2 * x;
        float interval = 10 * x;
        nextY = 4f * MathUtils.sinDeg(nelygumas) + high * MathUtils.sinDeg(interval) * 1f;
        slicePoly.set(x, y, x + SLICE_WIDTH, nextY);
        sliceFixture.shape = slicePoly;
        sliceFixture.friction = 10;
        groundBody.createFixture(sliceFixture);
    }


    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void dispose() {
        slicePoly.dispose();
        world.dispose();
    }

    @Override
    public void resize(int width, int height) {
    }
}

EDIT: I need to use this texture enter image description here

\$\endgroup\$
  • \$\begingroup\$ There's a great question in here, it would be nice if you could clarify a little more: what do you want the texture to look like? It would be ideal if you could maybe use MS paint or some other drawing program to create a mock-up, and add it to your question. \$\endgroup\$ – NauticalMile Feb 13 '16 at 18:09
  • 1
    \$\begingroup\$ @NauticalMile I just have edited my post \$\endgroup\$ – user3334375 Feb 14 '16 at 7:41
  • \$\begingroup\$ Does anybody know how to do that? I'm searchning for a solution three days but still no answer. \$\endgroup\$ – user3334375 Feb 14 '16 at 21:46
  • \$\begingroup\$ It will probably involve the use of shaders; not something I've played around with before. I think it's a good question though, I'm not sure why it hasn't attracted more attention. \$\endgroup\$ – NauticalMile Feb 17 '16 at 0:43
  • \$\begingroup\$ I'm doing a project similar to yours, can I see your whole project, please? \$\endgroup\$ – Oscar Dimas Jun 6 '18 at 18:09
1
\$\begingroup\$

I think I found a way to do it ...but I'm sure there is a more efficent way to do it! 1) You draw the texture all over the things you see on the screen ( only where the camera points at.

2) Then you iterate trough each point of the fixture of the ground and generate a Polygonshape made of the first point , the point that comes after it, and two points which have the same x coordinates but higher y coordinates. At the end you'll have a lot of polygons which you can contain in an array.

3) you render all the shapes with a shaperenderer black so you cover the texture that is not drawn on the ground!

ps. Do this passages only for the things which are seen on the screen to gain efficency,processor time and to prevent from nullpointerexceptions!!!!!! You could do this by checking each time you generate a polygon if the first points x coordinate is inside the screen if it isnt you simply break out the loop!

Hope I was helpful and ask for more explanations if you need some help!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.