「ちらつき」を無くす-1

Sprite を切り替える の演習「タイマ設定でアニメーション」のプログラムが完成したでしょうか。
実行すれば解るのですが、時々「画面がチラツク」でしょう。 (^_^;)
これではせっかくのアニメーションも台無しです。
ここではアニメーションしたときの「ちらつき」を無くす方法を説明します。
画面がチラツク直接の原因は Frame が背景色でクリアされることです。
これを無くせばチラツキを抑えられます。 \(^o^)/
VC++ では InvalidateRect() のパラメータで設定したのですが、C# では勝手が違うようです。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プロジェクトの設定

  1. 空のプロジェクトを作成して、ソースプログラムをプロジェクトに取り込んで下さい。
  2. 大きな画像から Sprite を切り出して、タイマの設定で Sprite を切り替えます。
    このようなプログラムでは MyHandler() で毎回ファイルからイメージをロードするのでは如何にも無駄です。 (^_^;)
    画像のロードの説明は Sprite を切り替える を参照して下さい。
  3. Sprite を描画するメソッドは Frame Class の OnPaint() をオーバーライドしています。
    描画は bmp にロードした画像から Sprite を切り出します。
        protected override void OnPaint(PaintEventArgs e)
        {
            if (bmp == null)
            {
                Application.Exit();
                return;
            }
            base.OnPaint(e);
            Graphics g = e.Graphics;
            g.DrawImage(bmp,new Rectangle(80,10,128,216),new Rectangle(SP_NO*128,0,128,216),GraphicsUnit.Pixel);
        }
        
  4. 肝心の「チラツキ」を無くす方法です。
    背景のクリアは Frame Class の OnPaintBackground() で行われます。
    これをオーバーライドして、何も行わなければ良いのです。
        protected override void OnPaintBackground(PaintEventArgs e)
        {
        }
        
  5. CLI の環境で実行可能な完成したプログラムです。
    /***************************************************************/
    /*★ OnPaint() をオーバーロードしてアニメーション    前田 稔 ★*/
    /***************************************************************/
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    public class MyForm : Form
    {
        private Timer timer1;
        private System.ComponentModel.IContainer components;
        Bitmap  bmp= null;
        int     SP_NO;
    
        public MyForm()
        {
            // timer1
            components = new System.ComponentModel.Container();
            timer1 = new System.Windows.Forms.Timer(this.components);
            SuspendLayout();
            timer1.Interval = 200;
            timer1.Tick += new System.EventHandler(this.timer1_Tick);
            // MyForm
            Name = "MyForm";
            // Load Image
            try
            {
                 bmp= new Bitmap("c:\\data\\test\\girl.gif");
            }
            catch
            {   MessageBox.Show("イメージが取得できません", "Error");
                return;
            }
            SP_NO = 0;
            timer1.Start();
        }
    
        protected override void OnPaint(PaintEventArgs e)
        {
            if (bmp == null)
            {
                Application.Exit();
                return;
            }
            base.OnPaint(e);
            Graphics g = e.Graphics;
            g.DrawImage(bmp,new Rectangle(80,10,128,216),new Rectangle(SP_NO*128,0,128,216),GraphicsUnit.Pixel);
        }
    
        protected override void OnPaintBackground(PaintEventArgs e)
        {
        }
    
        private void timer1_Tick(object sender, EventArgs e)
        {
            SP_NO= (SP_NO+1)%7;
            Invalidate();
        }
    }
    
    class anime
    {
        public static void Main()
        {
            MyForm mf = new MyForm();
            Application.Run(mf);
        }
    }
    

【演習】

  1. 画面が「ちらつく」こと無く、アニメーションが出来たでしょうか。
  2. このままでは Frame の背景(描画されない部分)が変ですね。 (;_;)
    そこで最初の一度だけ Frame をクリアして下さい。
    Frame をクリアするソースコードです。
    g.Clear(Color.LightGray);
  3. また、最初に一度しか画面をクリアしないのでは、透明色の部分が重ね書きされて画像が崩れます。
    ページ先頭の透明色を使わない画像で試して下さい。

超初心者のプログラム入門(C# Frame Work)