百变方块游戏.docx
《百变方块游戏.docx》由会员分享,可在线阅读,更多相关《百变方块游戏.docx(21页珍藏版)》请在冰豆网上搜索。
![百变方块游戏.docx](https://file1.bdocx.com/fileroot1/2023-6/15/4ed4db33-bf6a-495e-af75-13ff640a8186/4ed4db33-bf6a-495e-af75-13ff640a81861.gif)
百变方块游戏
窗体底端
C#开发-----百变方块游戏
例子代码:
n游戏在6×6格子的棋盘中进行,可排出55种不同的组合图案。
主要开发人的抽象思维能力、空间想象能力、动手能力、几何构建能力。
游戏运行时功能如下。
n
(1)实现用鼠标拖动拼块,拼块任意位置摆放。
n
(2)绕拼块的中心点旋转(旋转由鼠标右键操作实现)。
n(3)拼块水平翻转(由鼠标双击操作实现)
n百变方块游戏效果如图22-1所示。
用户拖动棋盘周围的8种拼块到棋盘中,直到棋盘所有空白方块格子被填满则此关游戏胜利。
单击“新方块图案”按钮则进入下一关游戏。
如果玩家无法完成则可以单击“参考答案”按钮查看参考拼图方案。
地图信息存储
n地图信息采用文本文件map.txt存储保存。
根据目标图案按列存放,每关占一行。
0代表固定不变的绿色填充方格,1代表蓝色填充的方格(即需要用户的8种拼块填充的方格)。
1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,0,1,0,1,1,0,0,0,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,0,1,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
n游戏在6×6格子的棋盘中进行,每关开始时从文本文件map.txt读取相应关所对应行的字符串,分割后将数据按列将目标图案存储到二维数组OrgMap[6,6],而用户移动拼块后的图案按列存储到二维数组Map[6,6]中。
通过对比两个数组知道是否成功完成此关。
1.拼块类(CChip.cs)
字段m_nType存储拼块的类型代号,总计有7个拼块。
分别用1—8代表图22-3的七个拼块。
m_nPointCount存储拼块的顶点个数,m_pointList存储拼块的顶点坐标。
myPath是形成拼块的路径。
[csharp]classCChip
{
Point[]m_pointList;//顶点坐标
intm_nPointCount;//顶点个数
intm_nType;//类型代号
privateGraphicsPathmyPath;
…….
}
拼块的参数设置方法SetChip
拼块类提供对拼块的参数设置方法SetChip,该方法完成拼块类型代号的设置,拼块图案顶点坐标初始化,最终形成拼块的路径。
[csharp]publicvoidSetChip(inttype,Point[]ppointlist,intcount)
{
m_nType=type;
m_nPointCount=count;
m_pointList=newPoint[m_nPointCount];
for(inti=0;im_pointList[i]=ppointlist[i];
myPath=newGraphicsPath();
myPath.AddLines(m_pointList);
myPath.CloseFigure();//CloseFigure方法闭合当前图形并开始新图形。
}
publicvoidSetChip(inttype,Point[]ppointlist,intcount)
{
m_nType=type;
m_nPointCount=count;
m_pointList=newPoint[m_nPointCount];
for(inti=0;im_pointList[i]=ppointlist[i];
myPath=newGraphicsPath();
myPath.AddLines(m_pointList);
myPath.CloseFigure();//CloseFigure方法闭合当前图形并开始新图形。
}
拼块的平移
[csharp]Move(intx_offset,inty_offset)应用Matrix实现GraphicsPath路径的平移。
publicvoidMove(intx_offset,inty_offset)
{
Matrixmatrix=newMatrix();
matrix.Translate(x_offset,y_offset);//追加平移
myPath.Transform(matrix);//应用变形
myPath.CloseFigure();
}
Move2(intx_offset,inty_offset)不用Matrix实现GraphicsPath路径的平移,而是直接对路径的每个顶点一一平移。
publicvoidMove2(intx_offset,inty_offset)
{
myPath.Reset();//清空路径
for(inti=0;i{
m_pointList[i].X+=x_offset;
m_pointList[i].Y+=y_offset;
}
myPath.AddLines(m_pointList);
myPath.CloseFigure();
}
Move(intx_offset,inty_offset)应用Matrix实现GraphicsPath路径的平移。
publicvoidMove(intx_offset,inty_offset)
{
Matrixmatrix=newMatrix();
matrix.Translate(x_offset,y_offset);//追加平移
myPath.Transform(matrix);//应用变形
myPath.CloseFigure();
}
Move2(intx_offset,inty_offset)不用Matrix实现GraphicsPath路径的平移,而是直接对路径的每个顶点一一平移。
publicvoidMove2(intx_offset,inty_offset)
{
myPath.Reset();//清空路径
for(inti=0;i{
m_pointList[i].X+=x_offset;
m_pointList[i].Y+=y_offset;
}
myPath.AddLines(m_pointList);
myPath.CloseFigure();
}
拼块的旋转
[csharp]Rotation()应用Matrix实现GraphicsPath路径的旋转,每次旋转45度。
publicvoidRotation()
{
Matrixmatrix=newMatrix();
RectangleFrect=newRectangleF();
rect=myPath.GetBounds();
//计算旋转中心坐标(x,y)
doublex=rect.Left+rect.Width/2;
doubley=rect.Top+rect.Height/2;
//matrix.Rotate(45.0f);//旋转顺时针45度
matrix.RotateAt(45.0f,newPoint((int)x,(int)y));//旋转顺时针45度
}
Rotation()应用Matrix实现GraphicsPath路径的旋转,每次旋转45度。
publicvoidRotation()
{
Matrixmatrix=newMatrix();
RectangleFrect=newRectangleF();
rect=myPath.GetBounds();
//计算旋转中心坐标(x,y)
doublex=rect.Left+rect.Width/2;
doubley=rect.Top+rect.Height/2;
//matrix.Rotate(45.0f);//旋转顺时针45度
matrix.RotateAt(45.0f,newPoint((int)x,(int)y));//旋转顺时针45度
}
拼块的旋转
(2)
[csharp]Rotation2()不用Matrix实现GraphicsPath路径的旋转,而是获取myPath的矩形区域,计算旋转中心,从而计算出每个顶点的新坐标。
publicvoidRotation2()
{
RectangleFrect=newRectangleF();
rect=myPath.GetBounds();
myPath.Reset();//清空路径
doublex=rect.Left+rect.Width/2;//计算旋转中心
doubley=rect.Top+rect.Height/2;
doubledx,dy;
for(inti=0;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();
}
Rotation2()不用Matrix实现GraphicsPath路径的旋转,而是获取myPath的矩形区域,计算旋转中心,从而计算出每个顶点的新坐标。
publicvoidRotation2()
{
RectangleFrect=newRectangleF();
rect=myPath.GetBounds();
myPath.Reset();//清空路径
doublex=rect.Left+rect.Width/2;//计算旋转中心
doubley=rect.Top+rect.Height/2;
doubledx,dy;
for(inti=0;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();
}
拼块水平反转
[csharp]ReverseTurn()获取myPath的矩形区域,计算旋转中心,从而计算出水平翻转后每个顶点的新坐标。
publicvoidReverseTurn()//水平反转
{
RectangleFrect=newRectangleF();
rect=myPath.GetBounds();
myPath.Reset();
doublex=rect.Left+rect.Width/2;//计算旋转中心
doubley=rect.Top+rect.Height/2;
for(inti=0;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();
}
ReverseTurn()获取myPath的矩形区域,计算旋转中心,从而计算出水平翻转后每个顶点的新坐标。
publicvoidReverseTurn()//水平反转
{
RectangleFrect=newRectangleF();
rect=myPath.GetBounds();
myPath.Reset();
doublex=rect.Left+rect.Width/2;//计算旋转中心
doubley=rect.Top+rect.Height/2;
for(inti=0;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();
}
DrawChip()在Graphics对象上画出拼块。
每个拼块设置不同的填充颜色。
[csharp]publicvoidDrawChip(Graphicsg)//画拼块
{
PenmyPen=newPen(Color.Black,1);
g.DrawPath(myPen,myPath);
intalpha=140;//透明度
Colorc=Color.FromArgb(alpha,255,255,255);
switch(m_nType)
{
case1:
c=Color.FromArgb(alpha,127,127,127);
break;
case2:
c=Color.FromArgb(alpha,255,0,0);
break;
case3:
c=Color.FromArgb(alpha,200,255,0);
break;
.......
case8:
c=Color.FromArgb(alpha,228,128,128);
break;
}
SolidBrushbrushNew=newSolidBrush(c);
g.FillPath(brushNew,myPath);
}
publicvoidDrawChip(Graphicsg)//画拼块
{
PenmyPen=newPen(Color.Black,1);
g.DrawPath(myPen,myPath);
intalpha=140;//透明度
Colorc=Color.FromArgb(alpha,255,255,255);
switch(m_nType)
{
case1:
c=Color.FromArgb(alpha,127,127,127);
break;
case2:
c=Color.FromArgb(alpha,255,0,0);
break;
case3:
c=Color.FromArgb(alpha,200,255,0);
break;
.......
case8:
c=Color.FromArgb(alpha,228,128,128);
break;
}
SolidBrushbrushNew=newSolidBrush(c);
g.FillPath(brushNew,myPath);
}
对用户移动的拼块进行位置校正
Verity(intCHIP_WIDTH)对用户移动的拼块进行位置校正,方法是判断拼块的第一个顶点坐标m_pointList[0]接近棋盘中那个方格,则计算出偏移量后,对拼块的所有顶点进行修正,保证拼块移动到适当的方格位置处。
publicvoidVerity(intCHIP_WIDTH)
{
myPath.Reset();//清空路径
intx_offset=0,y_offset=0;
intd;
d=m_pointList[0].X%CHIP_WIDTH;
if(d!
=0)
x_offset-=(dd:
d-CHIP_WIDTH);
d=m_pointList[0].Y%CHIP_WIDTH;
if(d!
=0)
y_offset-=(dd:
d-CHIP_WIDTH);
for(inti=0;i{
m_pointList[i].X+=x_offset;
m_pointList[i].Y+=y_offset;
}
myPath.AddLines(m_pointList);
myPath.CloseFigure();
}
Verity(intCHIP_WIDTH)对用户移动的拼块进行位置校正,方法是判断拼块的第一个顶点坐标m_pointList[0]接近棋盘中那个方格,则计算出偏移量后,对拼块的所有顶点进行修正,保证拼块移动到适当的方格位置处。
publicvoidVerity(intCHIP_WIDTH)
{
myPath.Reset();//清空路径
intx_offset=0,y_offset=0;
intd;
d=m_pointList[0].X%CHIP_WIDTH;
if(d!
=0)
x_offset-=(dd:
d-CHIP_WIDTH);
d=m_pointList[0].Y%CHIP_WIDTH;
if(d!
=0)
y_offset-=(dd:
d-CHIP_WIDTH);
for(inti=0;i{
m_pointList[i].X+=x_offset;
m_pointList[i].Y+=y_offset;
}
myPath.AddLines(m_pointList);
myPath.CloseFigure();
}
2.设计窗体类(Form1.cs)
窗体加载事件
[csharp]int[,]Map=newint[6,6];
int[,]OrgMap=newint[6,6];//初始化目标地图OrgMap
窗体加载事件中,调用Reset()对8个拼块的顶点坐标m_chipList数组初始化。
调用ReadOrgMap
(1)方法读出第一关目标图案的地图信息到OrgMap二维数组中。
privatevoidForm1_Load(objectsender,EventArgse)
{
Reset();//初始化拼图块
//以下两句是为了设置控件样式为双缓冲,这可以有效减少闪烁的问题
this.SetStyle(ControlStyles.OptimizedDoubleBuffer|ControlStyles.AllPaintingInWmPaint|ControlStyles.UserPaint,true);
this.UpdateStyles();
ReadOrgMap
(1);//读出第一关目标图案的地图信息到OrgMap二维数组中
Draw_AllChip();//画出所有拼块
}
int[,]Map=newint[6,6];
int[,]OrgMap=newint[6,6];//初始化目标地图OrgMap
窗体加载事件中,调用Reset()对8个拼块的顶点坐标m_chipList数组初始化。
调用ReadOrgMap
(1)方法读出第一关目标图案的地图信息到OrgMap二维数组中。
privatevoidForm1_Load(objectsender,EventArgse)
{
Reset();//初始化拼图块
//以下两句是为了设置控件样式为双缓冲,这可以有效减少闪烁的问题
this.SetStyle(ControlStyles.OptimizedDoubleBuffer|ControlStyles.AllPaintingInWmPaint|ControlStyles.UserPaint,true);
this.UpdateStyles();
ReadOrgMap
(1);//读出第一关目标图案的地图信息到OrgMap二维数组中
Draw_AllChip();//画出所有拼块
}
初始化拼块
Reset()初始化拼图块顶点坐标m_chipList数组,并形成拼块的图形路径。
[csharp]privatevoidReset()
{
for(inti=0;im_chipList[i]=newCChip();
Point[]pointList=newPoint[MAX_POINTS];
intsx=250,sy=0;
pointList[0]=newPoint(sx,sy);
pointList[1]=newPoint(sx+2*CHIP_WIDTH,sy);
pointList[2]=newPoint(sx+2*CHIP_WIDTH,sy+2*CHIP_WIDTH);
pointList[3]=newPoint(sx,sy+2*CHIP_WIDTH);
m_chipList[0].SetChip(1,pointList,4);//m_chipList[0]为一个2W*2W的正方形
sx=170;sy=90;
pointList[0]=newPoint(sx+CHIP_WIDTH*2,