2012-02-08 14 views
76

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

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

फोरम लिंक: http://www.java-gaming.org/index.php?topic=25685.new

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

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

+0

क्या आप ब्लॉग या फ़ोरम से लिंक कर सकते हैं जिसमें एक ही समस्या थी? –

+0

@ स्टेवब्लैकवेल यहां लिंक है: http://www.java-gaming.org/index.php?topic=25685.new – Rafay

+0

@ स्टेवब्लैकवेल कृपया अपडेट किया गया प्रश्न देखें और देखें कि क्या आप इस पर सहायता कर सकते हैं। – Rafay

उत्तर

50

यह आजकल कैसे करना है:

इस के बाद से, यहाँ libgdx के कुछ सर्वाधिक प्रसिद्ध सवालों में से एक है कि मैं इसे एक छोटे से अद्यतन देंगे:

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

आपको इसके बारे में जानने की हर चीज here मिल सकती है।

+0

मैं इसे करने की कोशिश की है, लेकिन अभी भी अपने 'TextureRegion' streches। यदि 'reszie (int चौड़ाई, int ऊंचाई) 'फ़ंक्शन खाली छोड़ दें। वह 'TextureRegion' strectch नहीं है। –

+0

लेकिन व्यूपोर्ट्स का उपयोग करते समय भी हमें विभिन्न पहलू अनुपात के लिए अलग-अलग बनावट का उपयोग करना है, है ना? क्या उस विधि को सरल बनाने के लिए कोई तर्क है? या संकल्प से स्वतंत्र रखने के द्वारा ग्राफिक डिज़ाइनिंग किया जाना चाहिए? – WeirdElfB0y

+0

व्यूपोर्ट का उपयोग करने पर अच्छा ट्यूटोरियल: http://www.gamefromscratch.com/post/2014/12/09/LibGDX-Tutorial-Part-17-Viewports.aspx – ubzack

7

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

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

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

+0

"किसी भी में मामला, एक देशी आकार बदलने योग्य खिड़की के रूप में ऐप चलाने के लिए एवीडी का एक समूह बनाने की तुलना में कई स्क्रीन आकारों का परीक्षण करने का एक आसान तरीका है। "ठीक है। वास्तव में, मैं इस घटना पर काम करने की कोशिश कर रहा हूं ताकि विभिन्न स्क्रीन आकारों को लक्षित करने के बजाय अधिकतम संगतता सुनिश्चित हो सके। बनावट के विभिन्न आकार। – Rafay

3

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

24

संपादित करें: libGDX विकसित हुआ है। सबसे अच्छा जवाब अब उपयोगकर्ता नंबर द्वारा this one है। Viewport documentation. पर लिंक जांचना सुनिश्चित करें।

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

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

यह कोड की एक पंक्ति थी और तुम सब करने की है:

आकार में() methond:

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

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

Profile link of the original person who actually resolved my issue

+6

libGDX 0.9.6 में, स्टैग e.setViewport (640, 480, झूठा) पर्याप्त है क्योंकि इसमें पहले से ही मंच पर कॉल शामिल है .getCamera() .position.set (640/2, 480/2, 0); –

+0

काम नहीं करता !!! –

+1

'सेट व्यूपोर्ट' 3 पैरामीटर के साथ अब उपलब्ध नहीं है! –

0

मैं से 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); 
} 

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

+0

यह कैमरे की अप्रत्याशित विधि के समान लगता है। क्या यह वही काम करता है? – milosmns

+0

@milosmns इस तरह से मैं की तरह 1 साल पहले कर रहा था मैं unproject बात पता चला है, अच्छा .. अपने कैमरे एक ही स्थिति में हमेशा होता है जब अच्छा है .. –

0

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

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); 
} 
से बड़ा है
संबंधित मुद्दे