2D oyun çözünürlüğünü nasıl bağımsız hale getirebilirim?


10

Basit bir 2D oyun üzerinde çalışıyorum. Cep telefonu versiyonunu bitirdim.

Ancak, patronum oyunun RT'si üzerinde çalışmasını istiyor. Ben "dönüşüm" yapıyorum ama düğmelerimi yanlış yerlerde, çünkü ekran boyutunu sabit kodladım, şöyle:

 texture = game.Content.Load<Texture2D>("StartScreen");
 mainFrame = new Rectangle(0, 0, game.GraphicsDevice.Viewport.Width, game.GraphicsDevice.Viewport.Height);

 // button definitions
 startbrect = new Rectangle(300, 258, 88, 88);
 startbtext = game.Content.Load<Texture2D>("bplay");

Bu örnekte, mainframesorun yok, ancak startbrectdeğil, çünkü boyutu bir Windows telefonun ekranıyla eşleşecek şekilde tanımladım. Tüm Windows 8 telefonlarının ekranları farklı olduğunda duyarlı tasarımı nasıl ele alabilirim? Her seferinde iyi boyutu hesaplamak için bir formül veya makro var mı?


Windows Phone'un ekran boyutunun yüzde kaçının düğmelerin kullanıldığını kontrol edebilir ve ardından bu yüzdeyi diğer tüm çözünürlükler için doğru ekran boyutunu hesaplamak için kullanabilirsiniz. Ama eminim bundan daha zarif yollar var.
Christian

Daha zarif bir yol arıyorum, ama şu an için yüzde ile deneyeceğim.
Gabson

2
Kamerayı manipüle ederek bunu yapabilmelisiniz.
ashes999

Benim çözümüm yüzdesi ile başa çıkmak daha iyi bulamadık.
Gabson

Yanıtlar:


17

Bir referans ekran boyutu kullanıyorum ve her şeyin oranını korurken her şeyi buna göre ölçeklendiriyorum.

private static float CalcRatio(Vector2 Sizes)
{
    return Sizes.y/Sizes.x;
}

public static Vector2 CalculateNewPos(Vector2 RefPos, Vector2 RefScreenSize, 
                                      Vector2 CurrentScreenSize)
{       
    return new Vector2((RefPos.x/RefScreenSize.x) * CurrentScreenSize.x, 
                       (RefPos.y/RefScreenSize.y) * CurrentScreenSize.y);
}

public static Vector2 CalculateNewSize(Vector2 RefSize, Vector2 RefScreenSize,
                                       Vector2 CurrentScreenSize)
{       
    float origRatio = CalcRatio(RefSize);
    float perW = RefSize.x * 100f / RefScreenSize.x;    
    float newW = perW / 100f * CurrentScreenSize.x;
    float newH = newW * origRatio;
    return new Vector2(newW, newH);
}

Oyunun referans çözünürlüklerinizden oldukça farklı oranlara sahip çözünürlüklerde iyi göründüğünden emin olmak için, her türlü ekrana sığabilecek ve oynanabilirlikle ilgili tüm kritik görselleri oraya koyabileceğiniz bir "oynanabilir alan" tanımlayın. Bunun dışındaki her şeyi arka planla doldurun. Genellikle, oynatılabilir referans alanım referans ekran boyutunun kendisi kadar büyüktür.

Dikey yönlerde, (yeni) oynanabilir alanı ekran dikey olarak doldurulacak şekilde hesaplıyorum ve yatay olarak aldığı alan oranı korumak için gereken kadar büyük. Yatay yönlerde, ekranı yatay olarak dolduruyorum ve dikey boyutu ayarlarken oranı koruyorum.

Daha fazla bilgi için, http://en.wikipedia.org/wiki/Safe_area_(television) 'a benzer olmasa da benzer bir konsept bakın.


0

Bağımsız mizanpajların çözümlenmesinde en kolay ve en doğal yaklaşımın göreceli (yüzde) bir plan olduğunu düşünüyorum. Bu yüzden başlangıçtan itibaren gerçek çözünürlükle değil, mümkün olan her yerde tekdüze [0,1] x [0,1] kare şeklinde çalışın.

Bu, belirli bir screen_sizeve belirli bir object_sizeve belirli bir göreceli konum için (px, py)(örneğin ekranın merkezi için (0.5, 0.5)), nesnenin sol üst köşesinin şu şekilde hesaplandığı anlamına gelir:

x = px * screen_size.width - 0.5 * object_size.width
y = py * screen_size.height - 0.5 * object_size.height

Fikir açık olmalı. Hazır bir soyutlama

x = cx1 * screen_size.width + cx2 * object_size.width + cx3
y = cy1 * screen_size.height + cy2 * object_size.height + cy3

ve her pozisyon o zaman ile tanımlanır (cxi, cyi). Böylece nesneler kenarlıklı veya kenarsız vb. Köşelere yerleştirilebilir.

Lütfen tek öğe boyutunun (düğmeler, etiketler, ...) de ölçeklendiğinden emin olun.


-2

Özellikle MonoGame için IRR (Independent Resolution Renderer) adı verilen bu sorun için platformdan bağımsız bir çözümüm var. Çok basit bir kullanımı vardır:

  1. Initialize () yönteminde IRR oluşturma

    _irr = new ResolutionRenderer (this, VirtualResolutionWidth, VirtualResolutionHeight, _gfx.PreferredBackBufferWidth, _gfx.PreferredBackBufferHeight);

  2. Çağrı _irr.Draw () her döngü Çekiliş () çağrısı
  3. Tedarik _irr.GetTransformationMatrix () herhangi SpriteBatch.Begin () Eğer IRR kullanmak istiyorum arayın.

Açıklama burada: http://panthernet.ru/forum/index.php?/topic/17-monogamexna-examples-v14/?p=44

Kod burada: https://github.com/panthernet/Monogame-Examples

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.