问题描述
1,如何用Keydown键控制小人的上下左右行走,坐标是如何计算的?2、怎么控制小人和箱子坐标重合后,箱子的移动。
解决方案
解决方案二:
坐等来人.....坐标应该可以通过数组解决吧?人和箱子重合的时候判断哪一边...然后....不懂了--
解决方案三:
“坐标”有两个含义,一个是编程世界的坐标,一个是应用领域的坐标。应用领域的坐标其x、y可能就是从1到5,表示最多有5行、5列。而编程领域的坐标,则可能是像素坐标系的坐标(例如x、y都是从0到800或者从0到任意n数值之间映射)。你需要写两个个双向转换的函数,从一个应用领域坐标数据结构转换为Point,再反过来转换。这是最基本的算法元素。然后你就能轻易判断重合了。所谓重合,就是从应用领域坐标去看的。所谓移动,比如说一个箱子从(2,2)移动到(3,2),经过上述转换,就是从(120,120)动画移动到(240,120)。而移动之前,你可能要先判断(3,2)这个位置必须是“空的”,这时候才可能移动(2,2)位置上的箱子。而要向下推动(2,2)位置的箱子,那么一定响应“向下”按键,且小人的位置在(1,2)。把这些逻辑有机地联系起来,你就能设计一套业务逻辑,以及实现它。
解决方案四:
位置(用复数表示):小人x+yi箱子X+Yi步长上0-1i下0+1i左-1+0i右1+0i则有:if小人+步长==墙then不动if小人+步长==箱子thenif箱子+步长==墙then不动else箱子=箱子+步长小人=小人+步长
解决方案五:
最好是能从一开始就意识到“分成两层”,比如说应用领域坐标系中x、y都是从1到5的整数,不可能小于1也不可能大于5。当你确定这样的分层,再来设计业务控制逻辑,你就跟实现相分离了。如果在“一层”代码中把什么概念都组合在一起,慢慢地你就发现越来越失控了。
解决方案六:
比如说我们要在地图上把一个城市的某些油气管道标出来,那么我们拿到一堆的经纬度表示的管道、阀门坐标,一堆管道直径数值,于是我们就直接调用“画图线、画阀门”操作了!其输入参数就是应用领域的经纬度坐标,而不是地图上的x-y,更不是显示器上的x-y坐标。只有你有这样的逻辑设计习惯,你才能很好地继续进行软件设计。而假设有的人只能从最底层的显示器坐标来表示应用领域逻辑设计问题,我们就知道他的前景堪忧,只能做一小部分底层编程技术工作。实际上,做一个推箱子游戏,如果能理解这样的系统分层设计,会比做出来这个游戏本身,更有意义。
解决方案七:
publicpartialclassForm9:Form{publicForm9(){InitializeComponent();}publicenumBoxType{None,//0空白Wall,//1墙Box,//2箱子Tag,//3目标没用到Person,//4人没用到Walkway//5过道}//privateBoxType[,]m_box=newBoxType[8,8]{//{BoxType.None,BoxType.None,BoxType.Wall,BoxType.Wall,BoxType.Wall,BoxType.None,BoxType.None,BoxType.None}//...//};privateintm_nBoxWidth=40;//格子大小privatePointm_ptPerson=newPoint(4,4);//人的初始位置privatePoint[]m_ptTag=newPoint[]{//目标的坐标点newPoint(3,1),newPoint(6,3),newPoint(1,4),newPoint(4,6)};privateint[,]m_box=newint[/*y*/,/*x*/]{//箱子的地图{0,0,1,1,1,0,0,0},{0,0,1,5,1,0,0,0},{0,0,1,5,1,1,1,1},{1,1,1,2,5,2,5,1},{1,5,5,2,4,1,1,1},{1,1,1,1,2,1,0,0},{0,0,0,1,5,1,0,0},{0,0,0,1,1,1,0,0},};protectedoverridevoidOnPaint(PaintEventArgse){Graphicsg=e.Graphics;//绘制基本地图for(intx=0;x<8;x++){for(inty=0;y<8;y++){switch((BoxType)m_box[y,x]){caseBoxType.None:g.FillRectangle(Brushes.Black,x*m_nBoxWidth,y*m_nBoxWidth,m_nBoxWidth,m_nBoxWidth);break;caseBoxType.Wall:g.FillRectangle(Brushes.Gray,x*m_nBoxWidth,y*m_nBoxWidth,m_nBoxWidth,m_nBoxWidth);break;caseBoxType.Box:g.FillRectangle(Brushes.YellowGreen,x*m_nBoxWidth,y*m_nBoxWidth,m_nBoxWidth,m_nBoxWidth);g.DrawRectangle(Pens.Green,x*m_nBoxWidth,y*m_nBoxWidth,m_nBoxWidth-1,m_nBoxWidth-1);break;caseBoxType.Walkway:g.FillRectangle(Brushes.Blue,x*m_nBoxWidth,y*m_nBoxWidth,m_nBoxWidth,m_nBoxWidth);break;caseBoxType.Person:g.FillRectangle(Brushes.Blue,x*m_nBoxWidth,y*m_nBoxWidth,m_nBoxWidth,m_nBoxWidth);break;}}}//绘制目标层foreach(varvinm_ptTag){g.FillEllipse(Brushes.White,v.X*m_nBoxWidth+5,v.Y*m_nBoxWidth+5,m_nBoxWidth-10,m_nBoxWidth-10);}//绘制人物g.FillEllipse(Brushes.Red,m_ptPerson.X*m_nBoxWidth+5,m_ptPerson.Y*m_nBoxWidth+5,m_nBoxWidth-10,m_nBoxWidth-10);base.OnPaint(e);}}
由m_boxm_ptTagm_ptPerson组成一副完整的地图换地图就换这三个参数就是了当用户按上下左右的时候去操作m_ptPerson的位置移动位置的时候先根据m_ptPerson现在的坐标去m_box地图上判断是否可以移动比如当前m_ptPerson在(2,3)的位置用户点击了上那么就要去判断m_box地图上的(2,2)位置是什么如果是墙那么就不能移动如果是箱子那么再判断m_box(2,1)位置是什么如果是墙或者是箱子那么就不能移动否则m_ptPerson变成(2,2)然后地图上m_box(2,1)=m_box(2,2);m_box(2,2)=过道;当所有箱子都和m_ptTag坐标重合的时候游戏结束上面的只是临时做的yield参考
解决方案八:
引用6楼刁斤干的回复:
publicpartialclassForm9:Form{publicForm9(){InitializeComponent();}publicenumBoxType{None,//0空白Wall,//1墙Box,//2箱子Tag,//3目标没用到Person,//4人没用到Walkway//5过道}//privateBoxType[,]m_box=newBoxType[8,8]{//{BoxType.None,BoxType.None,BoxType.Wall,BoxType.Wall,BoxType.Wall,BoxType.None,BoxType.None,BoxType.None}//...//};privateintm_nBoxWidth=40;//格子大小privatePointm_ptPerson=newPoint(4,4);//人的初始位置privatePoint[]m_ptTag=newPoint[]{//目标的坐标点newPoint(3,1),newPoint(6,3),newPoint(1,4),newPoint(4,6)};privateint[,]m_box=newint[/*y*/,/*x*/]{//箱子的地图{0,0,1,1,1,0,0,0},{0,0,1,5,1,0,0,0},{0,0,1,5,1,1,1,1},{1,1,1,2,5,2,5,1},{1,5,5,2,4,1,1,1},{1,1,1,1,2,1,0,0},{0,0,0,1,5,1,0,0},{0,0,0,1,1,1,0,0},};protectedoverridevoidOnPaint(PaintEventArgse){Graphicsg=e.Graphics;//绘制基本地图for(intx=0;x<8;x++){for(inty=0;y<8;y++){switch((BoxType)m_box[y,x]){caseBoxType.None:g.FillRectangle(Brushes.Black,x*m_nBoxWidth,y*m_nBoxWidth,m_nBoxWidth,m_nBoxWidth);break;caseBoxType.Wall:g.FillRectangle(Brushes.Gray,x*m_nBoxWidth,y*m_nBoxWidth,m_nBoxWidth,m_nBoxWidth);break;caseBoxType.Box:g.FillRectangle(Brushes.YellowGreen,x*m_nBoxWidth,y*m_nBoxWidth,m_nBoxWidth,m_nBoxWidth);g.DrawRectangle(Pens.Green,x*m_nBoxWidth,y*m_nBoxWidth,m_nBoxWidth-1,m_nBoxWidth-1);break;caseBoxType.Walkway:g.FillRectangle(Brushes.Blue,x*m_nBoxWidth,y*m_nBoxWidth,m_nBoxWidth,m_nBoxWidth);break;caseBoxType.Person:g.FillRectangle(Brushes.Blue,x*m_nBoxWidth,y*m_nBoxWidth,m_nBoxWidth,m_nBoxWidth);break;}}}//绘制目标层foreach(varvinm_ptTag){g.FillEllipse(Brushes.White,v.X*m_nBoxWidth+5,v.Y*m_nBoxWidth+5,m_nBoxWidth-10,m_nBoxWidth-10);}//绘制人物g.FillEllipse(Brushes.Red,m_ptPerson.X*m_nBoxWidth+5,m_ptPerson.Y*m_nBoxWidth+5,m_nBoxWidth-10,m_nBoxWidth-10);base.OnPaint(e);}}由m_boxm_ptTagm_ptPerson组成一副完整的地图换地图就换这三个参数就是了当用户按上下左右的时候去操作m_ptPerson的位置移动位置的时候先根据m_ptPerson现在的坐标去m_box地图上判断是否可以移动比如当前m_ptPerson在(2,3)的位置用户点击了上那么就要去判断m_box地图上的(2,2)位置是什么如果是墙那么就不能移动如果是箱子那么再判断m_box(2,1)位置是什么如果是墙或者是箱子那么就不能移动否则m_ptPerson变成(2,2)然后地图上m_box(2,1)=m_box(2,2);m_box(2,2)=过道;当所有箱子都和m_ptTag坐标重合的时候游戏结束上面的只是临时做的yield参考
下面关于坐标的文字描述能麻烦写成代码吗?