2012-07-05 5 views
21

私は、アバターが常にマウスカーソルを指して回転していることに依存するトップダウンシューティングゲームを作っています。 phiは、鋭いエッジと検出ピクセルと、画像が通常の品質でレンダリングされ、ゼロのときコンテキストをローテーションした後に画像が品質を損ねるのはなぜですか?

//Rendering. 
context.save(); //Save the context state, we're about to change it a lot. 

context.translate(position[0] + picture.width/2, position[1] + picture.height/2); //Translate the context to the center of the image. 
context.rotate(phi); //Rotate the context by the object's phi. 
context.drawImage(picture.image, -picture.width/2, -picture.height/2); //Draw the image at the appropriate position (center of the image = [0, 0]). 

context.restore(); //Get the state back. 

:私はこのような回転を達成します。しかし、phiを0以外の値に設定すると(実際には0Pi/2PiPi+Pi/2または2Pi)、画像がぼやけて見えなくなり、個々のピクセルがぼやけて見えなくなります。ここで

は(スクリーンショットの一般的な悪い品質については申し訳ありませんが、私は違いが顕著以上であることを考える)のスクリーンショットです:

enter image description here

これは、まあ、少しは受け入れられません。私はイメージが常にぼやけていることはできません! なぜこれが起こっていて、私はそれを解決できますか?

+3

元のピクセルとイメージの回転バージョンを整列させる必要があると考えると、ピクセルグリッドには一致しません。 – Randy

+0

HTML5以外のゲームではなぜそうなりませんか?私はこの日の後にドラゴンフライをしていましたが、小さなドラゴンを回転させるのに問題はありません! – corazza

+5

フラッシュはちょっと違っています。 – Daedalus

答えて

14

あなたはdocsを参照してください

context.imageSmoothingEnabled = false; 

を試みることができる:

context.imageSmoothingEnabled [=値]のパターンを埋めてのdrawImage()メソッドがあれば、画像を滑らかにしようとするかどうか

戻り値それらを再スケーリングしなければなりません(イメージを単に「大きなピクセル」でレンダリングするのではなく)。

イメージを平滑化するか(true)、または平滑化(false)するかを設定できます。

あなたは真のピクセルアートレトロなスタイルの効果をしたい場合は、手動で、いくつかの角度回転させスプライト画像を作成phiの現在の値のための適切なスプライトを調べ、回転せずに、それを描画する必要があると思います。これは明らかにかなりの量の芸術作品を必要とします!

+0

+1手動作成。ゲームの主な要素はほとんど避けられません。 – Robert

1

(picture.width/2, picture.height/2)ポイントは常に動作しません。

(Math.floor(picture.width/2) + 0.5, Math.floor(picture.height/2) + 0.5)助けてください。

+1

まだぼんやりしていません! – corazza

+1

これは、線の場合にのみ有効です。イメージの場合は正反対です。常に整数を使用します。 –

2

イメージを中心点の周りに回転させる場合は、イメージ自体に偶数ピクセルがあることを確認してください。奇数座標になったら、ターゲットキャンバスの画像データを補間する必要があります。アップルはいくつか素敵なdocumentation on translating and rotating the canvasを持っています。

したがって、上記のいずれの画像でも、丸めを使用して全画素にスナップすることができます。

このように、イメージのすべてのソースピクセルは常にキャンバス内のピクセルに描画され、ぼかしは発生しません。しかし、これは90度の倍数にのみ当てはまります。

すべてのブラウザはイメージ描画でアンチエイリアス処理を行うように思われるので、回転イメージをスプライトとして提供する必要があります。

このChromium bug reportによれば、あなたがまだそれを修正していない場合は、そこに運がよいかもしれません。読んでみると、Ian Hicksonはアンチエイリアス処理されたイメージ描画をオプションにすることに反対する可能性があることを学びます。

+0

*これは90度の倍数の場合にのみ当てはまります* Yep、そこに大きな問題があります... – corazza

+0

これはよく知られている問題で、2009年からChromiumチームで議論されました。それに応じて答えてください。 –

0

まあ、実際にそれはあなたが90度の倍数で画像を回転させる場合は何も補間が適用されないように、あなたのライブラリが十分にスマートすべき周り

得ることができないものです。

しかし、90度の倍数とは異なる角度で画像を回転させるとすぐに、補間する必要があります。結果として、あなたはそれを平滑化します。理論に興味があれば、コンピュータグラフィックや画像処理に関する本を探すことができます。

画像回転の具体的なケースでは、あなたがこの論文を見ても、 http://bigwww.epfl.ch/publications/unser9502.html

+0

-1は「あなたが逃げることのできないものです」 –

+0

私はあなたがそれを回避できると確信しています。おそらくキャンバスを使用していないかもしれませんが、C++ですが、間違いなく可能です。つまり、補間を適用せず、すべてのものを少し粗く描画します。たぶん、これらの組み合わせが最高です...また、あなたが言った文献へのリンクを提供すれば素晴らしいでしょう。 – corazza

+0

@Baneすべての原油をどのようにして解決することができますか?その結果、元のイメージに入れた小さなピクセルの詳細がすべて失われます。また、原図と補間を混在させると、結果はまだぼやけています(そして粗い)。私はまだC++をjavascriptに統合する方法を見出していませんが、もちろんC++コードをjavascriptコードに変換することは可能です。それでも、C++でピクセルを失うことなく任意のラスタ画像を回転させる実際の方法はありません。ベクトルベースの画像では、はるかに簡単です。 – Robert

0

だけヒント:あなただけのキャンバスprogrammimgを学習しているが、あなたは助けるためにImpactJsを使用できるかどうかはわかりませんあなたはレトロゲームを構築します。

+0

私は実際にそれでいくつかのゲームを構築しましたが、パターン、理論、OOPおよび一般的なコーディングに集中しました。私は本当に多くの回転を必要としたことはありませんでした。私はそれが必要なときにぼかしを気にしませんでしたが、今はエンジンを構築しています。 – corazza

+1

また、これは解答ではなくコメントに適しています。 – corazza

関連する問題