我在做一个模拟交通控制的小程序,
里面会用矩形模拟车辆的移动,大家能给一个矩形移动的小例子么?C# winform, 谢谢

解决方案 »

  1.   

    用Timer控制当前的绘制位置,触发绘制事件
    绘制事件处理方法中在指定位置绘制
      

  2.   

            private void button1_Click(object sender, EventArgs e)
            {
                Graphics graph_car = this.CreateGraphics();
                this.Show();            Pen erasePen = new Pen(BackColor, 3);
                Pen bluePen = new Pen(Color.Blue, 3);
                Rectangle rec = new Rectangle(5, 5, 80, 80);                 for (int i = -100; i < 1000; ++i)
                {
                    graph_car.DrawRectangle(erasePen, rec);                Point p = new Point(i, i);
                    rec.Location.Offset(p);                graph_car.DrawRectangle(bluePen, rec);
                }
            }
      

  3.   

    你是在那个for循环里面重绘吗?
      

  4.   

            private void button1_Click(object sender, EventArgs e) 
            { 
                Graphics graph_car = this.CreateGraphics(); 
                this.Show();             Pen erasePen = new Pen(BackColor, 3); 
                Pen bluePen = new Pen(Color.Blue, 3); 
                Rectangle rec = new Rectangle(5, 5, 80, 80);                  for (int i = -100; i  < 1000; ++i) 
                { 
                    graph_car.DrawRectangle(erasePen, rec);                 Point p = new Point(i, i);
                    //将下面这句改掉,是移动矩形,不是矩形左上角的点的移动
                    //rec.Location.Offset(p); 
                    rec.Offset(p);                 graph_car.DrawRectangle(bluePen, rec); 
                } 
            } 
      

  5.   


    Duping9626, 那如果不采用背景色覆盖原来的位置,还有别的办法么?
      

  6.   

    用个Timer。
    private void button1_Click(object sender, EventArgs e)
    {
        timer1.Enabled = !timer1.Enabled;
    }Point carPoint = new Point(0, 0);
    private void timer1_Tick(object sender, EventArgs e)
    {
        Graphics graph_car = CreateGraphics();
        graph_car.DrawRectangle(new Pen(BackColor, 3), 
            new Rectangle(carPoint.X, carPoint.Y, 80, 80));
        carPoint.Offset(2, 2);
        graph_car.DrawRectangle(new Pen(Color.Blue, 3),
            new Rectangle(carPoint.X, carPoint.Y, 80, 80));
        graph_car.Dispose();
    }参考我写的方块绘制速度还可以。
      

  7.   

    那如果不采用背景色覆盖原来的位置??
    什么意思
    直接移动就是呀    public partial class Form3 : Form
        {
            Rectangle rec = new Rectangle(5, 5, 80, 80);
            private int i = 0;        public Form3()
            {
                InitializeComponent();
            }        private void button1_Click(object sender, EventArgs e)
            {
                Graphics graph_car = this.CreateGraphics();             Pen bluePen = new Pen(Color.Blue, 3);
                rec.Offset(i, i);
                graph_car.DrawRectangle(bluePen,rec);
                i+=10;
            }
        }
      

  8.   

    this.Show()要去掉,每次都重绘了
      

  9.   

    肯定要擦除的,其实8楼的方法可以参考(一直new Pen不是好习惯)
      

  10.   

    你是要一次就一个呀,开始没理解    public partial class Form3 : Form
        {
            Rectangle rec = new Rectangle(5, 5, 80, 80);
            private int i = 0;        public Form3()
            {
                InitializeComponent();
            }        private void button1_Click(object sender, EventArgs e)
            {
                Graphics graph_car = this.CreateGraphics();
                //加重绘就行了
                this.Refresh();
                Pen bluePen = new Pen(Color.Blue, 3);
                rec.Offset(i, i);
                graph_car.DrawRectangle(bluePen,rec);
                i+=10;
                
            }
        }
      

  11.   

    类定义里放个Point pt=new Point(0,0);
    Button的Click事件里还是启用Timer
    Timer的Tick事件里修改pt的值,再this.Invalidate();
    加一个Form的Paint事件处理方法,在此方法中完成绘制,这里只需要绘制,不需要擦除
    Graphics对象可以从事件参数中获得,不需要再创建。
      

  12.   


    那不同速度的多个矩形该怎么做,设置多个timer么?
      

  13.   


    你的意思是zswang的code里,每次都新创建了一个Graphics实例,对么?那么这个graph_car的初始化写在那个位置?以及作为事件参数,如何传递?对不起第一次用C#的绘图功能,所以问的问题比较浅。
      

  14.   


    class RectList
    {
       private ArrayList list;
       pubic RectList()
       {
          list=new ArrayList();
        }    public void Add(Rectangle rect,int v)
        {
           Rect r=new Rect();
           r.Rectangle=rect;
           r.V=v;
           list.Add(r);
        }    public Rectangle GetRect(int index)
        {
           Rect r=list[index] as Rect;
           if(r==null) return null;
           return r.Rectangle;
        }    public int GetV(int index);
        {
            Rect r=list[index] as Rect;
            if(r==null) return -1;
            return r.V;
         }    public void SetV(int index,int v)
        {
          ...
        }
        class Rect
       {
           private Rectangle rc;
           private int v;      public Rectangle Rectangle
         {
             get
             {
                return rc;
             }
            set
            {
               rc=value;
            }
         }     public int V
         {
            get
            {
                return v;
            }
            set
            {
                v=value;
            }
          }    }
    }
      

  15.   

    他的方法里面创建了,也销毁了,并没有什么问题,我的意思只不过是Paint事件会传一个Graphics对象,无需自己创建
    至于矩形的绘制位置,另外在Form的定义中加上一个Point,在Timer的Tick事件中更改它的值,在Form的Paint事件中根据它的值来绘制
    这个其实与C#没有太大关系,Windows本身的机制
      

  16.   

    谢谢你。
    但是好像在一个timer中绘制和更新的速度是相同的,
    在你写的类里,比如,我创建了两个rect的实例,r1.V = 1; r2.V = 5;
    那么这个速度的控制,是在哪儿进行的呢?
      

  17.   

    可以在Timer的Tick事件中,不过,使用一个Timer一块儿处理,显然会带来另外一个问题:有些矩形的速度可能设得太高,以至于移动时会有明显的跳跃感。要解决这个问题,只能是让Timer的Tick事件发生的更频繁一些。其他好的解决办法,暂时还没想到。
      

  18.   

    建议LZ 用flash 来做.这样最省时省力.
    用C#实现.
    楼上的方法大都用Graph draw 来完成, 这样感觉不太好控制.如车辆的速度,轨迹等.而且车辆只是个矩形色块, 也不好看.
    可采用picturebox来放车辆的图片.然后移动 picturebox 参考(http://topic.csdn.net/u/20080318/10/308b6685-1bc9-4f38-a704-41ab6277efe3.html)
      

  19.   


        public partial class Form3 : Form
        {
            Rectangle rec = new Rectangle(5, 5, 80, 80);
            private int i = 0;        public Form3()
            {
                InitializeComponent();
            }        private void button1_Click(object sender, EventArgs e)
            {
                Graphics graph_car = this.CreateGraphics();
                  this.Refresh();
                Pen bluePen = new Pen(Color.Blue, 3);
                rec.Offset(i, i);
                graph_car.DrawRectangle(bluePen,rec);
                i+=10;
                
            }
        }
      

  20.   

    可以定义一个IShape接口,包含Paint方法、Level、Pos、Zoom属性等
    汽车实现IShape接口,实现Paint方法,Paint中按这些属性进行绘制
    一个List<IShape>存所有的形状
    窗体的Paint中遍历列表中的所有IShape,并按照Level画到Bitmap上,然后一次性将Bitmap画到窗体上。
    然后用Timer改变这些Shape的属性,刷新窗体
      

  21.   


    1. 如何更改tick事件发生的频率?2. 在同一个timer里面呢,如何使得不同的汽车表现出不同的移动速度呢?
      

  22.   


    有没有可能,每一个矩形分配一个对应速率的timer, 当这个矩形消亡时,控制它重绘的timer也一起消失?
      

  23.   

    我给你的那个类中的V就是速度,每个Timer的Tick事件中,将其中包含的每个Rectangle水平和垂直方向分别偏移对应的V个点使用的Timer是System.Windows.Forms命名空间中的那一个吗?Interval属性就是Tick事件发生的频率
    Timer不会自动消亡,需要Dispose手动销毁
      

  24.   

    如果窗体上的矩形总数不变的话,没必要总在创建销毁Timer
    这个Timer有一个Tag属性,可以用来保存与之相联系的矩形及移动速度
    当一个矩形应该消失在窗体之外的时候,你可以:更改其大小、位置、速度,再使之重新出现,就如一个新矩形,也可以创建一个新矩形,指定速度之后,赋给刚才消失的那个矩形使用的Timer的Tag。
      

  25.   

    Form1_OnPaint(PaintEventArgs e)
    {
       Graphics _g = e.Graphics;
       foreach(Rectangle rect in lstRectangle)
       {
          _g.FillRectangle(new Pen(Red), rect);
       }
    }
    Timer_OnTick()
    {
       Invalidate();
    }