Derinlik, siyah çizgiler taklit dönüşüm dokular (düz nesneleri 3D olarak çizilmiş) rastgele görünür
Yukarıdan aşağıya RPG kullanarak PAZARLAR geliştiriyoruz. Son zamanlarda haritaları görüntülemek için kod yazarken bir aksilik çarptık. Harita, yukarıdan aşağıya çizim normal bir dönüşüm matrisi ile görüntülemek, her şey iyi olacak gibi görünüyor. Ne zaman kullanarak bir düz olmayan dönüşüm matrisi gibi sıkma üst veya alt kısmına taklit derinliği, siyah çizgiler (satırlar zaman üst veya alt, sütun sola veya sağa sıkılmış) bu hareket ne zaman kamera değişiklikleri konumu, görünür. Hareket ve yerleştirme rastgele gibi görünüyor. (Resim daha aşağı sağladı.)
Arka plan bilgileri
Haritalar fayans içerir. Özgün doku fayans 32 x 32 piksel içerir. 2 üçgenler oluşturarak ve bu üçgenlerin orijinal doku parçası görüntüleyerek fayans çizeriz. Bir shader bizim için bunu yapar. Üçgenlerin üç katman var. İlk yarı opak ve kısmi saydam tüm taşlar tüm opak fayans ve tüm piksel opak, yarı opak ve kısmi saydam karolar ve piksel tüm çizeriz. Bu güzel (ama biz kayan nokta faktörüyle çekim yaparken, bazen renk karışık çizgiler çini satır ve/veya sütunlar arasında) çalışır.
Renderstates
Tüm taşlar aynı rasterizerState kullanıyoruz ve katı ya da yarı-şeffaf kiremit çizerken iki arasında geçiş yapar.
_rasterizerState = new RasterizerState();
_rasterizerState.CullMode = CullMode.CullCounterClockwiseFace;
_solidDepthState = new DepthStencilState();
_solidDepthState.DepthBufferEnable = true;
_solidDepthState.DepthBufferWriteEnable = true;
_alphaDepthState = new DepthStencilState();
_alphaDepthState.DepthBufferEnable = true;
_alphaDepthState.DepthBufferWriteEnable = false;
Gölgede aşağıdaki gibi SpriteBlendMode kurduk
İlk katı Kat 1 kullanır
AlphaBlendEnable = False;
SrcBlend = One;
DestBlend = Zero;
Katı ve şeffaf diğer tüm katmanları (üstü çizilmiş) kullanın
AlphaBlendEnable = True;
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha;
Diğer gölgeleme de bunu kullan. SpriteFonts
SpriteBatch
varsayılan ayar kullanılır kullanır.
Doku Oluşturdu
Bazı taşlar anında oluşturulur ve dosyaya kaydedilebilir. Dosyayı göster yüklendiğinde yüklenir. Bu şöyle: RenderTarget
bir oluşturulan kullanılarak yapılır
RenderTarget2D rt = new RenderTarget2D(sb.GraphicsDevice, 768, 1792, false,
SurfaceFormat.Color, DepthFormat.None);
sb.GraphicsDevice.SetRenderTarget(rt);
Oluşturulan dosyayı ve artık RenderTarget
üzerinde olacak çünkü cihaz sıfırlar zaman kaybetmek istemem () kayıtlı yüklenir. Mipmap oluşturma kullanarak denedim, ama bir spritesheet. Fayans yerleştirildiği hakkında bilgi yok, mipmap oluşturma işe yaramaz ve bu sorunu çözmedi.
Köşeler
Biz her pozisyon döngü. Kayan henüz puan, ama bir pozisyon Vector3 (Float3).
for (UInt16 x = 0; x < _width; x )
{
for (UInt16 y = 0; y < _heigth; y )
{
[...]
position.z = priority; // this is a byte 0-5
Karolar, aşağıdaki kodu konumlandırmak için kullanılır:
tilePosition.X = position.X;
tilePosition.Y = position.Y position.Z;
tilePosition.Z = position.Z;
Bildiğiniz gibi, 32 bit, hassasiyet için 24 bit ile yüzer. Z en fazla bit değeri 8 bit (5 = 00000101). X ve Y için maksimum değerleri 16 bit olabilir. 24 bit. Hiçbir şey yüzen puan açısından yanlış gidebileceğini düşündüm.
this.Position = tilePosition;
Köşe ayarladığınızda, aşağıdaki gibi hepsi aynı kiremit pozisyonda)
Vector3[] offsets = new Vector3[] { Vector3.Zero, Vector3.Right,
Vector3.Right (this.IsVertical ? Vector3.Forward : Vector3.Up),
(this.IsVertical ? Vector3.Forward : Vector3.Up) };
Vector2[] texOffset = new Vector2[] { Vector2.Zero, Vector2.UnitX,
Vector2.One, Vector2.UnitY };
for (int i = 0; i < 4; i )
{
SetVertex(out arr[start i]);
arr[start i].vertexPosition = Position offsets[i];
if (this.Tiles[0] != null)
arr[start i].texturePos1 = texOffset[i] * this.Tiles[0].TextureWidth;
if (this.Tiles[1] != null)
arr[start i].texturePos2 = texOffset[i] * this.Tiles[1].TextureWidth;
if (this.Tiles[2] != null)
arr[start i].texturePos3 = texOffset[i] * this.Tiles[2].TextureWidth;
}
Shader
Gölgelendirici animasyonlu fayans ve Fayans statik çizebilirsiniz. Her ikisi de aşağıdaki sampler devlet kullanın:
sampler2D staticTilesSampler = sampler_state {
texture = <staticTiles> ; magfilter = POINT; minfilter = POINT;
mipfilter = POINT; AddressU = clamp; AddressV = clamp;};
Gölgelendiricinin farklı sampler Birleşik Devletleri, Biz de bizim kod yok set yok.
Her, biz alfa değeri siyah piksel yok) aşağıdaki satırı kullanarak klip geçirir
clip(color.a - alpha)
Alfa katı Kat 1 ve 1neredeyseBaşka bir katman için 0. Bu alfa bir kısmını ise, alt tabaka ne bilemeyiz çünkü) sürece çizilmiş olması anlamına gelir.
Kamera
Kullandığımız kamera için mimik arama tepeden aşağı fayans, yapma gibi görünen düz, kullanarak z değeri için onlara katman dış katman veri (3 kat değil, her zaman doğru sipariş). Bu da gayet iyi çalışıyor. Kamera güncellemeleri dönüşüm matrisi. Böyle garip bir yapısı var neden merak ediyorsanız.AddChange - kodu Tamponlu Çift (bu da çalışır). Dönüşüm matrisi aşağıdaki gibi oluşturulur
// First get the position we will be looking at. Zoom is normally 32
Single x = (Single)Math.Round((newPosition.X newShakeOffset.X) *
this.Zoom) / this.Zoom;
Single y = (Single)Math.Round((newPosition.Y newShakeOffset.Y) *
this.Zoom) / this.Zoom;
// Translation
Matrix translation = Matrix.CreateTranslation(-x, -y, 0);
// Projection
Matrix obliqueProjection = new Matrix(1, 0, 0, 0,
0, 1, 1, 0,
0, -1, 0, 0,
0, 0, 0, 1);
Matrix taper = Matrix.Identity;
// Base it of center screen
Matrix orthographic = Matrix.CreateOrthographicOffCenter(
-_resolution.X / this.Zoom / 2,
_resolution.X / this.Zoom / 2,
_resolution.Y / this.Zoom / 2,
-_resolution.Y / this.Zoom / 2,
-10000, 10000);
// Shake rotation. This works fine
Matrix shakeRotation = Matrix.CreateRotationZ(
newShakeOffset.Z > 0.01 ? newShakeOffset.Z / 20 : 0);
// Projection is used in Draw/Render
this.AddChange(() => {
this.Projection = translation * obliqueProjection *
orthographic * taper * shakeRotation; });
Akıl ve Akış
Karo veri 3 kat vardır. Her karo IsSemiTransparent
ile tanımlanır. Bir karo olduğunda IsSemiTransparent
, sonra IsSemiTransparent
çizilmiş olması gerekiyor. Karo veri SplattedTile
bir örnek üzerinde yüklü olduğunda yığılmış. Eğer katman kiremit veri boşsa bile, SplattedTile
katman ilk katman, (verilen en az bir katman kiremit veri var) çini veri olacak. Nedeni Z-buffer
eğer arkasında sağlam bir piksel olabilir hiçbir beri sırayla çizilmiş, onlar ile uyum için ne olduğunu bilmiyor.
Katmanları z bir değeri YOK, tek tek çini veri vardır. Zemin karo, Priority = 0
. Aynı döşemeleri ile 34 ** katman (çizim sırası) ve sayede donukluk (yarı saydam, opak sonra) sipariş edilebilir. Farklı bir öncelik ile taşlar kendi önceliklerine göre çekilecek.
İlk katı katman hedef piksele sahip, DestinationBlend.Zero
bunu aldım. Ayrıca alphablend için bir şey olmadığından AlphaBlending
, ihtiyacı yok. Diğer katmanları (5, 2 katı, 3 şeffaf) zaten ve buna göre uyum renk verileri ihtiyaç olduğunda çizilmiş olabilir.
6 geçirir yineleme önce, projection matrix
ayarlanır. Hayır konik kullanırken, bu çalışıyor. Bir konik kullanırken değil.
Sorun
Konik uygulayarak biraz daha derinlik taklit etmek için, bazı matrisi kullanarak istiyoruz. Bazı değerler denedik ama bu bir örnek:
new Matrix(1, 0, 0, 0,
0, 1, 0, 0.1f,
0, 0, 1, 0,
0, 0, 0, 1);
Ekran (yükseklik değeri 0, tüm düz malzeme ile her şeyi) sıkılmış olacak. Alt y (ekran üzeri), fazla sıkılmış. Bu gerçekten çalışıyor, ama şimdi rastgele siyah çizgiler hemen hemen her yerde görünür. Birkaç fayans dışlamak gibi görünüyor, ama bu ilişki göremiyorum. Bir şey aradeğerleme veya mipmaps ile bir ilgisi olabileceğini düşünüyoruz.
Ve burada neden söz ettiğimi göstermek için bir görüntü:
.
Kiremit değil etkilenen alt tabaka üzerinde statik fayans gibi görünüyor.Ancak, bu konuda en şeffaf fayans diğer grafik eserler göstermek. Satır satır sadece silinmiş, bu yüzden () özlüyorlar.Ne için bir ipucu olduğunu düşünüyorum, çünkü bu metin işaretledim.dikeyçizgiler Linear
39 *koyarsanız görünür.
Burada bir resim (oyun zoom) yakınlaştırma veya 3 katman 2 çini obje gösteriyor
Biz zaten denedik
Point
Linear
mipfilter
- Orijinal dokular üzerinde
GenerateMipMaps
ayarı - Oluşturulan dokular (
RenderTarget
gerçek bayrak kurucu)GenerateMipMaps
ayarı - Mipmap oluşturma açma (sadece mipmapping a spritesheet olduğum için uzaklaştırıldığında daha fazla eser verdi.
- Çizim katman 2 ve 3 (Bu aslında TÜM taşlar siyah çizgiler var yapar)
DepthBufferEnable = false
SrcBlend = One;
DestBlend = Zero;
tüm katı katmanları ayarı- *
DestBlend = InvSrcAlpha;
*50 tüm katı katmanları ayarı - Saydam tabaka çizim (çizgiler hala orada).
clip(opacity)
shader
kaldırılıyor. Bu sadece bazı satırlar kaldırır. Bu da araştırıyoruz.- Msdn, stackoverflow aynı sorun için arama ve google (hiç şans) kullanarak.
Kimse bu sorunu kabul ediyor mu? Son bir not, fayans çizdikten SONRA SpriteBatch
çağrı yapıyoruz ve avatarlar (yükseklik ^ oldukları için sorun yok. Shader
başka bir kullanım 0). Bu bizim sampler state
Geri Al? Ya da...?
CEVAP
Son resmin altındaki taşa bak - kumlu-renkli çizgiler geçiyor. Muhtemelen, önce kum, sonra da üzerine Kaya çizim.
Bu "siyah çizgiler" dokular aracılığıyla, ama doku parçaları çizilmiş. çizilmiş ibaret olmadığını söylüyor Sen dikey streç zaman olur bu yana, bu neredeyse kesinlikle yeni Piksel piksel eski bir eşleme oluşturmak demektir, değerleri, yeni doku arasındakileri interpolasyon olmadan.
Örneğin, eşleme kullanarak (x,y) --> (x, 2y)
puan (0,0) --> (0,0)
, (0,1) --> (0,2)
ve (0,2) --> (0, 4)
gibi eşleştirilmiş olacak. Kaynak doku ve sayı yok (0,1)
(0,3)
göster dikkat edin. Bu arka plan yayılması neden olur. Eğer horizonally germek için değiştirirseniz, dikey çizgiler göreceksiniz eminim.
Yapmak için ne gerekir başka yolu göster: hedef doku, her piksel için verilen, kaynak görüntü dönüşüm yukarıda. tersini kullanarak değerini bulmak Muhtemelen değerler eklemek istiyorum, böylece kesirli değerler piksel koordinatlarını alacaksınız.
JAY ile hiç aşina değilim, ama muhtemelen elle daha bunu yapmak için daha uygun bir yol var.
Süreli Düz Eski Java nesneleri(POJO) t...
Nesneleri imha etmek ve onları boş ola...
Otomatik olarak çizim farklı renkli çi...
Neden std::map kırmızı-siyah ağaç olar...
StringBuilder sınıfı nasıl uygulanır? ...