アニメ『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());
}
}
これでペンタブで、自由に描いてドミノ配置できるようになりました。
マトリクスを増やして、試し描きしてみました。
ペンタブですらすらドミノが配置できます。
しかし描いてから、セーブ機能を追加していないことに気が付きました。


コメント