Bagaimana cara membuat resolusi game 2D independen?

10

Saya sedang mengerjakan game 2D sederhana. Saya telah menyelesaikan versi ponsel.

Namun, bos saya ingin game bekerja pada RT-nya. Saya melakukan "konversi" tetapi tombol saya ada di tempat yang salah, karena saya meng-hard-sod ukuran layar, seperti ini:

 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");

Dalam contoh ini, mainframebaik-baik saja, tetapi startbrecttidak, karena saya menentukan ukuran agar sesuai dengan layar ponsel Windows. Bagaimana saya bisa menangani desain responsif ketika semua layar ponsel Windows 8 berbeda? Apakah ada rumus atau makro untuk menghitung setiap kali ukuran yang baik?

Gabson
sumber
Anda dapat memeriksa persentase Windows Phone yang membuat screensize tombol yang Anda gunakan, dan kemudian menggunakan persentase itu untuk menghitung screensize yang benar untuk setiap resolusi lainnya. Tapi saya yakin ada cara yang lebih elegan dari ini.
Christian
Saya mencari cara yang lebih elegan, tetapi saya akan mencoba dengan persentase untuk saat ini.
Gabson
2
Anda harus dapat melakukannya dengan memanipulasi kamera.
ashes999
Solusi saya adalah berurusan dengan persentase tidak menemukan yang lebih baik.
Gabson

Jawaban:

17

Saya menggunakan ukuran layar referensi, dan skala semuanya sesuai dengan itu, sambil menjaga rasio semuanya tetap sama.

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);
}

Untuk memastikan permainan terlihat bagus pada resolusi dengan rasio yang jauh berbeda dari resolusi referensi Anda, tentukan "area yang dapat dimainkan", yang cocok dengan segala jenis layar, dan letakkan semua visual penting gameplay di sana. Isi semua yang ada di luarnya dengan latar belakang. Biasanya, area referensi yang dapat diputar saya sebesar ukuran layar referensi itu sendiri.

Pada orientasi potret, saya menghitung area yang dapat diputar (baru) sehingga layar diisi secara vertikal, dan ruang yang dibutuhkan secara horizontal sama besarnya dengan yang diperlukan untuk menjaga rasio. Pada orientasi lanskap, saya mengisi layar secara horizontal, dan menjaga rasio ketika mengatur ukuran vertikal.

Untuk lebih lanjut, lihat http://en.wikipedia.org/wiki/Safe_area_(television) karena konsepnya mirip, jika tidak identik.


sumber
0

Saya pikir pendekatan termudah dan paling alami untuk resolusi tata letak independen adalah skema (persentase) relatif. Jadi sejak awal tidak bekerja dengan resolusi nyata tetapi hanya dalam seragam [0,1] x [0,1] kuadrat sedapat mungkin.

Itu berarti bahwa untuk posisi diberikan screen_sizedan posisi tertentu object_sizedan diberikan (px, py)(misalnya (0,5, 0,5) untuk pusat layar), sudut atas, kiri objek dihitung dengan:

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

Idenya harus jelas. Abstraksi yang siap adalah

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

dan setiap posisi ditentukan kemudian oleh (cxi, cyi). Dengan ini orang dapat menempatkan objek di sudut dengan atau tanpa batas, dll.

Pastikan ukuran elemen tunggal (tombol, label, ...) juga diskalakan.

Trilarion
sumber
-2

Khusus untuk MonoGame, saya memiliki solusi platform independen untuk masalah ini yang disebut IRR (Independent Resolution Renderer). Ini memiliki penggunaan yang sangat sederhana:

  1. Buat IRR dalam metode Inisialisasi ()

    _irr = ResolutionRenderer baru (ini, VirtualResolutionWidth, VirtualResolutionHeight, _gfx.PreferredBackBufferWidth, _gfx.PreferredBackBufferHeight);

  2. Panggil _irr.Draw () setiap siklus dalam panggilan Draw ()
  3. Supply _irr.GetTransformationMatrix () di semua panggilan SpriteBatch.Begin () yang ingin Anda gunakan IRR.

Deskripsi ada di sini: http://panthernet.ru/forum/index.php?/topic/17-monogamexna-examples-v14/?p=44

Kode ada di sini: https://github.com/panthernet/Monogame-Examples

Alexander Smirnov
sumber