2B bir uzay oyununda izometrik grafikleri taklit etmek


15

Öncelikle, çizim problemimin tam olarak ne olduğunu biliyorum ve çözme yaklaşımına nasıl yaklaşacağım konusunda çeşitli fikirlerim var. İzometrik "yanılsama" korunacak şekilde hangi çerçevenin çizileceğini ayarlamak için buradayım.

Uzayda yer alan 2 boyutlu, kuşbakışı bir oyun yazıyorum. İzometrik grafikleri Up'ın Kuzey olduğu bir dünyada kullanmaya çalışıyorum, geleneksel izometrik oyunlarda olduğu gibi oyun dünyasını döndürmüyorum (unutmayın, oyun uzayda gerçekleşiyor, arazi yok). Kullanmaya çalıştığım örnek bir hareketli grafik: http://cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64.png 35 derecelik görüş açısına sahip kendi dikey ekseni hakkında 64 kez döndürüldü (aka, izo). Görüntü yaratıldı, bu nedenle bu olabilir değiştirilemez.

Anlaşılır olması için, Kuzey'in (Yukarı) 0 derece ve Doğu'nun (Sağ) 90 olduğunu dikte ettim.

Benim sorunum, sprite'ım her zaman oyunun kullanılan 3D uçaklardaki bir farktan kaynaklandığını düşündüğü yere bakmıyor gibi görünüyor . Terminolojiyi doğru şekilde kullanıp kullanmadığımdan emin değilim, ancak uzay gemim bir düzlemde döndürüldü ve görüş düzlemi, şeylerin kendi düzleminde döndürülmesini bekliyor. İşte sorunun bir tasviri:

http://cell.stat-life.com/images/stories/AsteroidOutpost/ProjectionIssue.png Solda, ben sağda ben yukarıdan aşağıya görüşlere sahip, yan görüşlere sahip. Üstte, dünyanın uzay gemisi / sprite sayfası görünümü var. Altta, ekrana çizildiğinde sprite neye benziyor .

Sağ üstte uzay gemimin nasıl döndürüldüğünün basitleştirilmiş bir versiyonu var (her bir çerçeve arasında eşit derecede ayrımlar). Sağ altta açı sprite olmasıdır görünüyor belirli bir açı ekranda çizildiğinde bunun gibi yüzleşiyor. Sorun en çok yaklaşık 45 derecede belirgindir. Geminin karşı karşıya kaldığı yöne işaret eden bir "ekran düzlemi" çizgisiyle kaplanmış bir görüntü: http://cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64RedLine.png Kırmızı çizgi her zaman gemiyle tam olarak aynı yönde olmalıdır , ancak gördüğünüz gibi, projeksiyon sorunu bir soruna neden oluyor. Umarım sorunu yeterince iyi açıklarım.

DÜZENLEME: Uzay gemisi "gemi uçağı" üzerinde döndürülürken, kırmızı çizgi ekran düzleminde döndürülür, bu nedenle çizildiğinde gemi açısı ile ekran açısı arasındaki büyük fark. SON DÜZENLEME

Bu gemi bir tarafa kapalı bir hedefe lazer ışını çekerken, düz bir şekilde ateş etmesi gerektiğinde oldukça garip görünüyor.

Yani ... bulduğum çözümler:

  1. İzometrik bir görünümü taklit etmeye, büyük veya eve gitmeye çalışmayı bırak. Dünyamı zaten döndür. (PS: bu sorunumu çözecek değil mi?)
  2. Sprite sayfamı (her nasılsa) modelin görüntüleneceği "ekran açısını" temsil eden karelere sahip olacak şekilde değiştirin. Yani 45 derecelik bir görüntü istediğimde, aslında ekranda 45 dereceye bakmış gibi görünecek.
  3. Sprite oluşturma sistemimi, "normal" çerçeveyi yakalamanın komik görüneceğini bilerek sprite sayfasından (her nasılsa) farklı bir çerçeve kapmak için değiştir. Bu nedenle 45 derecelik çerçeveyi tutmak yerine, ... 33 derece çerçeveyi (sadece tahmin) yakalar, böylece kullanıcıya doğru görünür .
  4. Sadece 3D kullanın! Çok daha kolay adamım

Birincisi: Hangi çözümü önerirsiniz? Yanlış olduğunu bilsem bile 2'ye doğru eğildim. Hareketli grafik oluşturma aracına tam erişimim olduğunu unutmayın. Yöntem 3 benim ikinci tercihim olurdu. Bu yöntemlerin her ikisi de, istenen sonucumu elde etmek için açılara biraz matematik uygulamamı gerektirir. Btw, şaka olarak # 4 ekledim, 3D'ye geçmek istemiyorum.

İki kişilik: Yöntem 2 veya 3'ü kullanarak giriş veya çıkış açılarını nasıl ayarlayabilirim? 3D projeksiyonlar ve 3D matrisler (bırakın 2D matrisler) ile o kadar iyi değilim ve bana istenen sonucu elde etmek için başka herhangi bir matematik kullanılabilir.

Burada yüksek sesle düşünmek: geminin bakmasını istediğim yöne bakan bir birim vektörü alırsam (ekran düzleminde), o zaman bunu gemi düzlemine yansıtırsanız, o zaman yansıtılan çizgi ile uçağın arasındaki açının ne olduğunu anlayın kuzeyde, göstermek istediğim gemi grafiğinin açısına sahip olmalıyım. Sağ? (# 3 için çözüm?) Adam ... Bunu çözemiyorum.

DÜZENLE:

Sorunun statik görüntülerle görselleştirilmesinin zor olduğunu biliyorum, bu yüzden sorunu göstermek için Sprite Library Visual Tester'a uydum : http://cell.stat-life.com/downloads/SpriteLibVisualTest.zip XNA 4.0 gerektirir Bu uygulama basitçe hareketli çizgiyi döndürmek ve oyunun geminin karşı karşıya kalması gerektiğini düşündüğü açıda merkez noktasından dışa doğru bir çizgi çizmek.

8 Eylül DÜZENLE

"Yüksek sesle düşünmek" paragrafımdan devam etmek: Bir projeksiyon kullanmak yerine (zor göründüğü için) kuzeye bakan birim vektörü (0x, 1y, 0z) alabileceğimi, açıya döndürmek için bir matris kullanabileceğimi düşünüyorum hareketli grafik aslında bakacak şekilde, sonra tekrar "görüntüleme düzleminden" X ekseni etrafındaki "hareketli grafik düzlemine" döndürün, sonra ... düzleştirin? vektör (esasen onu yansıtır) sadece X ve Y kullanarak (Z yoksayılır) görüntüleme düzlemine geri döner. Sonra bu yeni düzleştirilmiş vektörü kullanarak, açısını belirleyebilir ve bunu ... bir şey yapmak için kullanabilirim. Daha sonra düşüneceğim.

8 Eylül DÜZENLE (2)

Fikrimi yukarıdan takip etmeyi denedim, yay! Yani ... uzay gemimden çıkmış gibi görünen kırmızı bir çizgi elde etmek için (sadece test amaçlı), aşağıdakileri yaptım:

Vector3 vect = new Vector3(0, 1, 0);
vect = Vector3.Transform(vect, Matrix.CreateRotationZ(rotation));
vect = Vector3.Transform(vect, Matrix.CreateRotationY((float)((Math.PI / 2) - MathHelper.ToRadians(AngleFromHorizon))));
Vector2 flattenedVect = new Vector2(vect.X, vect.Y);

float adjustedRotation = (float)(getAngle(flattenedVect.X, flattenedVect.Y));

rotationEkran açısı nerede ve adjustedRotationşimdi ekran açısı hareketli grafiğe bakıyor. X yerine Y'yi neden döndürmem gerektiğini bilmiyorum, ama muhtemelen bilmediğim 3D ile ilgili bir şey.

Peki, şimdi ek bir bilgim var, ancak daha uygun bir çerçeve seçmek için bunu nasıl kullanabilirim? Belki bakış düzleminden hareketli grafiğe dönüp sonra geri yansıtmak yerine, bunu tam tersine yapmaya çalışmalıyım. İşte benim sprite ayarlanmış bir kırmızı çizgi ile, ama gerçekten yapmak istediğim modeli değil çizgiyi ayarlamak: http://cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64RedLineCorrected.png

9 Eylül EDIT

HORAY! Düzeltildi! Bunu düzeltmek için ne yaptığımı açıklayacağım:

EBusiness'ın tavsiyelerine uydum ve dünya koordinat sistemi tarafından "ezildim" (ya da gerildim ...?). Bu aslında 1 numaralı çözümdür, ancak dünya koordinat sistemimi ekran koordinat sistemine göre döndürmem gerektiği izlenimi altındaydım. Doğru değil! Yukarı hala + y ve Sağ hala + x. WorldToScreen ve ScreenToWorld yöntemlerimi, dünya ve ekran koordinatları arasında düzgün bir şekilde dönüştürmek için değiştirdim. Bu yöntemler en uygun olmayabilir, ancak burada kod tabanımda değişmesi gereken tek iki yöntem var.

public Vector2 ScreenToWorld(float x, float y)
{
    float deltaX = x - (size.Width / 2f);
    float deltaY = y - (size.Height / 2f);

    deltaX = deltaX * scaleFactor / (float)Math.Sqrt(3);
    deltaY = deltaY * scaleFactor;

    return new Vector2(focusWorldPoint.X + deltaX, focusWorldPoint.Y + deltaY);
}

public Vector2 WorldToScreen(float x, float y)
{
    float deltaX = x - focusWorldPoint.X;
    float deltaY = y - focusWorldPoint.Y;

    deltaX = deltaX / scaleFactor * (float)Math.Sqrt(3);
    deltaY = deltaY / scaleFactor;

    return new Vector2(size.Width / 2f + deltaX, size.Height / 2f + deltaY);
}

Hepsi bu kadar! Bu iki yöntemi değiştirmek her şeyi etkiledi: neye bakıyordum, çizilen nesneler nerede, nereye tıklıyordum, her şey. Uzay gemim şimdi doğrudan vurduğu hedefe bakıyor ve her şey yerine oturuyor. Ortografik izdüşümü deneyeceğim, bakın her şeyin daha 'gerçek' görünmesini sağlıyor.


Tebrikler. Oynatılabilir bir şey olduğunda beni dürtmeyi unutma, bunun nereye gittiğini görmek istiyorum.
aaaaaaaaaaaa

@eBusiness şöyle söz verdi: cell.stat-life.com/images/stories/AsteroidOutpost/... ve cell.stat-life.com/images/stories/AsteroidOutpost/AOOhNoes.png Bildirimi gemi nasıl görünüyor böyle o kulede bakıyor? : D Teşekkürler!
John McDonald

@ eBusiness, Bir video youtube.com/watch?v=Q8pR9KDBsCo İstediğinizden indirmek için bir bağlantı da var.
John McDonald

Yanıtlar:


4

İzometrik perspektifi seçtiğinizde, X ve Y ekseni arasındaki ölçeği düzeltmeniz gerekir. Belirli bir mesafe ekranlar Y ekseni üzerinde 1'e yansıtılırsa, aynı mesafe ekranlar X ekseni üzerinde sqrt (3) 'e yansıtılır. Ekranda düz bir şeyler çizerseniz şöyle bir şey yaparsınız:

draw(object.image, object.x*sqrt(3), object.y)

Yanıtlanmamış notlar:

  • Sprite sayfalarını ve eşyalarını neden karıştırıyorsun? İsterseniz izometrik bir 3D oluşturucu alabilirsiniz.
  • Sprite sayfaları kullandığınız için, neden kenarları yumuşatılmıyor?
  • İzometrik uzayda, şimdiye kadar bir oyun kullanımı gördüğümü sanmıyorum, görsel referans için açıkça izometrik bir zemin eksikliği göz önüne alındığında ne kadar iyi çalışacağından emin değilim.

1
Bence ... Bu her şeyi düzeltebilir. Bu kolay bir düzeltme ve sayfayı yalnız bırakabilirim. Bunu en kısa zamanda deneyeceğim ve nasıl gittiğini size bildireceğim. Notlarınızı cevaplamak için: 1) 2B kullanıyorum çünkü aşina olduğum şey ve sayfalarımı 3B modellerden üretiyorum. 2) Kenarlar keskin olmalı, ancak sert kenarların içinde alfa kanalını kenar yumuşatma için kullanabilirim, bu gelecek. 3) Üçüncü boyutu simüle etmeyi planlamıyorum (çok), esas olarak yukarıdan aşağıya olmayan ve şeylerin kenarlarını görmenize izin veren 2D grafikler istiyorum.
John McDonald

5

Döndürülmüş hareketli grafik nasıl üretilir? Bu ekran görüntüleri dönen bir 3D model mi? 3B modelleme aracının kamera perspektifi nedeniyle ön yüz açısı kapalı olabilir. İzometrik perspektif, 3D uzayının doğru bir temsili değildir. 'Kameradan' uzakta olan şeyler küçülmez.

Sadece hızlı bir düzeltme istiyorsanız. Çözüm 2'nin doğru olması zor olabilir. Çözüm 3 kolay görünüyor, sadece açıya uymayan çerçeveleri, açıya daha iyi uyan bir çerçeveyle değiştirin.

Lazerler bazen kapalı olacaktır. Düzgün bir dönüş yapmamanız, ancak belirli derece aralıkları için farklı çerçeveler göstermeniz.

DÜZENLE:

Sorununuz, oluşturulan ekran görüntülerinin izometrik perspektif değil, normal bir 3D kamera görüntüsü olmasıdır.

resim açıklamasını buraya girin

İzometrik görünüm, 3D alanı simüle eder, ancak doğru bir gösterim değildir. Kameradan uzaklaştıkça işler küçülür. Bu, izometrik perspektif için yapılmaz, çünkü bu hareketli grafikte çirkin ölçekleme artefaktlarına neden olur.

Uzay gemisi ekran görüntüleriniz 3D kamera perspektifiyle yapılır. Bu yüzden lazer çekimi kapalı. 'İzometrik' ve 'perspektif' içindeki kırmızı çizgiyi karşılaştırın.

Hareketli grafik jeneratör kullanmalıdır Matrix.CreateOrthographic () yerine Matrix.CreatePerspective () çıkıntı matris için.


Sprite, geliştirdiğim bir 3D - 2D aracı kullanılarak üretildi, bu yüzden sorun bu araçta çok iyi olabilir. Araç sadece bir 3D model yükler, daha sonra Spaceship64.png (yukarıda) elde etmek için, modeli (360/64) = 5.625 derece döndürür, bunu bir çerçeve olarak kaydeder, daha sonra hepsini elde edene kadar aynı miktarda döndürür. 64 kare. Modeli oluşturmak için kullanılan kod burada: code.google.com/p/sprite-maker/source/browse/trunk/XNAWindow/… Döndürme başka bir sınıfta yapılır. Ayrıca çözüm 2 ve 3'ün birbirinin tersi olduğunu düşünüyordum, değil mi?
John McDonald

Cevabımı düzenledi. Yukarıyı görmek.
Stephen

Her ikisini de yapmam gerekebileceğini düşünüyorum: sprite jeneratörünün ortografik bir projeksiyon kullanmasını sağlayın ve @eBusiness'ın söylediği gibi dünya koordinat sistemimi değiştirin. Dün gece Ortografik projeksiyonu denedim ve gemimin görünüşünü kesinlikle değiştirdi, ancak tek başına yaşadığım açı problemini çözmedi.
John McDonald

Düzenlemenizi gördüm. Düzeltilmiş sprite, geminin merkezi kırmızı çizginin merkezinden uzakta gibi görünüyor. Belki de gemiyi kırmızı çizginin başlangıç ​​noktasından bir veya iki piksel daha yükseğe çekmek yeterlidir. Gemi dünyanızdan uzaklaşırken görünen hata değişiyor mu? Ardından X Eksenini ölçeklendirmek bunu düzeltebilir.
Stephen

1

Bence burada ne var basitçe izometrik görünüyor. Görsel olarak konuşursak, 0 derece ile 10 derece arasında 90 derece ile 100 derece arasında olduğundan daha büyük bir fark var gibi görünüyor. . . ancak bunun nedeni, izometrik bir ekseni içsel olarak sıkıştırmasıdır. Bu görünümü istemiyorsanız, izometrik istemezsiniz.

Bununla birlikte, yaşadığınız görsel sorunların görsel bir referans noktasına sahip olmamanızdan kaynaklandığını söyledi. Beyniniz yukarıdan aşağıya baktığınızı varsayıyor - hey, boşluk, neden olmasın - ve bunu standart yukarıdan aşağıya bir görünüm olarak yorumluyor. Test etmek için bazı yüzen holografik referans noktaları eklemeyi deneyin. Örneğin 45 derecelik açılı bir ızgara veya uzay aracınızın etrafındaki bir dizi menzil çemberi. Uzay geminizin yapıldığı aynı izometrik düzlemdeymiş gibi uygun şekilde çarpık olduğundan emin olun. Bahse girerim ki beyniniz perspektifi bulur ve aniden doğru görünür.

Şimdi, bunu kullanıcılarınıza nasıl ulaştıracağınızı öğrenin. . . bu tamamen başka bir mesele.


Bu yöntemi kullanarak (soruda 1. yöntem) illüzyonu tamamlamak için dünya eksenini de döndürmem gerekmeyecek mi?
John McDonald

Anlayabildiğim kadarıyla, gemi zaten doğru bir şekilde işleniyor - yan görünümler, izometrik "doğru" görünmesi için olması gereken açıda gösteriyor. "Dünya eksenini döndür" derken ne demek istediğinden emin değilim.
ZorbaTHut

"Dünya eksenini döndür" derken, "Kuzey" in ekranın sağ üst veya sol üst köşesine doğru "Kuzey" in düz olması yerine kamerayla ilişkili olarak dünyayı 45 derece döndürmek demek istiyorum. ekranın üst kısmına doğru kaydırın.
John McDonald


Bu yardımcı olabilir, ancak uzayda zaten bu kadar çok fark yaratmamalıdır. Dünya üzerinde bir ızgara bulunmadığı sürece bunun bir önemi yok.
ZorbaTHut
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.