Использование обычных фигур libgdx с фигурами box2d

Прежде чем я решил, что хочу использовать box2d для всей своей игровой физики, я настроил все неанимированные формы с помощью shaperenderer. Я преобразовал свой мир и форму box2d в метры с масштабом 32 ppm, но все мои обычные формы по-прежнему нарисованы с помощью пикселей.

Поскольку мой круг box2d был масштабирован вместе с камерой, он отлично отображается с нужным размером. Однако все фигуры, которые я нарисовал с помощью пикселей с помощью shaperenderer, находятся вне поля зрения.

  1. Нужно ли мне переделывать все мои исходные формы с помощью фигур box2d?
  2. Могу ли я просто масштабировать все исходные формы с помощью масштабирования PPM?

Насколько я понимаю, я должен иметь возможность просто масштабировать все размеры исходных форм с помощью PPM, поскольку я уже масштабировал камеру?

public class Controller extends Game {
    public OrthographicCamera cam;
    public ShapeRenderer shape;
    public ShapeRenderer circle;
    public FitViewport viewport;
    public Stage stage;

    public World world;
    public Body ball;
    public Box2DDebugRenderer box2DDebugRenderer;

  @Override
  public void create() {
    cam = new OrthographicCamera();
    viewport = new FitViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), cam);
    cam.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    shape = new ShapeRenderer();
    circle = new ShapeRenderer(); //balls shot from cannon

    world = new World(new Vector2(0, 0), true);
    box2DDebugRenderer = new Box2DDebugRenderer();

    setScreen(new GameScreen(this));
    //setScreen(new TitleScreen(this));
}

@Override
public void dispose() {
    shape.dispose();
    stage.dispose();
    circle.dispose();
    box2DDebugRenderer.dispose();
    world.dispose();
}

@Override
public void pause() {
}

@Override
public void resume() {
}

@Override
public void resize(int width, int height) {
    viewport.update(width, height);
}

public Body createBall(){
    Body bBody;
    BodyDef def = new BodyDef();
    def.type = BodyDef.BodyType.DynamicBody;
    def.position.set(500,500);
    def.fixedRotation = true;
    bBody = world.createBody(def);

    return bBody;
}
}

А вот фактический экран игры, на котором реализованы все исходные формы и формы box2d:

import static com.mygdx.game.Utils.Constants.PPM;

public class GameScreen extends ScreenAdapter {
Controller game;

//x-axis length for top/bottom bar
private float goalWidth;

//y-axis height for back bar
private float goalHeight;
private float goalPostThickness;

//Screen height and width
private float screenWidth;
private float screenHeight;

//How far down/up posts are from edge of screen
private float goalPostTopOffset;
private float goalPostBottomOffset;

private float cannonOriginX; //Variables used for starting position of balls
private float cannonOriginY;

float ballX;
float ballY;

public GameScreen (Controller game){
    this.game = game;
}

@Override
public void show(){
    game.ball = game.createBall();
    // Create a circle shape and set its radius to 6
    CircleShape circle = new CircleShape();
    circle.setRadius(32/2/PPM);

// Create a fixture definition to apply our shape to
    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = circle;
    fixtureDef.density = 0.5f;
    fixtureDef.friction = 0.4f;
    fixtureDef.restitution = 0.6f; // Make it bounce a little bit

// Create our fixture and attach it to the body
    Fixture fixture = game.ball.createFixture(fixtureDef);

    circle.dispose();
}

@Override
public void render(float delta){
    //Logic
    screenWidth = Gdx.graphics.getWidth();
    screenHeight = Gdx.graphics.getHeight();

    goalPostTopOffset = screenHeight/7;
    goalPostBottomOffset = goalPostTopOffset * 3;
    goalHeight = screenHeight - (goalPostTopOffset + goalPostBottomOffset);
    goalWidth = screenWidth / 6;
    goalPostThickness = screenWidth / 75;

    cannonOriginX = goalWidth / 2; //Variables used for starting position of balls
    cannonOriginY = (goalPostThickness*5) / 2;

    ballX = 0 + cannonOriginX;
    ballY = (goalPostBottomOffset - (goalPostBottomOffset / 4)) + cannonOriginY;

    game.world.step(1/60f, 6, 2);

    //Draw
    game.cam.update();
    Gdx.gl.glClearColor(0, 0, 0, 0);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    game.box2DDebugRenderer.render(game.world, game.cam.combined.scl(PPM));
    game.shape.setProjectionMatrix(game.cam.combined);

    drawNonAnimated();
    drawAnimated();



}

@Override
public void hide(){

}

//draws stationary objects such as goal posts
public void drawNonAnimated(){
    //Top goal bar
    game.shape.setColor(1, 1, 1, 1);
    game.shape.begin(ShapeRenderer.ShapeType.Filled);
    game.shape.rect(screenWidth - goalWidth, screenHeight - goalPostTopOffset, goalWidth, goalPostThickness);
    game.shape.end();

    //Bottom goal bar
    game.shape.setColor(1, 1, 1, 1);
    game.shape.begin(ShapeRenderer.ShapeType.Filled);
    game.shape.rect(screenWidth - goalWidth, goalPostBottomOffset, goalWidth, goalPostThickness);
    game.shape.end();

    //Back goal bar
    game.shape.setColor(1, 1, 1, 1);
    game.shape.begin(ShapeRenderer.ShapeType.Filled);
    game.shape.rect(screenWidth - goalPostThickness, goalPostBottomOffset, goalPostThickness, goalHeight);
    game.shape.end();

    //Cannon platform
    game.shape.setColor(1, 1, 1, 1);
    game.shape.begin(ShapeRenderer.ShapeType.Filled);
    game.shape.rect(0, goalPostBottomOffset - (goalPostBottomOffset / 4),goalWidth, goalPostThickness*2);
    game.shape.end();

    //Cannon
    game.shape.setColor(1, 1, 1, 1);
    game.shape.begin(ShapeRenderer.ShapeType.Filled);
    game.shape.rect(0, goalPostBottomOffset - (goalPostBottomOffset / 4), cannonOriginX,
            cannonOriginY, goalWidth, goalPostThickness*5, 1, 1, 45);
    game.shape.end();
}

public void drawAnimated(){
    //Ball(s)
        game.circle.setColor(1, 1, 1, 1);
        game.circle.begin(ShapeRenderer.ShapeType.Filled);
        game.circle.circle(ballX, ballY, goalPostThickness * 2.5f);
        game.circle.end();
        game.cam.update();

        ballX += 1;
}



}

Как я упоминал ранее, форма круга, визуализированная с помощью box2d, отлично отображается в масштабе PPM. Однако все фигуры, которые я нарисовал с помощью shaperenderer, находятся за пределами экрана.

Я не собираюсь отвечать на ваш вопрос, потому что у меня нет опыта работы с box2d, но я рекомендую вам не беспокоиться о масштабировании всего до размера экрана. Я рекомендую вам поместить все, что вы хотите визуализировать, на сцену, а затем использовать ExtendsViewport, чтобы вам не приходилось беспокоиться о масштабировании, потому что это Viewport всегда будет иметь одинаковую высоту или одинаковую ширину. Если вы используете FitViewport, я считаю, что он всегда будет отображать одно и то же, независимо от разрешения. Есть много окон просмотра, которые вы можете использовать, чтобы упростить себе задачу.

retodaredevil 29.12.2018 17:54

Спасибо за ответ. Я использую fitviewport, но проблемы с масштабированием все еще возникают. Окно просмотра решало проблемы с разным соотношением сторон между устройствами, но объекты в моей игре по-прежнему рендерились слишком большими / слишком маленькими. Это было проблемой, так как игра становилась очень простой / сложной с объектами разного размера. Не уверен, что так должно быть, и я просто сделал что-то не так.

Nick Hudson 30.12.2018 00:33

Одна из возможностей - Constants.PPM. Если это как-то изменится, это может быть проблемой. (Если это общедоступный статический финал, все должно быть в порядке). Еще вы можете использовать высоту и ширину экрана для определения размеров и прочего. Вы можете попробовать сделать это другим способом, например, используя ограничивающую рамку, которая не меняет и не использует константы ширины и высоты, которые вы передаете в ExtendsViewport. Уловка состоит в том, чтобы никогда не использовать Gdx.graphics.getWidth () или getHeight () для чего-то, кроме пользовательского интерфейса или чего-то, что не влияет на игровой процесс.

retodaredevil 30.12.2018 01:18

Кроме того, если вы используете сцену, вам не нужно хранить экземпляр камеры или области просмотра. Вы всегда можете выполнить stage.getViewport (). GetCamera (), если вам это нужно.

retodaredevil 30.12.2018 01:21
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
155
0

Другие вопросы по теме