最近想用C#做一个平面的地图编辑器,但在绘图区不知道该用什么控件picturebox还是form?还有在这种情况下新建文件该怎么建,绘图区的网格怎么生成(可以显示或隐藏),哪个大侠可以提供帮组

解决方案 »

  1.   

    都可以,关键你要知道如何用gdi绘图,并控制每一个图形元素
      

  2.   

    可缩放矢量图  听说过没LZ   .SVG文件格式听说过没 
    XML 也学会给你带来帮助!
      

  3.   

    发个贴解决不了问题
    有空看看深蓝色右手的blog,这么好的文章在那里却没人会欣赏
    http://www.cnblogs.com/alamiye010/
    http://www.cnblogs.com/alamiye010/archive/2009/06/17/1505346.html
      

  4.   


    我对C# CS模式的API不太熟,所以代码上帮不了你了 说一下我的思路吧
    我以前学VC,做了一款坦克大战玩,也写了个很简单的地图编辑器。为了不使画面在编辑地图时出现闪动和效率考虑,先创建了一个内存兼容的Bitmap,你可以看作是一个画布,是一个n*m的矩阵,每个格子的大小最好等于图形元件的大小,不然你要缩放比较麻烦,图形就画在格子上,而显示,就把画布画到控件上就可以了,至于是控件picturebox还是form,都无所谓,是窗口都是可以绘图的,label这些都可以,这些窗口控件都会有一个自绘函数OnPaint,重载这个函数,把画布画在窗口上就可以了,
    绘图函数自己找找,绘制预览窗口的话,可以把画布缩小,画在指定大小的控件上,绘图API应该已实现了缩放功能,编辑地图时同步刷新预览控件。
    绘图区的网格显示,用一个函数实现就可以了,用两个for循环,画行和列,用一个bool来控制,true调用这个函数就可以了,调用也在OnPaint里调用。
    一个图像文件可以包含多个图形元件,也可以是一个图像文件一个图形,这都无所谓。程序打开初始化时,把所有图像文件读取到内存,得到索引,这个索引可以找到图形元件。
    一个格子可以是一个结构体或类,struct{位置,索引}例如struct{int x,int y,索引}或struct{int index,索引}  index%n得到列 index%m得到行
    n*m 就有n*m个struct,保存文件就按一定顺序保存这些结构,读还是按这个顺序读
    注意,图形都先画到画布缓存上,画完了,再把画布画到窗口
      

  5.   

    劝你用arcengine吧,好好学学,里边很多东西,涉及到地图的,还是用专业的好,你总不想自己重新开发一个arcmap吧
      

  6.   

    我用的是 PictureBox ,其实用其他的比如 Lable , Form 都可以,因为是在控件 Pain 事件中画上去的。网格的显示和隐藏用一个 bool 值保存,当状态发生改变时,强制重绘控件就可以生效了,调用控件重绘有几种方法:Invalidate()或者 Refresh(),具体的实现方法去参考一些 GDI+ 的书籍吧
      

  7.   


    非常感谢,你的思路对我帮助很大。我有一个问题 画网格你说用bool值来判断,当是true就绘制网格,当我要取消掉网格显示怎么处理呢(24楼的sheryee100说的是强制重新绘制,但是重绘的话要考虑到背景的颜色,如果我的背景是张图片,而且图片的颜色也各不相同,这个会在重绘下留下痕迹),请问这个问题怎么解决?
      

  8.   

    把绘制背景的操作放OnPaint里,先画背景,再画 画布和网格。把所有绘画放OnPaint里,要取消网格,强制重绘,全部重新画,不会留下痕迹的
      

  9.   

    private void toolStripButton2_Click(object sender, EventArgs e)
            {  
                if (bpaint == true)
                {
                    bpaint = false;
                    //OnPaint(e);
                }
                else
                {
                    bpaint = true;
                }
            }protected override void  OnPaint(PaintEventArgs e)
            {
                
                base.OnPaint(e);
                int ivisible = 20;
                int width = 400;
                int height = 400;        
                Graphics g = e.Graphics;
                Color color = new Color();
                color = Color.Red;
                Bitmap objBitmap = new Bitmap(width, height);
                Graphics objGraphics = Graphics.FromImage(objBitmap);
                objGraphics.FillRectangle(new SolidBrush(Color.White), 0, 0, width, height);//以白色作为图像的总体背景颜色。      
                if (bpaint==true)
                {
                    for (int iIndex = 0; iIndex <= width - ivisible; iIndex += ivisible)
                    {
                     
                        objGraphics.DrawLine(new Pen(new SolidBrush(color)), iIndex + ivisible, 0, iIndex + ivisible, height);
                    }                objGraphics.DrawLine(new Pen(new SolidBrush(Color.Black), 2), width / 2, 0, width / 2, height);                for (int iIndex = 0; iIndex <= height - ivisible; iIndex += ivisible)
                    {
                        objGraphics.DrawLine(new Pen(new SolidBrush(color)), 0, iIndex + ivisible, width, iIndex + ivisible);
                    }
                }
                pictureBox1.Image = objBitmap;     
            }
    Onpaint()方法是自动调用吗?我单击一个按钮来决定Onpaint()中网格是否绘制,但Onpaint怎么会自动执行,这个是为什么?不太理解啊
      

  10.   

    控件.Invalidate 强制刷新
    如果有绘图或想刷新背景图 这个函数就会触发OnPaint
      

  11.   

    OnPaint一般是自动调用的,被覆盖或移动都有可能被调用。做小地图用这种GDI就行了,如果地图比较大,或者要求比较华丽效果的,可以考虑DX或免费的游戏引擎
      

  12.   


    都是些小地图private Image curimage=null;
    curImage=openfiledialog.Filename;
    protected override void OnPaint(PaintEventArgs e)
            {
                base.OnPaint(e);
                int ivisible = 40;
                int width = 400;
                int height = 400;
                Color color = new Color();
                color = Color.Green;         
                Bitmap objBitmap = new Bitmap(width, height); ; 
                if (curimage!=null)
                {                
                    width = curimage.Width;
                    height = curimage.Height;
                   objBitmap = new Bitmap(curimage, width, height);
                   
                }
                       
                Graphics objGraphics =Graphics.FromImage(objBitmap);
                 
                if (bpaint == true)
                {
                    for (int iIndex = 0; iIndex <= width - ivisible; iIndex += ivisible)
                    {
                        objGraphics.DrawLine(new Pen(new SolidBrush(color),2), iIndex + ivisible, 0, iIndex + ivisible, height);
                    }                            for (int iIndex = 0; iIndex <= height - ivisible; iIndex += ivisible)
                    {
                        objGraphics.DrawLine(new Pen(new SolidBrush(color),2), 0, iIndex + ivisible, width, iIndex + ivisible);
                    }
                }
               pictureBox1.Image = objBitmap;
            }
            bool bpaint = false;
            private void toolStripButton1_Click(object sender, EventArgs e)
            {
                if (bpaint == true)
                {
                    bpaint = false;
                }
                else
                {
                    bpaint = true;
                }
            }上面的代码可以画背景和网格了 ,只是有一段代码写的感觉特别别扭如下
    //width height 初始化时不能为0 不然下面的会报错说参数无效
    Bitmap objBitmap = new Bitmap(width, height); ; 
                if (curimage!=null)
                {                
                    width = curimage.Width;
                    height = curimage.Height;
                   objBitmap = new Bitmap(curimage, width, height);//而且这里也要另一次调用
                }总之这样写就是感觉到别扭,有没有什么好的方法
      

  13.   

    http://ufo-crackerx.blog.163.com/blog/static/113078778201211594830275/
      

  14.   


    画图(流程图之类的)还可以,做地图的话还是建议你先了解下地理信息系统,做地图有专门的开包,比如:ArcGIS, SupperMap这些
      

  15.   


    //width height 初始化时不能为0 不然下面的会报错说参数无效
    Bitmap objBitmap = new Bitmap(width, height); ; 
                if (curimage!=null)
                {                
                    width = curimage.Width;
                    height = curimage.Height;
                   objBitmap = new Bitmap(curimage, width, height);//而且这里也要另一次调用
                }把objBitmap定义为全局变量,不要每次重新生成 curimage是背景图?OnPaint中IO操作比较费时
      

  16.   


    curimage是背景图  这样的话我感觉有个问题 如果我要在背景图上添加其他的一些图片 那岂不是每次都要重绘
      

  17.   

    用一个bitmap保存背景,另一个bitmap保存画布。当向地图中添加新的图形元件时,更新格子数据(数组),更新画布(背景和图形全部画在画布上)。
    在OnPaint里重绘画布的bitmap的行了,这个速度是比较快的
    你的地图是有几层的,如果是两层(背景一层,图形一层)并且格子长宽都相等,可以考虑在程序初始化时就把背景绘制在画布上,添加新图形时,直接画画布上,移除图形时,图形所在画布格子的区域用背景重新覆盖还原,这样图形就不用全部重绘了
      

  18.   


    wulijian    这是你把你的qq发给我吧 我们qq上聊,这样效率太慢