Bir sprite tuvali çevirmek

Bazı sprite'ları göstermek için tuval kullanıyorum ve bir tane yatay olarak çevirmem gerekiyor (bu yüzden sola veya sağa bakacak). Bununla birlikte, drawImage ile bunu yapmak için herhangi bir yöntem göremiyorum.

İşte benim ilgili kodum:

this.idleSprite = new Image();
this.idleSprite.src = "/game/images/idleSprite.png";
this.idleSprite.frameWidth = 28;
this.idleSprite.frameHeight = 40;
this.idleSprite.frames = 12;
this.idleSprite.frameCount = 0;

this.draw = function() {
        if(this.state == "idle") {
            c.drawImage(this.idleSprite, this.idleSprite.frameWidth * this.idleSprite.frameCount, 0, this.idleSprite.frameWidth, this.idleSprite.frameHeight, this.xpos, this.ypos, this.idleSprite.frameWidth, this.idleSprite.frameHeight);
            if(this.idleSprite.frameCount < this.idleSprite.frames - 1) { this.idleSprite.frameCount++; } else { this.idleSprite.frameCount = 0; }
        } else if(this.state == "running") {
            c.drawImage(this.runningSprite, this.runningSprite.frameWidth * this.runningSprite.frameCount, 0, this.runningSprite.frameWidth, this.runningSprite.frameHeight, this.xpos, this.ypos, this.runningSprite.frameWidth, this.runningSprite.frameHeight);
            if(this.runningSprite.frameCount < this.runningSprite.frames - 1) { this.runningSprite.frameCount++; } else { this.runningSprite.frameCount = 0; }
        }
    }

Gördüğünüz gibi, spritelarımı tuvale çekmek için drawImage yöntemini kullanıyorum. Görebileceğim bir hareketli çizgiyi çevirmenin tek yolu, tüm tuvali çevirmek/döndürmek. Yapmak istediğim şey bu değil.

Bunu yapmanın bir yolu var mı? Yoksa başka yöne bakan yeni bir sprite yapmam gerekecek mi?

20

3 cevap

Gaurav, tuvalde bir sprite çevirmenin teknik yolunu gösterdi ...

Bunu oyunun için yapmayın.

Bunun yerine, tükenmez sayfanın ters çevrilmiş bir versiyonu olan ikinci bir resim yapın (veya mevcut resminizi büyütün). "İçeriği çevirme ve bir görüntü çizme" ile "yalnızca bir görüntü çizme" arasındaki performans farkı çok büyük olabilir. Opera ve Safari'de tuvali ters çevirmek, çizimde on kat daha yavaş ve çizimde ise iki kat daha yavaştır. Örnek için bu jsPerf konusuna bakın.

Saygısız spritesinizi önceden hesaplamak her zaman daha hızlı olacaktır ve oyunların tuval performansında gerçekten önemlidir.

33
katma
Teşekkürler. Yaptığım şey, benim mevcut karakterime (altta) başka bir sprite ekleyerek diğer karaktere koşarken karakterim ekledim ve yönüne bağlı olarak bu sprite kümesini kullanmak için bir kod ekledim. Bunun gibi: i.imgur.com/uIPvF.png
katma yazar James Dawson, kaynak
İyi görünüyor! Her ne kadar yeni satırı yeniden düzenlesem de: her bir dikey olarak ters çevrilmiş versiyonunu sıraya sokun, böylece çevirdiğinizde değiştirmeniz gereken tek şey y koordinatıdır.
katma yazar Simon Sarris, kaynak
Jeff, kaydet ve geri yükleme 'nın gerekli olmadığı iyi bir noktaya yükseltiyorsunuz, ancak sonucunuz bir fluke idi, şimdi sonuçları görün. Tarayıcı, sayfayı veya Java'yı (zamanlayıcıda kullanılır) yüklemeyi bitirmeden önce testinize başlamış olabilirsiniz. Testin /4 'da doğru olmadığını iddia ediyorum çünkü çevirmek için gerekli olan iş, dönüşümü normal durumuna geri döndürecek işi de içermelidir. Bu, ctx.scale (-1,1) için en az ikinci bir çağrı anlamına gelir. İşte bu "adil" bir testtir ve saygısızdır, her tarayıcıda ve mobil cihazda daha yavaş test edilir, bazen çok fazla: jsperf.com/ctx-flip-performance/5
katma yazar Simon Sarris, kaynak
Woah! Gerçekten önemli bir şey gösterdin. Jsperf'ın kurulum işlevi bozuldu ve tuvali temizlemiyor! Açıkça olursam ne olacağını öğrenmek için jsperf.com/ctx-flip-performance/10 adresine bakın. testin içini temizleyin ve gerçekte ne olduğuna ilişkin jsfiddle.net/sX2jT konusuna bakın. scale her zaman çarpar, gördüğü jsperf ile bir hata :(
katma yazar Simon Sarris, kaynak
Gaurav'un ​​cevabı ctx.save/restore nedeniyle gerçekten sadece performans açısından pahalıdır. Aslında, ctx.scale (...) 'i her seferinde çağıracak olursanız, hileli bir şekilde daha hızlı bir şekilde çekilir: jsperf.com/ctx-flip-performance/3 . (Eğer ters çevrilmiş bir durum için ctx.scale (-1) çağırırsanız ve daha hızlı olmayan bir durum için daha hızlıdır: jsperf.com/ctx-flip-performance/4 .
katma yazar Jeff Gates, kaynak
Ben düşünmüştüm.() (Ölçeklendirme ölçeğini tersine çevirmek) ölçeğini ayarlamak. Bu çarpım, w3.org belgelerinde ( dev. Gerçekten de testi geçersiz kılan w3.org/html5/2dcontext/#dom-context-2d-scale ). ('Belirsiz' olan 'add' terimini kullanır). Ancak, en azından kromda olduğu gibi görünmüyor: jsperf.com/ctx- flip-performans/8 .
katma yazar Jeff Gates, kaynak

Tuvalin tamamını çevirmeden tuval çizim içeriğini dönüştürebilirsiniz.

c.save();
c.scale(-1, 1);

içeriği yansıtacaktır. Resminizi çizin, sonra

c.restore();

and you can draw normally again. For more information, see https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Transformations

11
katma
Teşekkür ederim! Ama Simon'ın cevabı yüzünden, tekniğini kullanacağım. Ben de cevabımı kabul ettiğim gibi kabul ettiğim cevap olarak işaretleyeceğim :)
katma yazar James Dawson, kaynak

Use this to flip your sprite sheet http://flipapicture.com/

3
katma
Ne yazık ki bu PNG'leri desteklemiyor :(
katma yazar Scott, kaynak