Saya membuat game uji di mana saya ingin levelnya terus bergulir. Untuk membuat efek ini, saya telah membuat kelas kamera yang hanya menyimpan posisi vektor2 dan arah enum. Ini juga berisi metode publik untuk 'bergerak' yang hanya mengubah posisi pada tingkat yang tetap. Saya kemudian menggunakan posisi ini ketika memutar melalui array ubin saya saat menggambar. Ini semua berfungsi dengan baik.
Namun, saya telah diberitahu bahwa saya harus menggunakan matriks Transform untuk menggerakkan kamera, dan bahwa saya harus menyediakan ini ketika saya memulai spritebatch. Saya agak bingung a.) Bagaimana cara kerjanya? seolah-olah saya hanya memberikannya ketika spritebatch dimulai, bagaimana ia tahu untuk terus mengubah posisi? b.) Mengapa melakukannya karena saya masih memerlukan posisi kamera ketika saya melewati ubin?
Saat ini saya tidak bisa membuatnya bekerja, tetapi itu tidak mengejutkan karena saya tidak sepenuhnya mengerti bagaimana ini dimaksudkan untuk bekerja. Saat ini dalam upaya saya (kode untuk mengikuti) ubin ditarik perubahan yang berarti posisi kamera berubah, tetapi posisi viewport tetap tidak berubah (yaitu pada asal kamera). Saya akan sangat menghargai beberapa saran / bimbingan tentang bagaimana seharusnya digunakan?
Kamera:
class Camera {
// The position of the camera.
public Vector2 Position {
get { return mCameraPosition; }
set { mCameraPosition = value; }
}
Vector2 mCameraPosition;
public Vector2 Origin { get; set; }
public float Zoom { get; set; }
public float Rotation { get; set; }
public ScrollDirection Direction { get; set; }
private Vector2 mScrollSpeed = new Vector2(20, 18);
public Camera() {
Position = Vector2.Zero;
Origin = Vector2.Zero;
Zoom = 1;
Rotation = 0;
}
public Matrix GetTransform() {
return Matrix.CreateTranslation(new Vector3(mCameraPosition, 0.0f)) *
Matrix.CreateRotationZ(Rotation) *
Matrix.CreateScale(Zoom, Zoom, 1.0f) *
Matrix.CreateTranslation(new Vector3(Origin, 0.0f));
}
public void MoveCamera(Level level) {
if (Direction == ScrollDirection.Up)
{
mCameraPosition.Y = MathHelper.Clamp(mCameraPosition.Y - mScrollSpeed.Y, 0, (level.Height * Tile.Height - level.mViewport.Height));
}
}
Tingkat:
public void Update(GameTime gameTime, TouchCollection touchState) {
Camera.MoveCamera(this);
}
public void Draw(SpriteBatch spriteBatch) {
//spriteBatch.Begin();
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullCounterClockwise, null, mCamera.GetTransform());
DrawTiles(spriteBatch);
spriteBatch.End();
}
Game - cukup panggil undian dalam level:
protected override void Draw(GameTime gameTime) {
mGraphics.GraphicsDevice.Clear(Color.Black);
//mSpriteBatch.Begin();
// Draw the level.
mLevel.Draw(mSpriteBatch);
//mSpriteBatch.End();
base.Draw(gameTime);
}
================================================== =============================== Edit:
Pertama, terima kasih craftworkgames atas bantuan Anda sejauh ini.
Saya bermain-main dengan saran itu. Ketika saya benar-benar menggambar semua ubin, fr memangkas sekitar 15 dari 30 - mungkin karena levelnya cukup besar.
Jadi apa yang telah saya lakukan adalah menerapkan matriks dan bergerak dalam pembaruan (seperti yang disarankan) tetapi dalam menggambar saya menggunakan posisi kamera untuk perulangan melalui ubin (yaitu mulai counter di kiri dan berakhir di ubin kanan). Ini semua bekerja dengan baik dan saya senang dengan itu :-)
Masalah baru saya terletak pada pemain. Jelas karena saya sekarang memindahkan kamera daripada level, pemain akan tertinggal oleh kamera saat posisinya tetap. Saya telah memikirkan dua solusi untuk masalah ini, yang pertama adalah hanya mempertimbangkan posisi kamera saat menggambar pemain. Yaitu di fungsi undian cukup menambahkan posisi kamera ke posisi pemain. Yang kedua adalah memulai batch sprite baru untuk pemain yang tidak memiliki transformasi. yaitu mengakhiri spritebatch setelah menggambar ubin lalu mulai yang baru saat menggambar pemain. Saya tahu keduanya akan bekerja, tetapi saya tidak bisa membuat kepala yang lebih baik dalam hal kinerja / pengkodean yang baik? Saya tidak yakin apa implikasi kinerja dari memulai batch dua kali?
Jawaban:
Transformasi matriks kamera mudah
Membuat kamera dasar itu mudah. Di bawah ini akan membantu Anda memulai dengan dasar-dasarnya. Memindahkannya, berputar, dan scaling. Memindahkan setiap sprite 2d tidak banyak masalah tetapi jika Anda memfaktorkan penskalaan atau rotasi, maka akan sangat sulit untuk diterapkan ke setiap sprite secara individual.
Itu membuatnya sangat mudah untuk mengkonversi antara definisi sistem koordinat
Untuk berpindah dari layar ke ruang dunia secara sederhana. Ini biasanya digunakan untuk mendapatkan lokasi mouse di dunia untuk pengambilan objek.
Untuk pergi dari dunia ke ruang layar cukup lakukan sebaliknya.
Tidak ada yang menarik untuk menggunakan matriks selain butuh sedikit pembelajaran.
Sangat mudah untuk mendapatkan area yang terlihat
Anda dapat dengan mudah mengubah sudut kamera dan mendapatkan lokasinya di ruang dunia. Min maks nilai x, y dan Anda bisa mendapatkan persegi panjang di sekitar ruang yang dapat dilihat. Sangat berguna untuk menyisihkan dan mengoptimalkan panggilan draw.
sumber
Menerapkan sebuah matriks ke SpriteBatch Anda mengubah seluruh panggilan undian sekaligus. Ini berarti Anda tidak perlu menggunakan kamera dalam metode DrawTiles Anda sama sekali.
Itu bisa menjadi jauh lebih sederhana seperti:
Jadi intinya menggunakan matriks adalah agar Anda tidak perlu memikirkannya. Hanya menggambar dan memindahkan kamera secara mandiri.
Juga, metode MoveCamera Anda terlihat sedikit aneh. Sangat tidak biasa memiliki kelas kamera yang menggunakan Level sebagai ketergantungan. Implementasi yang lebih khas akan terlihat seperti ini:
Kemudian dalam metode Pembaruan Anda, Anda mungkin melakukan sesuatu seperti ini:
Secara keseluruhan, saran saya adalah membuatnya sederhana. Dapatkan itu bekerja dengan cara paling sederhana dan membangunnya. Cobalah untuk tidak menulis kode yang sangat dioptimalkan sampai dasar-dasar Anda berhasil terlebih dahulu. Anda mungkin menemukan bahwa memberikan setiap ubin setiap frame tidak terlalu buruk.
EDIT: Untuk bagian kedua dari pertanyaan.
Meskipun benar bahwa Anda ingin menjaga jumlah batch Anda tetap rendah, memiliki 2 atau 3 seharusnya tidak menjadi masalah sama sekali. Jadi, jika Anda memiliki alasan yang bagus untuk membuat batch sprite kedua lakukan saja.
Yang mengatakan, mungkin tidak ada alasan yang baik untuk menggunakan batch sprite kedua dalam kasus ini. Kemungkinan besar, Anda ingin menggambar pemain Anda dengan cara yang sama persis seperti Anda menggambar ubin dalam kumpulan sprite yang sama dengan transformasi kamera yang diterapkan.
Agak sulit untuk mengatakan mengapa pemain Anda tertinggal tanpa melihat beberapa kode tetapi masuk akal bahwa jika Anda menarik pemain Anda pada posisi yang sama persis dengan ubin, ia akan muncul di posisi yang sama dengan yang sama. kumpulan sprite.
Misalnya, jika Anda ingin pemain tampil di ubin 10, 10 Anda bisa melakukan ini:
Cobalah untuk masuk ke dalam pola pikir berpikir tentang menggambar hal-hal di mana mereka berada dan kamera benar-benar menggerakkan seluruh "pemandangan" ke dalam tampilan. Itulah yang dilakukan oleh transformasi matriks Anda.
sumber