转载请标明是引用于 http://blog.csdn.net/chenyujing1234
例子代码:
n百变方块游戏效果如图22-1所示。用户拖动棋盘周围的8种拼块到棋盘中,直到棋盘所有空白方块格子被填满则此关游戏胜利。单击“新方块图案”按钮则进入下一关游戏。如果玩家无法完成则可以单击“参考答案”按钮查看参考拼图方案。
class CChip { Point []m_pointList; //顶点坐标 int m_nPointCount; //顶点个数 int m_nType; //类型代号 private GraphicsPath myPath; ……. }
public void SetChip(int type, Point []ppointlist, int count) { m_nType = type; m_nPointCount = count; m_pointList = new Point[m_nPointCount]; for(int i=0; i<count; i++) m_pointList[i] = ppointlist[i]; myPath = new GraphicsPath(); myPath.AddLines(m_pointList); myPath.CloseFigure();//CloseFigure方法闭合当前图形并开始新图形。 }
Move(int x_offset, int y_offset)应用Matrix实现GraphicsPath路径的平移。 public void Move(int x_offset, int y_offset) { Matrix matrix = new Matrix(); matrix.Translate(x_offset, y_offset); //追加平移 myPath.Transform(matrix);//应用变形 myPath.CloseFigure(); } Move2(int x_offset, int y_offset)不用Matrix实现GraphicsPath路径的平移,而是直接对路径的每个顶点一一平移。 public void Move2(int x_offset, int y_offset) { myPath.Reset(); //清空路径 for (int i = 0; i < m_nPointCount; i++) // 平移各顶点 { m_pointList[i].X += x_offset; m_pointList[i].Y += y_offset; } myPath.AddLines(m_pointList); myPath.CloseFigure(); }
Rotation()应用Matrix实现GraphicsPath路径的旋转,每次旋转45度。 public void Rotation() { Matrix matrix = new Matrix(); RectangleF rect = new RectangleF(); rect = myPath.GetBounds(); // 计算旋转中心坐标(x,y) double x = rect.Left + rect.Width / 2; double y = rect.Top + rect.Height / 2; //matrix.Rotate(45.0f); //旋转顺时针45度 matrix.RotateAt(45.0f, new Point((int)x, (int)y)); //旋转顺时针45度 }
Rotation2()不用Matrix实现GraphicsPath路径的旋转,而是获取myPath的矩形区域,计算旋转中心,从而计算出每个顶点的新坐标。 public void Rotation2() { RectangleF rect=new RectangleF() ; rect=myPath.GetBounds(); myPath.Reset(); //清空路径 double x = rect.Left + rect.Width/2; // 计算旋转中心 double y = rect.Top + rect.Height/ 2; double dx, dy; for (int i = 0; i < m_nPointCount; i++) // 旋转各顶点 { dx = m_pointList[i].X - x; dy = m_pointList[i].Y - y; m_pointList[i].X = (int)(x + dx * 0.7071 - dy * 0.7071); m_pointList[i].Y = (int)(y + dx * 0.7071 + dy * 0.7071); } myPath.AddLines(m_pointList); myPath.CloseFigure(); }
ReverseTurn()获取myPath的矩形区域,计算旋转中心,从而计算出水平翻转后每个顶点的新坐标。 public void ReverseTurn() // 水平反转 { RectangleF rect = new RectangleF(); rect = myPath.GetBounds(); myPath.Reset(); double x = rect.Left + rect.Width / 2; // 计算旋转中心 double y = rect.Top + rect.Height / 2; for (int i = 0; i < m_nPointCount; i++) // 水平反转各点 { m_pointList[i].X = (int)(2 * x - m_pointList[i].X); m_pointList[i].Y = m_pointList[i].Y; } myPath.AddLines(m_pointList); myPath.CloseFigure(); }
public void DrawChip(Graphics g)//画拼块 { Pen myPen = new Pen(Color.Black, 1); g.DrawPath(myPen, myPath); int alpha = 140; //透明度 Color c= Color.FromArgb(alpha, 255, 255, 255); switch (m_nType) { case 1: c = Color.FromArgb(alpha, 127, 127, 127); break; case 2: c = Color.FromArgb(alpha, 255, 0, 0); break; case 3: c = Color.FromArgb(alpha, 200, 255, 0); break; ....... case 8: c = Color.FromArgb(alpha, 228, 128, 128); break; } SolidBrush brushNew = new SolidBrush(c); g.FillPath(brushNew, myPath); }
Verity(int CHIP_WIDTH)对用户移动的拼块进行位置校正,方法是判断拼块的第一个顶点坐标m_pointList[0]接近棋盘中那个方格,则计算出偏移量后,对拼块的所有顶点进行修正,保证拼块移动到适当的方格位置处。 public void Verity(int CHIP_WIDTH) { myPath.Reset(); //清空路径 int x_offset=0, y_offset=0; int d; d=m_pointList[0].X % CHIP_WIDTH; if (d != 0) x_offset -= (d < CHIP_WIDTH / 2 ? d:d- CHIP_WIDTH); d = m_pointList[0].Y % CHIP_WIDTH; if (d != 0) y_offset -= (d < CHIP_WIDTH / 2 ? d:d- CHIP_WIDTH); for (int i = 0; i < m_nPointCount; i++) // 平移各点 { m_pointList[i].X += x_offset; m_pointList[i].Y += y_offset; } myPath.AddLines(m_pointList); myPath.CloseFigure(); }
int [,]Map=new int[6,6]; int[,] OrgMap = new int[6, 6];//初始化目标地图OrgMap 窗体加载事件中,调用Reset()对8个拼块的顶点坐标m_chipList 数组初始化。调用ReadOrgMap(1)方法读出第一关目标图案的地图信息到OrgMap二维数组中。 private void Form1_Load(object sender, EventArgs e) { Reset();// 初始化拼图块 //以下两句是为了设置控件样式为双缓冲,这可以有效减少闪烁的问题 this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true); this.UpdateStyles(); ReadOrgMap(1); //读出第一关目标图案的地图信息到OrgMap二维数组中 Draw_AllChip();//画出所有拼块 }
private void Reset() { for (int i = 0; i < CHIP_COUNT; i++) m_chipList[i] = new CChip(); Point[] pointList = new Point[MAX_POINTS]; int sx=250, sy=0; pointList[0] = new Point(sx , sy ); pointList[1] = new Point(sx + 2* CHIP_WIDTH, sy ); pointList[2] = new Point(sx + 2* CHIP_WIDTH, sy + 2 * CHIP_WIDTH); pointList[3] = new Point(sx , sy + 2 * CHIP_WIDTH); m_chipList[0].SetChip(1, pointList, 4); //m_chipList[0]为一个2W*2W的正方形 sx =170 ; sy = 90; pointList[0] = new Point(sx + CHIP_WIDTH * 2, sy); pointList[1] = new Point(sx + CHIP_WIDTH * 6, sy); pointList[2] = new Point(sx + CHIP_WIDTH * 6, sy + CHIP_WIDTH); pointList[3] = new Point(sx + CHIP_WIDTH * 2, sy + CHIP_WIDTH); m_chipList[1].SetChip(2, pointList, 4); //m_chipList[1]为一个4W*1W的长方形 …… }
private void ReadOrgMap(int n) { string filename = "map.txt"; FileStream fs = File.OpenRead(filename); StreamReader sr = new StreamReader(fs, Encoding.Default); string t = null; while (n > 0) { t = sr.ReadLine(); n--; } sr.Close(); fs.Close(); string [] a = new string[36 + 1]; a = t.Split(','); for (int i = 1; i < 7; i++) for (int j = 1; j < 7; j++) OrgMap[i-1, j-1]=Convert.ToInt16(a[(i-1)*6+j-1]); }
private void button1_Click(object sender, EventArgs e)//“新图案”按钮 { n++; if (n > max) { MessageBox.Show("没有新图案了"); n--; return; } ReadOrgMap(n);//读目标地图OrgMap文件 Map = new int[6, 6]; Reset(); // 初始化拼图块 Draw_AllChip(); //画出所有拼块 }
private void Draw_AllChip() ///画出所有拼块及目标图案 { Bitmap bmp = new Bitmap(this.Width, this.Height); this.BackgroundImage = bmp; //Graphics g = this.CreateGraphics(); Graphics g = Graphics.FromImage(bmp); g.Clear(this.BackColor); string r=n.ToString()+".jpg"; Bitmap s = (Bitmap)Image.FromFile(r); //g.DrawImage(s,new Point(400, 0)); g.DrawImage(s, new Rectangle(450, 10, 320, 240), new Rectangle(0, 0, 640, 480),GraphicsUnit.Pixel); //在(450,10)处显示320*240图案 for (int i = 0; i < CHIP_COUNT; i++) m_chipList[i].DrawChip(g); }
private void Form1_MouseDown(object sender, MouseEventArgs e) { Point p = new Point(e.X, e.Y); for (int i = 0; i < CHIP_COUNT; i++) if (m_chipList[i].PtInChip(p) == true) { m_nCurrIndex = i; //记录用户选中的拼块 Drag_PictBox = true; //移动标志赋值为真 oldx = e.X; oldy = e.Y; break; } if (e.Button == MouseButtons.Right) //右键旋转 { m_chipList[m_nCurrIndex].Rotation2(); //旋转顺时针45度 m_chipList[m_nCurrIndex].Rotation2(); //旋转顺时针45度 Draw_AllChip();//画出所有拼块 } }
private void Form1_MouseMove(object sender, MouseEventArgs e) { Point p = new Point(e.X, e.Y); label1.Text = p.ToString(); if (Drag_PictBox == true) { Cursor.Current = Cursors.Hand; m_chipList[m_nCurrIndex].Move2(e.X - oldx, e.Y - oldy); //移动 Draw_AllChip(); //画出所有拼块 } oldx = e.X; oldy = e.Y; }
private void Form1_MouseUp(object sender, MouseEventArgs e) { Drag_PictBox = false; //对用户选中的m_nCurrIndex拼块坐标进行修正,放置到正确位置 m_chipList[m_nCurrIndex].Verity(CHIP_WIDTH); Draw_AllChip(); //画出所有拼块 if(Win()) MessageBox.Show("成功完成此关") ; //判断是否成功 }
private void Form1_MouseDoubleClick(object sender, MouseEventArgs e) { Point p = new Point(e.X, e.Y); for (int i = 0; i < CHIP_COUNT; i++) if (m_chipList[i].PtInChip(p) == true) { m_nCurrIndex = i; //记录用户选中的拼块 Drag_PictBox = true; oldx = e.X; oldy = e.Y; break; } m_chipList[m_nCurrIndex].ReverseTurn(); //// 水平反转 Draw_AllChip();//画出所有拼块 }
在窗体重绘事件中,绘制棋盘和本关已固定的绿色方块。 private void Form1_Paint(object sender, PaintEventArgs e) { Graphics gp = e.Graphics; SolidBrush myBrush = new SolidBrush(Color.Green); for (int i = 0; i < 6; i++) //绘制本关已固定的绿色方块 for (int j = 0; j < 6; j++) { if(OrgMap[i,j]==0) gp.FillRectangle(myBrush, i * CHIP_WIDTH, j * CHIP_WIDTH, CHIP_WIDTH, CHIP_WIDTH); } Pen p = new Pen(Color.Brown, 1); for (int i = 1; i < 7; i++) //绘制棋盘 for (int j = 1; j < 7; j++) { gp.DrawLine(p, 1, j * CHIP_WIDTH, CHIP_WIDTH*6, j * CHIP_WIDTH); gp.DrawLine(p, i * CHIP_WIDTH, 1, i * CHIP_WIDTH, CHIP_WIDTH * 6); } }