最近在用C#做一个地图编辑器…… 最近想用C#做一个平面的地图编辑器,但在绘图区不知道该用什么控件picturebox还是form?还有在这种情况下新建文件该怎么建,绘图区的网格怎么生成(可以显示或隐藏),哪个大侠可以提供帮组 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 都可以,关键你要知道如何用gdi绘图,并控制每一个图形元素 可缩放矢量图 听说过没LZ .SVG文件格式听说过没 XML 也学会给你带来帮助! 发个贴解决不了问题有空看看深蓝色右手的blog,这么好的文章在那里却没人会欣赏http://www.cnblogs.com/alamiye010/http://www.cnblogs.com/alamiye010/archive/2009/06/17/1505346.html 我对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,保存文件就按一定顺序保存这些结构,读还是按这个顺序读注意,图形都先画到画布缓存上,画完了,再把画布画到窗口 劝你用arcengine吧,好好学学,里边很多东西,涉及到地图的,还是用专业的好,你总不想自己重新开发一个arcmap吧 我用的是 PictureBox ,其实用其他的比如 Lable , Form 都可以,因为是在控件 Pain 事件中画上去的。网格的显示和隐藏用一个 bool 值保存,当状态发生改变时,强制重绘控件就可以生效了,调用控件重绘有几种方法:Invalidate()或者 Refresh(),具体的实现方法去参考一些 GDI+ 的书籍吧 非常感谢,你的思路对我帮助很大。我有一个问题 画网格你说用bool值来判断,当是true就绘制网格,当我要取消掉网格显示怎么处理呢(24楼的sheryee100说的是强制重新绘制,但是重绘的话要考虑到背景的颜色,如果我的背景是张图片,而且图片的颜色也各不相同,这个会在重绘下留下痕迹),请问这个问题怎么解决? 把绘制背景的操作放OnPaint里,先画背景,再画 画布和网格。把所有绘画放OnPaint里,要取消网格,强制重绘,全部重新画,不会留下痕迹的 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怎么会自动执行,这个是为什么?不太理解啊 控件.Invalidate 强制刷新如果有绘图或想刷新背景图 这个函数就会触发OnPaint OnPaint一般是自动调用的,被覆盖或移动都有可能被调用。做小地图用这种GDI就行了,如果地图比较大,或者要求比较华丽效果的,可以考虑DX或免费的游戏引擎 都是些小地图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);//而且这里也要另一次调用 }总之这样写就是感觉到别扭,有没有什么好的方法 http://ufo-crackerx.blog.163.com/blog/static/113078778201211594830275/ 画图(流程图之类的)还可以,做地图的话还是建议你先了解下地理信息系统,做地图有专门的开包,比如:ArcGIS, SupperMap这些 //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操作比较费时 curimage是背景图 这样的话我感觉有个问题 如果我要在背景图上添加其他的一些图片 那岂不是每次都要重绘 用一个bitmap保存背景,另一个bitmap保存画布。当向地图中添加新的图形元件时,更新格子数据(数组),更新画布(背景和图形全部画在画布上)。在OnPaint里重绘画布的bitmap的行了,这个速度是比较快的你的地图是有几层的,如果是两层(背景一层,图形一层)并且格子长宽都相等,可以考虑在程序初始化时就把背景绘制在画布上,添加新图形时,直接画画布上,移除图形时,图形所在画布格子的区域用背景重新覆盖还原,这样图形就不用全部重绘了 wulijian 这是你把你的qq发给我吧 我们qq上聊,这样效率太慢 使用委托的几行代码,错在何处呢?就是找不到 这些语句如何循环赋值 串口通讯中的多线程问题? 怎样调整工具栏上按钮上的图片的大小 dataset 对xml访问与操作 vs2005项目如何转换成VS2010 关于在Asp.net中调用word文档的问题 急急急 高分求问题! 类型或命名空间名称“SqlConnection 在类或命名空间,System中不存在(是否缺少程序集引用?) 急,求助在C#中dataGridView控件如何设置当前选中行 checkbox能否像radiobutton一样,一组只能选一个? 求助,如何使按钮闪烁
XML 也学会给你带来帮助!
有空看看深蓝色右手的blog,这么好的文章在那里却没人会欣赏
http://www.cnblogs.com/alamiye010/
http://www.cnblogs.com/alamiye010/archive/2009/06/17/1505346.html
我对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,保存文件就按一定顺序保存这些结构,读还是按这个顺序读
注意,图形都先画到画布缓存上,画完了,再把画布画到窗口
非常感谢,你的思路对我帮助很大。我有一个问题 画网格你说用bool值来判断,当是true就绘制网格,当我要取消掉网格显示怎么处理呢(24楼的sheryee100说的是强制重新绘制,但是重绘的话要考虑到背景的颜色,如果我的背景是张图片,而且图片的颜色也各不相同,这个会在重绘下留下痕迹),请问这个问题怎么解决?
{
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怎么会自动执行,这个是为什么?不太理解啊
如果有绘图或想刷新背景图 这个函数就会触发OnPaint
都是些小地图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);//而且这里也要另一次调用
}总之这样写就是感觉到别扭,有没有什么好的方法
画图(流程图之类的)还可以,做地图的话还是建议你先了解下地理信息系统,做地图有专门的开包,比如:ArcGIS, SupperMap这些
//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操作比较费时
curimage是背景图 这样的话我感觉有个问题 如果我要在背景图上添加其他的一些图片 那岂不是每次都要重绘
在OnPaint里重绘画布的bitmap的行了,这个速度是比较快的
你的地图是有几层的,如果是两层(背景一层,图形一层)并且格子长宽都相等,可以考虑在程序初始化时就把背景绘制在画布上,添加新图形时,直接画画布上,移除图形时,图形所在画布格子的区域用背景重新覆盖还原,这样图形就不用全部重绘了
wulijian 这是你把你的qq发给我吧 我们qq上聊,这样效率太慢