アニメ『Re:CREATORS(レクリエイターズ)』
人が創造したはずのアニメの世界の住人が現実世界に現れて、てんやわんやになるってアニメっぽいです。
最近Re:から始まるタイトルをよく目にしますが、Re:って、~についてという意味だったと記憶してますが、そんなことはどうでもよく、Re:がつくとなんかかっこいい気がします。
ではドミノエディタの続きです。今回は描いた線に合わせて、このように斜めのドミノを自動で配置してみます。
考えなしに、プログラミングをしてますので、ぐっちゃぐちゃです。少しだけリファクタリングします。
まずは一番ひどい場所から。
new private void DragEnter(object sender, DragEventArgs e){ Matrix b = (Matrix)sender; string x_y = (string)e.Data.GetData(typeof(String)); char[] delim={','}; string[] pos=x_y.Split(delim,StringSplitOptions.None); if((int.Parse(pos[0]) == b.x) && (int.Parse(pos[1]) != b.y) ){ b.Image = Image.FromFile(basedir + img[1]); }else if((int.Parse(pos[1]) == b.y) && (int.Parse(pos[0]) != b.x) ){ b.Image = Image.FromFile(basedir + img[2]); } e.Data.SetData(""+b.x + "," + b.y); }
e.Data.GetDataで取得する文字列は、ドラッグ元のButtonの座標が入っていますが、わざわざ文字列にしなくても、Buttonオブジェクトをそのまま渡していまえばよいです。
このように修正することにしました。
new private void DragEnter(object sender, DragEventArgs e){ Matrix now = (Matrix)sender; Matrix last = (Matrix)e.Data.GetData(typeof(Matrix)); if((last.x == now.x) && (last.y != now.y) ){ now.Image = Image.FromFile(basedir + img[1]); }else if( (last.y == now.y) && (last.x != now.x) ){ now.Image = Image.FromFile(basedir + img[2]); } e.Data.SetData((Matrix)now);
次に画像を設定するこのようなソースですが、
now.Image = Image.FromFile(basedir + img[1]);
やってることは画像の設定ですが、もう少しオブジェクト指向っぽく考えると、ドミノを置いていることになります。
Matrixのクラスにドミノ設定を組み込んでしまいましょう。
now.SetDominoUp2Down();
こんな風に書き換えました。当然クラスが変更になります。
Matrixは、シンプルなButtonの派生でしたが、
class Matrix : Button{ public int state = 0; public int x; public int y; }
このようになりました。
class Matrix : Button{ public int state = 0; public int x; public int y; public int dx; public int dy; string basedir="c:\\Users\\takk\\Desktop\\img\\"; public void SetDominoUp2Down(){ Image = Image.FromFile(basedir + "domino-tate.png"); state = 1; } public void SetDominoLeft2Right(){ Image = Image.FromFile(basedir + "domino-yoko.png"); state = 2; } public void SetDominoDown2Left(){ Image = Image.FromFile(basedir + "domino-cv1.png"); state = 3; } public void SetDominoDown2Right(){ Image = Image.FromFile(basedir + "domino-cv2.png"); state = 4; } public void SetDominoUp2Right(){ Image = Image.FromFile(basedir + "domino-cv3.png"); state = 5; } public void SetDominoUp2Left(){ Image = Image.FromFile(basedir + "domino-cv4.png"); state = 6; } }
ボタンの中にファイル名が埋め込まれているのが、むしろ改悪な感じではありますが、とりあえずこんな形で修正を進めます。
最後に、ドラッグ方向が変わった時に、ドミノの方向を変える処理を埋め込みます。
DragEnterメソッドの最後に追加します。
if(last.state == 0){ if((now.x == last.x) && (now.y != last.y)){ last.SetDominoUp2Down(); }else if((now.y == last.y) && (now.x != last.x)){ last.SetDominoLeft2Right(); } }else if(last.state != now.state){ if((last.dx == 1) && (last.y < now.y)) last.SetDominoDown2Left(); if((last.dx == 1) && (last.y > now.y)) last.SetDominoUp2Left(); if((last.dx == -1) && (last.y < now.y)) last.SetDominoDown2Right(); if((last.dx == -1) && (last.y > now.y)) last.SetDominoUp2Right(); if((last.dy == 1) && (last.x < now.x)) last.SetDominoUp2Right(); if((last.dy == 1) && (last.x > now.x)) last.SetDominoUp2Left(); if((last.dy == -1) && (last.x < now.x)) last.SetDominoDown2Right(); if((last.dy == -1) && (last.x > now.x)) last.SetDominoDown2Left(); } if(last.x < now.x){ now.dx= 1; } if(last.x > now.x){ now.dx=-1; } if(last.y > now.y){ now.dy=-1; } if(last.y < now.y){ now.dy= 1; }
last.state が0のときは、ドラッグの起点を表してますので、縦か横かだけの判定にしています。
last.stateとnow.stateが違うときは、ドラッグ方向が変わってますので、ドラッグ元のドミノの配置を斜めにします。
最後のnow.dxやnow.dyへの1または-1の代入は、ドラッグの方向を覚えておくための処理です。
まだ直し甲斐のあるソースではありますが、修正後の全ソースです。
using System; using System.Drawing; using System.Windows.Forms; class Matrix : Button{ public int state = 0; public int x; public int y; public int dx; public int dy; string basedir="c:\\Users\\takk\\Desktop\\img\\"; public void SetDominoUp2Down(){ Image = Image.FromFile(basedir + "domino-tate.png"); state = 1; } public void SetDominoLeft2Right(){ Image = Image.FromFile(basedir + "domino-yoko.png"); state = 2; } public void SetDominoDown2Left(){ Image = Image.FromFile(basedir + "domino-cv1.png"); state = 3; } public void SetDominoDown2Right(){ Image = Image.FromFile(basedir + "domino-cv2.png"); state = 4; } public void SetDominoUp2Right(){ Image = Image.FromFile(basedir + "domino-cv3.png"); state = 5; } public void SetDominoUp2Left(){ Image = Image.FromFile(basedir + "domino-cv4.png"); state = 6; } } class Test : Form{ const int xlen=20; const int ylen=16; const int bsize=44; Matrix[,] mat = new Matrix[xlen,ylen]; Test(){ this.Size = new Size((bsize+1)*xlen,(bsize+1)*ylen); for(int x=0;x<xlen;x++){ for(int y=0;y<ylen;y++){ mat[x,y] = new Matrix(); mat[x,y].x = x; mat[x,y].y = y; mat[x,y].Parent = this; mat[x,y].Location = new Point(bsize*x,bsize*y); mat[x,y].Size = new Size(bsize,bsize); mat[x,y].AllowDrop = true; mat[x,y].MouseDown += MouseDown; mat[x,y].DragEnter += DragEnter; } } } new private void MouseDown(object sender, MouseEventArgs e){ Matrix b = (Matrix)sender; b.DoDragDrop((Matrix)sender, DragDropEffects.Copy | DragDropEffects.Move); } new private void DragEnter(object sender, DragEventArgs e){ Matrix now = (Matrix)sender; Matrix last = (Matrix)e.Data.GetData(typeof(Matrix)); if((last.x == now.x) && (last.y != now.y) ){ now.SetDominoUp2Down(); }else if( (last.y == now.y) && (last.x != now.x) ){ now.SetDominoLeft2Right(); } e.Data.SetData((Matrix)now); if(last.state == 0){ if((now.x == last.x) && (now.y != last.y)){ last.SetDominoUp2Down(); }else if((now.y == last.y) && (now.x != last.x)){ last.SetDominoLeft2Right(); } }else if(last.state != now.state){ if((last.dx == 1) && (last.y < now.y)) last.SetDominoDown2Left(); if((last.dx == 1) && (last.y > now.y)) last.SetDominoUp2Left(); if((last.dx == -1) && (last.y < now.y)) last.SetDominoDown2Right(); if((last.dx == -1) && (last.y > now.y)) last.SetDominoUp2Right(); if((last.dy == 1) && (last.x < now.x)) last.SetDominoUp2Right(); if((last.dy == 1) && (last.x > now.x)) last.SetDominoUp2Left(); if((last.dy == -1) && (last.x < now.x)) last.SetDominoDown2Right(); if((last.dy == -1) && (last.x > now.x)) last.SetDominoDown2Left(); } if(last.x < now.x){ now.dx= 1; } if(last.x > now.x){ now.dx=-1; } if(last.y > now.y){ now.dy=-1; } if(last.y < now.y){ now.dy= 1; } } [STAThread] public static void Main(){ Application.Run(new Test()); } }
これでペンタブで、自由に描いてドミノ配置できるようになりました。
マトリクスを増やして、試し描きしてみました。
ペンタブですらすらドミノが配置できます。
しかし描いてから、セーブ機能を追加していないことに気が付きました。
コメント