2014-09-28 4 views
3

Box2D를 사용하여 게임을 프로그래밍하려고 할 때 Box2D에서 문제가 발생했습니다. 텍스처와 스프라이트의 길이에 대한 픽셀 수를 채워 상자 주위에 상자를 만들었습니다. 모든 것이 올바른 위치에 있었지만 어떤 이유로 모든 것이 아주 천천히 진행되었습니다. 인터넷에서 보면 픽셀을 미터로 변환하지 않으면 box2d가 매우 큰 객체로 도형을 처리 할 수 ​​있다는 것을 알았습니다. 이것은 모든 것이 천천히 움직이는 논리적 인 원인으로 보였다.Libgdx Box2D 픽셀 - 미터 변환?

이 사이트에서 비슷한 질문을 발견했지만 답변이 도움이되지 못했습니다. 대부분의 경우 솔루션은 스케일링 요소를 사용하여 픽셀 수를 미터로 변환하는 방법을 만드는 것이 었습니다. 나는 이것을 시험해 보았지만 모든 것이 잘못되어 크기가 틀렸다. 이것은 숫자가 바뀌었지만 그 의미가 같았 기 때문에 나에게 논리적으로 보였다.

픽셀 수를 줄이는 방법이 있는지 궁금 해서요. 모든 것이 같은 (픽셀) 크기로 같은 위치에 있지만, 평균 미터가 더 낮습니다. 당신은 당신이 도움이 될 생각하는 다른 방법이있는 경우 , 나는 또한 이것은

 width = Gdx.graphics.getWidth()/5; 
     height = Gdx.graphics.getHeight()/5; 

     camera = new OrthographicCamera(width, height); 
     camera.setToOrtho(false, 1628, 440); 
     camera.update(); 

카메라를 내가하는 데 사용하는 방법을 만드는 데 사용할 여기

코드입니다 .. 그것을 듣고 싶어 whould

Table = new Item(); 
    Table.Create(372f, 60f, 152f, 96f, 1.0f, 0.2f, 0.2f, world); 
:

public void Create(float X, float Y, float Width, float Height, float density, float friction, float restitution, World world){ 
    //Method to create an item 
    width = Width; 
    height = Height; 

    polygonDef = new BodyDef(); 
    polygonDef.type = BodyType.DynamicBody; 
    polygonDef.position.set(X + (Width/2f), Y + (Height/2f)); 

    polygonBody = world.createBody(polygonDef); 

    polygonShape = new PolygonShape(); 
    polygonShape.setAsBox(Width/2f, Height/2f); 

    polygonFixture = new FixtureDef(); 
    polygonFixture.shape = polygonShape; 
    polygonFixture.density = density; 
    polygonFixture.friction = friction; 
    polygonFixture.restitution = restitution; 

    polygonBody.createFixture(polygonFixture); 
} 

이 경우 테이블에, 나는 다음과 같은 사용 항목을 만들려면 : 객체를 생성

스프라이트는 다음 방법을 사용하여 항목을 인출되어

public void drawSprite(Sprite sprite){ 
    polygonBody.setUserData(sprite); 
    Utils.batch.begin(); 
    if(polygonBody.getUserData() instanceof Sprite){ 
     Sprite Sprite = (Sprite) polygonBody.getUserData(); 
     Sprite.setPosition(polygonBody.getPosition().x - Sprite.getWidth()/2, polygonBody.getPosition().y - Sprite.getHeight()/2); 
     Sprite.setRotation(polygonBody.getAngle() * MathUtils.radiansToDegrees); 
     Sprite.draw(Utils.batch); 
    } 
    Utils.batch.end(); 
} 

스프라이트 또한 화소 사이즈를 갖는다.

이 방법을 사용하면 이미지가 올바른 위치에 표시되지만 모든 것이 천천히 움직입니다. 개체를 올바르게 이동하고/또는 의미가 적어 지도록 변경해야하는 경우 어떻게하는지 궁금합니다. 미리 감사드립니다.

답변

7

Box2D는 사용하는 그래픽 라이브러리와 완전히 독립적입니다. 스프라이트와 텍스쳐에 대한 개념이 없습니다. 온라인으로 읽은 내용이 정확하면 Box2D가 미터 (거리의 표준 단위)와 함께 작동하므로 픽셀을 미터로 변환해야합니다.

예를 들어 크기가 100x100 픽셀 인 스프라이트를 그린 경우 사용자가 화면에서 보게하려는 스프라이트의 크기입니다. 현실 세계에서 객체의 크기는 픽셀 단위가 아니라 미터 단위 여야합니다. 따라서 1px = 1m이라고 말하면 스프라이트를 거대한 100x100 미터 객체에 매핑합니다. Box2D에서 큰 세계 오브젝트는 계산 속도를 늦 춥니 다. 그래서 당신이해야 할 일은 100 픽셀을 더 작은 미터, 즉 1 미터로 매핑하는 것입니다. 따라서 100x100px 스프라이트는 Box2D 세계에서 1x1 미터 객체로 표현 될 것입니다.

Box2D는 매우 작은 숫자와 매우 큰 숫자에서는 제대로 작동하지 않습니다. 따라서 성능을 높이려면 0.5와 100 사이로 유지하십시오.

편집 : 확인. 이제 네 질문을 받는다. 픽셀을 코딩하지 마십시오. 그것만큼 간단합니다. 나는 이것을 이해하는 데 시간이 좀 걸릴 것이라는 것을 안다. 그러나 일단 당신은 그것의 걸림 새를, 그것의 똑 바른 앞으로 얻는다. 픽셀 대신 단위를 사용합니다. 예를 들어 미터라고 부릅니다. 그래서 우리는 뷰포트가 6mx5m이라고 말해야한다고 결정했습니다.

그래서 초기화는 실제 폭과 높이를 알게되면

Constants.VIEWPORT_WIDTH = 6; 
Constants.VIEWPORT_HEIGHT = 5; 
... 

void init() { 
    camera = new OrthographicCamera(Constants.VIEWPORT_WIDTH, Constants.VIEWPORT_HEIGHT); 
    camera.position.set(Constants.VIEWPORT_WIDTH/2, Constants.VIEWPORT_HEIGHT/2, 0); 
    camera.update(); 
} 

, 당신은 가로 세로 비율을 유지하기 위해 다음과 같은 함수를 호출 할 수 있습니다 : 언제든지 변경

public void resize(int width, int height) { 
     camera.viewportHeight = (Constants.VIEWPORT_WIDTH/width) * height; 
     camera.update(); 
} 

resize()를 호출 할 수 있습니다 화면 크기 (예 : 화면 방향 변경 화면). resize()은 픽셀 값 인 실제 너비와 높이 (320x480 등)를 사용합니다.

이제 스프라이트 크기와 위치 등을 6x5 크기의 새로운 세계에서 지정합니다. 픽셀을 잊을 수 있습니다. 화면을 채울 스프라이트의 최소 크기는 6x5입니다.

이제 Box2D에서 같은 장치를 사용할 수 있습니다. 새로운 차원이 작아지기 때문에 Box2D에서는 문제가되지 않습니다. 제대로 기억한다면 Box2D에는 유닛이 없습니다. 편의상 미터라고 부릅니다.

이제 창의 크기를 지정하십시오. 플랫폼에 따라 다릅니다. 다음 코드는 320 × 480 윈도우 바탕 화면 게임을 보여줍니다

public class Main { 
    public static void main(String[] args) { 
     LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration(); 
     cfg.title = "my-game"; 
     cfg.useGL20 = false; 
     cfg.width = 480; 
     cfg.height = 320; 

     new LwjglApplication(new MyGame(), cfg); 
    } 
} 

우리의 카메라가 지능적으로 480x320을에 6x5 뷰포트를 매핑합니다.

+0

고맙습니다. 그렇게하고 싶다면 픽셀을 다른 수의 미터에 매핑해야합니까? 어떻게해야합니까? (항목을 만들고 질문에 스프라이트를 그리는 데 사용 된 코딩이 포함되어 있습니다) – dragonfly

+0

내 대답을 편집했습니다. – sinu

+0

고마워, 나는 그것을 올바르게 보이게하는 방법을 이미 알아 냈지만 스프라이트의 위치를 ​​전체 화면으로 변환해야만 모든 것이 올바른 위치에있는 것처럼 보이지만 실제 시뮬레이션은 더 낮은 위치에 있었다. 왼쪽 구석. 이것은 더 나은 아이디어 인 것 같다. – dragonfly