android - LibGDX में विभिन्न पहलू अनुपात से निपटने के लिए कैसे?




opengl-es aspect-ratio (5)

मैंने libGDX का उपयोग करके कुछ स्क्रीन लागू की हैं जो स्पष्ट रूप से libGDX ढांचे द्वारा प्रदान की गई Screen क्लास का उपयोग करती हैं। हालांकि, इन स्क्रीन के लिए कार्यान्वयन केवल पूर्व परिभाषित स्क्रीन आकार के साथ काम करता है। उदाहरण के लिए, यदि स्प्राइट 640 x 480 आकार स्क्रीन (4: 3 पहलू अनुपात) के लिए था, तो यह अन्य स्क्रीन आकारों के अनुसार काम नहीं करेगा क्योंकि स्प्राइट स्क्रीन सीमाओं के बराबर जाते हैं और स्क्रीन आकार में स्केल नहीं किए जाते हैं बिलकुल। इसके अलावा, यदि libgDX द्वारा सरल स्केलिंग प्रदान की गई थी, तो जिस मुद्दे का सामना कर रहा हूं वह अभी भी वहां रहेगा क्योंकि इससे गेम स्क्रीन के पहलू अनुपात में बदलाव आएगा।

इंटरनेट पर शोध करने के बाद, मैं एक blog/forum आया जिसने एक ही मुद्दे पर चर्चा की थी। मैंने इसे लागू किया है और अब तक यह ठीक काम कर रहा है। लेकिन मैं यह पुष्टि करना चाहता हूं कि यह हासिल करने का सर्वोत्तम विकल्प है या नहीं, बेहतर विकल्प हैं या नहीं। यह दिखाने के लिए कोड है कि मैं इस वैध समस्या से कैसे निपट रहा हूं।

फोरम लिंक: blog/forum

public class SplashScreen implements Screen {

    // Aspect Ratio maintenance
    private static final int VIRTUAL_WIDTH = 640;
    private static final int VIRTUAL_HEIGHT = 480;
    private static final float ASPECT_RATIO = (float) VIRTUAL_WIDTH / (float) VIRTUAL_HEIGHT;

    private Camera camera;
    private Rectangle viewport;
    // ------end------

    MainGame TempMainGame;

    public Texture splashScreen;
    public TextureRegion splashScreenRegion;
    public SpriteBatch splashScreenSprite;

    public SplashScreen(MainGame maingame) {
        TempMainGame = maingame;
    }

    @Override
    public void dispose() {
        splashScreenSprite.dispose();
        splashScreen.dispose();
    }

    @Override
    public void render(float arg0) {
        //----Aspect Ratio maintenance

        // update camera
        camera.update();
        camera.apply(Gdx.gl10);

        // set viewport
        Gdx.gl.glViewport((int) viewport.x, (int) viewport.y,
        (int) viewport.width, (int) viewport.height);

        // clear previous frame
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

        // DRAW EVERYTHING
        //--maintenance end--

        splashScreenSprite.begin();
        splashScreenSprite.disableBlending();
        splashScreenSprite.draw(splashScreenRegion, 0, 0);
        splashScreenSprite.end();
    }

    @Override
    public void resize(int width, int height) {
        //--Aspect Ratio Maintenance--
        // calculate new viewport
        float aspectRatio = (float)width/(float)height;
        float scale = 1f;
        Vector2 crop = new Vector2(0f, 0f);

        if(aspectRatio > ASPECT_RATIO) {
            scale = (float) height / (float) VIRTUAL_HEIGHT;
            crop.x = (width - VIRTUAL_WIDTH * scale) / 2f;
        } else if(aspectRatio < ASPECT_RATIO) {
            scale = (float) width / (float) VIRTUAL_WIDTH;
            crop.y = (height - VIRTUAL_HEIGHT * scale) / 2f;
        } else {
            scale = (float) width / (float) VIRTUAL_WIDTH;
        }

        float w = (float) VIRTUAL_WIDTH * scale;
        float h = (float) VIRTUAL_HEIGHT * scale;
        viewport = new Rectangle(crop.x, crop.y, w, h);
        //Maintenance ends here--
    }

    @Override
    public void show() {
        camera = new OrthographicCamera(VIRTUAL_WIDTH, VIRTUAL_HEIGHT); //Aspect Ratio Maintenance

        splashScreen = new Texture(Gdx.files.internal("images/splashScreen.png"));
        splashScreenRegion = new TextureRegion(splashScreen, 0, 0, 640, 480);
        splashScreenSprite = new SpriteBatch();

        if(Assets.load()) {
            this.dispose();
            TempMainGame.setScreen(TempMainGame.mainmenu);
        }
    }
}

अद्यतन: मुझे हाल ही में पता चला है कि libGDX में पहलू अनुपात बनाए रखने के लिए अपनी कुछ कार्यक्षमता है जिसे मैं यहां चर्चा करना चाहता हूं। इंटरनेट पर पहलू अनुपात के मुद्दे की खोज करते समय, मैं कई मंचों / डेवलपर्स में आया, जिनके पास "स्क्रीन स्क्रीन पर पहलू अनुपात को बनाए रखने के लिए" की समस्या थी? वास्तव में मेरे लिए काम करने वाले समाधानों में से एक ऊपर पोस्ट किया गया था।

बाद में जब मैंने स्क्रीन के लिए touchDown() विधियों को लागू करने के साथ आगे बढ़े, तो मैंने पाया कि आकार बदलने पर स्केलिंग के कारण, जिस समन्वय पर मैंने touchDown() लागू किया था, वह बड़ी मात्रा में बदल जाएगा। स्क्रीन आकार के अनुसार समन्वय का अनुवाद करने के लिए कुछ कोड के साथ काम करने के बाद, मैंने इस राशि को काफी हद तक कम कर दिया लेकिन मैं उन्हें पिन पॉइंट सटीकता के साथ बनाए रखने में सफल नहीं था। उदाहरण के लिए, यदि मैंने एक बनावट पर touchDown() लागू किया था, तो स्क्रीन का आकार बदलना आकार के आधार पर टच लिस्टनर को बनावट क्षेत्र पर कुछ पिक्सेल दाएं या बाएं स्थानांतरित कर देगा और यह स्पष्ट रूप से अवांछित था।

बाद में मुझे पता चला कि स्टेज क्लास की पहलू अनुपात ( boolean stretch = false ) को बनाए रखने के लिए अपनी मूल कार्यक्षमता है। अब जब मैंने स्टेज क्लास का उपयोग कर अपनी स्क्रीन लागू की है, तो पहलू अनुपात इसके द्वारा अच्छी तरह से बनाए रखा जाता है। हालांकि आकार बदलने या विभिन्न स्क्रीन आकारों पर, उत्पन्न होने वाला काला क्षेत्र हमेशा स्क्रीन के दाईं ओर दिखाई देता है; यह स्क्रीन केंद्रित नहीं है जो काला क्षेत्र काफी बड़ा है अगर यह काफी बदसूरत बनाता है।

क्या कोई समुदाय सदस्य इस समस्या को हल करने में मेरी मदद कर सकता है?


आजकल इसे कैसे करें:

चूंकि यह libgdx पर सबसे प्रसिद्ध प्रश्नों में से एक है, इसलिए मैं इसे थोड़ा अपडेट दूंगा:

इस समस्या को संभालने के लिए लिबजीडीएक्स v1.0 ने Viewport पेश किया। इसका उपयोग करना बहुत आसान है और स्केलिंग रणनीति प्लग करने योग्य है, जिसका अर्थ है कि एक पंक्ति एक व्यवहार को बदल सकती है और आप इसके साथ खेल सकते हैं और देख सकते हैं कि कौन सा गेम आपके गेम को सबसे अच्छा बनाता है।

इसके बारे में आपको जो कुछ भी पता होना चाहिए वह here पाया जा सकता here



मैं http://blog.acamara.es/2012/02/05/keep-screen-aspect-ratio-with-different-resolutions-using-libgdx/ से उस विधि का उपयोग कर रहा हूं

मैंने यह फ़ंक्शन बनाया है जो स्क्रीन पर बिंदु को स्पर्श करता है, जो आप चाहते हैं उस गेम की स्थिति में घटाया जाता है।

public Vector2 getScaledPos(float x, float y) {
    float yR = viewport.height / (y - viewport.y);
    y = CAMERA_HEIGHT / yR;

    float xR = viewport.width / (x - viewport.x);
    x = CAMERA_WIDTH / xR;

    return new Vector2(x, CAMERA_HEIGHT - y);
}

इसे टचडाउन / अप / ड्रैग में उपयोग करें और आप अपने गेम में स्पर्श के लिए जांच सकते हैं।


यह कोड नवीनतम अपडेट के साथ मेरे लिए काम करता है: * ऑर्थोग्राफिक कैमरे कैम है, यह कोई फसल नहीं बनाता है, सिर्फ व्यूपोर्ट को बदलता है ताकि चौड़ाई अभी भी "खिड़की / डिवाइस की तुलना में बहुत अधिक" गुना हो

public void resize(int width, int height) {
    int newW = width, newH = height;
    if (cam.viewportWidth > width) {
        float scale = (float) cam.viewportWidth / (float) width;
        newW *= scale;
        newH *= scale;
    }

    // true here to flip the Y-axis
    cam.setToOrtho(true, newW, newH);
}

संपादित करें: libGDX विकसित हुआ है। सबसे अच्छा जवाब अब उपयोगकर्ता द्वारा कोई नहीं है। here के लिंक को जांचना सुनिश्चित करें here

चूंकि स्टीवब्लैक ने स्टेज क्लास में रिपोर्ट किए गए मुद्दे के लिंक को पोस्ट किया था, इसलिए मैं यह पता लगाने के लिए वहां गया कि यह मुद्दा (वास्तव में मेरा मुद्दा नहीं था) को नवीनतम नाइटली में हल किया गया है।

इस मुद्दे के लिए इंटरनेट पर यहां और वहां शोध करने के बाद, मुझे कोई समाधान नहीं मिला, इसलिए उस व्यक्ति से संपर्क करने का फैसला किया जिसने सीधे बग की सूचना दी। उसके बाद, उसने मुझे libgdx मंचों पर उत्तर दिया और मैं उसकी मदद करने के लिए उसके लिए ऋणी हूं। लिंक यहां दिया गया है

यह कोड की एक पंक्ति थी और आपको बस इतना करना है:

आकार में () मेथॉन्ड में:

stage.setViewport(640, 480, false);
stage.getCamera().position.set(640/2, 480/2, 0);

जहां 640 एक्स 480 आपके TextureRegion का संकल्प है जो इच्छित पहलू अनुपात का वर्णन करता है। यदि आपका TextureRegion आकार 320 x 240 था, तो दोनों तर्कों को चाल करने के लिए नए रिज़ॉल्यूशन में बदला जाना चाहिए।

मूल व्यक्ति का प्रोफ़ाइल लिंक जिसने वास्तव में मेरी समस्या का समाधान किया





aspect-ratio