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




opengl-es aspect-ratio (6)

ResolutionFileResolver क्लास आपको फ़ाइल नामों को सर्वोत्तम रिज़ॉल्यूशन में हल करने की अनुमति देता है। मेरा मानना ​​है कि विभिन्न पहलू अनुपात के साथ भी काम करेगा, बशर्ते आपने उन पहलू अनुपात के लिए sprites बनाया है। AssetManagerTest में एक उदाहरण का उपयोग है।

मैंने 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 ) को बनाए रखने के लिए अपनी मूल कार्यक्षमता है। अब जब मैंने स्टेज क्लास का उपयोग कर अपनी स्क्रीन लागू की है, तो पहलू अनुपात इसके द्वारा अच्छी तरह से बनाए रखा जाता है। हालांकि आकार बदलने या विभिन्न स्क्रीन आकारों पर, उत्पन्न होने वाला काला क्षेत्र हमेशा स्क्रीन के दाईं ओर दिखाई देता है; यह स्क्रीन केंद्रित नहीं है जो काला क्षेत्र काफी बड़ा है अगर यह काफी बदसूरत बनाता है।

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


बाएं / दाएं या ऊपर / नीचे काले रंग की बार स्क्रीन को फिट करने के लिए बस अपने पूरे दृश्य को विकृत करने से बेहतर दिखती हैं। यदि आप संभावित श्रेणी के बीच में एक पहलू अनुपात को लक्षित करते हैं (4: 3 शायद कम अंत है, 16: 9 शायद उच्च अंत है), तो अधिकांश उपकरणों के लिए सलाखों को छोटा होना चाहिए। यह भी आप बड़ी स्क्रीन पर भी अधिकांश स्क्रीन का उपयोग करते हैं, और आपके पास पहले से ही उस लड़के का कोड है इसलिए यह बहुत आसान है। यह भी अच्छा होगा अगर यह libgdx में बनाया गया एक विकल्प था।

लेकिन, मुझे लगता है कि पूरी स्क्रीन का उपयोग करना सबसे अच्छा तरीका है। मैंने अभी तक यह नहीं किया है, लेकिन यह मेरी अगली परियोजना के लिए दृष्टिकोण होगा। विचार यह है कि अगर किसी के पास व्यापक स्क्रीन है, तो उन्हें पक्षों पर और अधिक देखना चाहिए। क्रिस प्रूट ने अपनी वार्ता में यह कैसे करना है (बातचीत में स्पॉट करने के लिए लिंक - वास्तव में, पूरी बात वास्तव में बहुत अच्छी है) के बारे में बात करती है। विचार ऊंचाई के लिए स्केल करना है, और उसके बाद स्क्रीन को फिट करने के लिए पर्याप्त रूप से अपना व्यूपोर्ट सेट करें। ओपनजीएल को बाकी को प्रदर्शित करने का ख्याल रखना चाहिए। वह जिस तरह से करता है वह here

Libgdx के लिए, शायद कैमरे को मंच पर ले जाकर scene2d के साथ ऐसा करने का एक आसान तरीका है, लेकिन मैंने वास्तव में scene2d के साथ काम नहीं किया है। किसी भी मामले में, ऐप को मूल आकार बदलने योग्य विंडो के रूप में चलाने से AVDs का एक समूह बनाने की तुलना में एकाधिक स्क्रीन आकारों का परीक्षण करने का एक आसान तरीका है।


संपादित करें: 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 था, तो दोनों तर्कों को चाल करने के लिए नए रिज़ॉल्यूशन में बदला जाना चाहिए।

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


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

चूंकि यह 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);
}

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







aspect-ratio