前の記事
完成図
だいぶレイアウトが変わりました。
プレビュー機能作成
作成したグラフを使うとどのような挙動をするのかをすぐに確認できたらいいなーと思い作りました。
グラフの値に応じて黒い四角形が移動、回転、拡大縮小、フェードインフェードアウトを行うようにしました。
拡大縮小の実装方法はこちら
描画更新のタイミング変更
いままではなにかの値が変わるたびに描画を更新してました。
ですがその実装だと複数の値が同時に変わった時に無駄な描画を更新するのを対策しないといけないため実装がすこし大変でした。
そこでゲームと同じように1/60秒ごとに描画を更新することで描画の更新タイミングを気にしなくていいようになりました。
public Form1() { CompositionTarget.Rendering += RenderFrame; } //再生中の挙動 private void RenderFrame(object sender, EventArgs e) { m_preview.Update(); pictureBox1.Refresh();//再描画(グラフ用); pictureBox4.Refresh();//再描画(回転用); }
ソースコード
プレビュー機能部分だけ
using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using System.Threading; using System.Diagnostics; namespace CurveEditor { class Preview { double m_TotalTime = 0;//動いている時間 double m_MoveTime = 1000;//一回の卯木気にかける時間 double m_MoveRatio = 0;//今どのくらい時間がたってるかの割合 bool m_isLoop = true;//動きをループさせるか bool m_isInversion = false;//動きを反転させるか VerticalLine m_VLine;//縦線 System.Diagnostics.Stopwatch m_Stopwatch = new Stopwatch(); //時間を測る PointRender m_PointRender;//グラフを読み込む機能 int movecnt = 0;//何フレーム目 const decimal EndPosX = 470; const int PictureBoxSize = 50;//画像サイズ PictureBox[] m_PictureBox = new PictureBox[4]; int m_NextScale = 0;//次の画像サイズ float m_NextAngle = 0;//次の画像の角度 Image img2 = Properties.Resources.yazirusi; Bitmap bmp; //画像の種類 enum ePnum { eMove = 0, eScale, eRot, ea, }; public void SetP(PictureBox p,int i = 0) { m_PictureBox[i] = p; } public Preview() { bmp = new Bitmap(img2, 50, 50); } public void StartTimer() { m_Stopwatch.Restart(); m_TotalTime = 0; FindRatio(); m_VLine.SetX(m_MoveRatio); movecnt = 0; } public void StopTimer() { // m_TotalTime = 0; FindRatio(); m_VLine.SetX(m_MoveRatio); m_Stopwatch.Reset(); } //毎フレーム呼ばれる public void Update() { if (!m_Stopwatch.IsRunning) return; //端まで行ったら if(m_TotalTime >= m_MoveTime) { m_TotalTime = 0; if(m_isLoop) { m_Stopwatch.Restart(); movecnt = 0; } else { StopTimer(); } return; } m_TotalTime = m_Stopwatch.ElapsedMilliseconds; if (movecnt == 0) m_TotalTime = 0;//一回目のデータ読み込みは強制0 FindRatio(); m_VLine.SetX(m_MoveRatio); MovePictureBox(); movecnt++; } //グラフに沿ってPictureBoxを動かす public void MovePictureBox() { if (!m_Stopwatch.IsRunning) return; //Yを求める decimal y = m_PointRender.EvaluateY((decimal)m_MoveRatio); y = Math.Min(1, y); y = Math.Max(0, y); //移動 int nextpos = (int)(y * EndPosX); m_PictureBox[(int)ePnum.eMove].Location = new Point(nextpos, 15); //スケール m_NextScale = (int)(y * PictureBoxSize); ScalingPictureBox(); //回転 m_NextAngle = (float)(y * 360 * 1); //アルファ int nextcolor = (int)(255 * y); m_PictureBox[(int)ePnum.ea].BackColor = Color.FromArgb(nextcolor, 0,0,0); } public void FindRatio() { m_TotalTime = Math.Min(m_TotalTime, m_MoveTime); m_MoveRatio = m_TotalTime / m_MoveTime; } public void SetVLine(VerticalLine v) { m_VLine = v; } public void SetIsLoop(bool loop) { m_isLoop = loop; } public bool GetIsLoop() { return m_isLoop; } public void SetisInversion(bool inversion) { m_isInversion = inversion; } public void SetMoveTime(float Second) { double time = Second * 1000; m_MoveTime = time; } public void SetPointRender(PointRender p) { m_PointRender = p; } //次の回転取得 public int GetScale() { return m_NextScale; } //次の角度種t九 public float GetAngle() { return m_NextAngle; } public void Paint(Graphics g) { if (!m_Stopwatch.IsRunning) return; } //画像の拡大縮小 public void ScalingPictureBox() { m_PictureBox[(int)ePnum.eScale].Height = m_NextScale; m_PictureBox[(int)ePnum.eScale].Width = m_NextScale; Point centerPos = new Point(170, 80);//中心の座標 Point pos = new Point(0, 0); //中心から拡大させる pos.X = (centerPos.X - m_PictureBox[(int)ePnum.eScale].Width) / 2; pos.Y = (centerPos.Y - m_PictureBox[(int)ePnum.eScale].Height) / 2; m_PictureBox[(int)ePnum.eScale].Location = pos; } /// <summary> /// ビットマップ(Bitmap)を回転する画像取得 /// </summary> /// <param name="angle">回転角度</param> /// <returns></returns> public Bitmap GetRotateBitmap( float angle =0 ) { return bmp; } } }
終わりに
次はグラフの編集機能を強化していきたいです。
次の記事