Sprite ve metin efektleri
2D sprite'larda ve metinde gölge, dış çizgi, parlama ve bulanıklık; her birinin maliyeti, hareket eden bir sprite'a ne yaptığı ve yerini aldığı elle yazılmış tarif.
Bunun amacı ne#
Şimdiye kadar 2D bir sprite bir ton ve bir görüntü taşıyabiliyordu, başka hiçbir şey değil. Bir karakteri arka planından ayırmak için efekti elle kurmanız gerekiyordu: ikinci bir sprite oluşturmak, onu siyaha boyamak, kaydırmak, arkaya koymak ve her tek karede birinciyle eşgüdümlü tutmak. İşe yarıyor. Aynı zamanda karakter başına dört fazladan muhasebe satırı, ve bunlardan birini unuttuğunuz gün gölge, sahibinin arkasından sürüklenir.
Dört komut bunu sizin için yapar, hem sprite'larda hem metinde:
hero = LoadSprite("hero.png")
SpritePosition(hero, 160, 120)
SpriteShadow(hero, 4, 4, 6, 128) ' offset x, offset y, softness, opacity
SpriteOutline(hero, 2, 255, 255, 255) ' thickness, colour
SpriteGlow(hero, 0, 240, 255, 8) ' colour, size
DO
Sync()
LOOP
Bakılacak başka hiçbir şey yok. Sprite'ı hareket ettirin, ölçeklendirin, çevirin, animasyonunu oynatın: efektler onu izler.
Dört efekt#
Gölge#
SpriteShadow(spriteID, offsetX, offsetY, softness, opacity)
SpriteShadowColor(spriteID, red, green, blue)
offsetX ve offsetY, SpritePosition ile aynı şekilde sayılan, kendi ekran
birimlerinizdedir: pozitif Y aşağı gider. softness gölgeyi yayar;
opacity 0'dan 255'e gider. Renk, siz başka bir şey söylemedikçe siyahtır.
SpriteShadow(hero, 3, 5, 4, 110)
SpriteShadowColor(hero, 20, 0, 40) ' a cold shadow, not a grey one
0 opaklıktaki bir gölge, gölge değildir. Onu kapatmanın yolu budur.
Dış çizgi#
SpriteOutline(spriteID, thickness, red, green, blue)
Dış çizgi, sprite'ın yaşadığı dikdörtgeni değil, silüetini izler: saydam bir PNG, dosyanın etrafında değil, çizimin etrafında bir dış çizgi alır. Kalınlık ekran birimindedir, ve 1'den 3'e kadar olan aralık kullanışlıdır. Bunun ötesinde, dış çizginin inşa edildiği sekiz yön sekiz kulakçık olarak görünmeye başlar.
SpriteOutline(hero, 2, 255, 255, 255) ' the readable-on-anything outline
SpriteOutline(hero, 0, 0, 0, 0) ' off
Parlama#
SpriteGlow(spriteID, red, green, blue, size)
Silüetin size birim ötesine yayılan renkli bir hale. Sprite'ın arkasında,
gölgenin önünde durur; ikisini birlikte kullanmanızı sağlayan da budur.
SpriteGlow(pickup, 255, 210, 0, 10) ' this one is worth walking to
Bulanıklık#
SpriteBlur(spriteID, radius)
Bulanıklık, diğer üçünden farklıdır. Diğer üçü sprite'ın etrafına çizilir; bulanıklık, sprite'ın kendi görüntüsünü bulanık bir kopyasıyla değiştirir. Bu, bilinmeye değer iki şey demektir:
- kare başına hiçbir şeye mal olmaz (bulanık görüntü bir kez hesaplanır), ve
- bulanıklık, görüntünün kenarında kırpılır. PNG'sinin kenarına değen bir çizim, dışarı taşacak halesinin o parçasını kaybeder. Bulanıklaştırmayı düşünüyorsanız, dosyada birkaç piksel saydam boşluk bırakın.
SpriteColor, bulanık bir sprite üzerinde çalışmaya devam eder.
Hepsini kapatmak, ve geri açmak#
SpriteEffects(spriteID, 0) ' all four off
SpriteEffects(spriteID, 1) ' all four back, exactly as they were
SpriteEffects, ayarlarınızı silmez. Bir sıfırlama değil, bir anahtardır; bu
yüzden bir karakter, gölgesini sonradan yeniden bildirmenize gerek
kalmadan yanıp sönebilir.
Metinde aynı dört efekt#
score = CreateText("SCORE 0")
TextPositionSet(score, 10, 10)
TextSizeSet(score, 6)
TextOutline(score, 3, 0, 0, 0) ' readable on any background
TextShadow(score, 2, 2, 4, 160)
TextGlow(score, 255, 80, 0, 6)
TextBlur(score, 0)
TextEffects(score, 1)
İmzalar, sprite olanlarla tam olarak eşleşir, yani öğrenilecek yeni bir şey yok. Davranışta iki fark var:
- Bir parlama, bir gölgenin yumuşaklığını geçersiz kılar. İkisi de aynı mekanizmayla çizilir, ve yumuşaklığı olmayan bir parlama görünmezken yumuşaklığı olmayan bir gölge yine de bir gölgedir. İkisini birden istediğinizde, yumuşaklığı alan parlamadır.
- Bunlar vektör metne uygulanır, bitmap yazı tipi metnine değil.
TextFontImageile çizilen bir metin, sprite'lardan oluşan bir bileşimdir; komutlar onun üzerinde sessizce yok sayılır. Bu durumda SPRITE efektlerini sprite'ların üzerinde kullanın.
Çözümlü bir örnek: her şeyin üzerinde okunaklı#
Bu komutların gerçekte çözdüğü sorun, kontrol edemediğiniz bir kontrasttır. Beyaz bir skor karda görünmezdir; siyah bir skor gecede görünmezdir. Bir dış çizgi bunu bir kez çözer, çizeceğiniz her arka plan için.
CreateText(1, "SCORE 0")
TextPositionSet(1, 10, 10)
TextSizeSet(1, 8)
TextColorSet(1, 255, 255, 255, 255)
TextOutline(1, 3, 0, 0, 0)
hero = LoadSprite("hero.png")
SpriteName(hero, "hero")
SpriteShadow(hero, 4, 6, 5, 120)
SpriteOutline(hero, 2, 255, 255, 255)
points = 0
DO
points = points + 1
TextString(1, "SCORE " + Str(points))
Sync()
LOOP
Bir efekti geri okumak#
Yazdığınız her parametrenin, SpriteColor'ın SpriteColorRed'e sahip
olduğu gibi, bir okuyucusu vardır. Bu, lehçenin kuralıdır, ve bu komutlar
onu izler.
IF SpriteEffectsEnabled(hero) = 1
SpriteEffects(hero, 0)
ENDIF
alpha = SpriteShadowAlpha(hero) ' 0 to 255
size = SpriteGlowSize(hero) ' 0 means no glow
Tam küme, aile başına: SpriteShadowOffsetX, SpriteShadowOffsetY,
SpriteShadowBlur, SpriteShadowAlpha, SpriteShadowColorRed,
SpriteShadowColorGreen, SpriteShadowColorBlue, SpriteGlowRed,
SpriteGlowGreen, SpriteGlowBlue, SpriteGlowSize,
SpriteOutlineThickness, SpriteOutlineRed, SpriteOutlineGreen,
SpriteOutlineBlue, SpriteBlurRadius, SpriteEffectsEnabled, artı aynı on
yedisinin başına Text eklenmiş hali.
Bilinmeye değer iki kural:
- Hiç efekt verilmemiş bir sprite, kendini AÇIK olarak bildirir. Bu varsayılan durumdur; 0 yanıtlamak, bir programa henüz hiçbirini ayarlamadan efektlerinin kesildiğini söylerdi.
- Var olmayan bir sprite'a sormak 0 yanıtlar, programı durdurmaz.
Lehçenin her yerde soruları ele alma biçimi budur:
SpriteHit, hiçbir şeye değilmediğinde 0 yanıtlar, ve programlar bu 0'ı test etmeden okur.
Bunun maliyeti#
Gölge, dış çizgi ve parlama çizilir, bu yüzden çizim çağrılarına mal olurlar: gölge için bir (yumuşak olduğunda üç), bir parlama için dört, bir dış çizgi için sekiz. Dış çizgili iki yüz sprite'lık bir ekran, bin sekiz yüz dörtgen çizen bir ekrandır, ve bu görülür. Bunlar, oyuncunun bakması gereken bir avuç şey için tasarlanmıştır: karakter, toplanabilir eşya, seçili birim.
Bulanıklık kare başına hiçbir şeye mal olmaz.
Pratik bir kural: hareket eden ve önemli olan şeyde efekt, arka planda hiç.
Dışa aktarılan bir oyuna geçen şey#
| Hedef | Gölge, dış çizgi, parlama | Bulanıklık | Metin efektleri |
|---|---|---|---|
| Editör | evet | evet | evet |
| HTML5 dışa aktarımı | evet | evet | evet |
| Native ve wasm (Bevy) | evet | hayır | hayır |
Gölge, dış çizgi ve parlama sıradan sprite'lardan yapılmıştır, bu yüzden sprite'ların gittiği her yere giderler. Bulanıklık ve metin efektleri, Bevy hedeflerinin henüz sahip olmadığı bir köprüye ihtiyaç duyar: dışa aktarımın dönüştürme raporu, onları sessizce düşürmek yerine adlandırır; bu yüzden bir derleme size neyi taşıyamadığını söyler.
Efektlerin olmadığı yer#
Efekt adını bir dize olarak alan bir SpriteEffect(id, "glow", ...) yoktur.
Her efekt kendi komutudur, böylece parametreleri yazarken adlandırılabilir,
belgelenebilir ve tamamlanabilir. Bu dördünün ötesinde, iki komut daha devreye
girer: katkılı ya da çarpımsal karışım için (bir ateş, bir lazer)
SpriteBlendModes(id, src, dst), ve LoadSpriteShader tarafından derlenmiş
bir shader'ı bir sprite'a koymak için SpriteShader(id, shaderID). İkisi de
uzun süre uygulamasız olarak katalogda tanımlıydı ve çağrılmaları bir hata
yükseltiyordu; artık çalışıyorlar.