【问题标题】:add one UserControl from many userControls to winforms at runtime one after another at random and Attach timers to selected Usercontrols在运行时随机将许多用户控件中的一个用户控件添加到winforms,并将计时器附加到选定的用户控件
【发布时间】:2020-04-13 05:07:44
【问题描述】:

我正在尝试使用 C# 以 Windows 形式创建俄罗斯方块游戏。 这是我的 Form1.cs 代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Tetris
{
    public partial class Form1 : Form
    {
        Control s;
        int value = 1;
        Point startPointOfWindow;//red square-left top corner
        Point endPointOfWindow;//red square- right bottom corner 
        public Timer timer1;

       public Form1()
        {
            InitializeComponent();

        }

        private void Process()
        {
            do
            {
                this.s = ChooseOneShape();
                this.s.Location = new System.Drawing.Point(10, 10);

                //this.ResumeLayout(false);
                //this.s.PerformLayout();

                timer1 = new Timer();
                timer1.Tick += new System.EventHandler(timer1_Tick);
                timer1.Interval = 800;
                timer1.Enabled = true;
                //await Task.Delay(2000);
                Application.DoEvents();

                this.Controls.Add(this.s);

                value++;
                // System.Threading.Thread.Sleep(2000);

            } while (value <= 3);
        }

      private Control ChooseOneShape()
        {
            Shape1 s2 = new Shape1();//rectangle
            Shape2 s1 = new Shape2();//square
            List<Control> list = new List<Control>();

            list.Add(s2);
            list.Add(s1);
            Random r = new Random();
            int index = r.Next(list.Count);
            return list[index];

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            var oldLocation = new Point(this.s.Location.X + this.s.Width, this.s.Location.Y + this.s.Height);

            if (oldLocation.X < endPointOfWindow.X && oldLocation.X >= startPointOfWindow.X &&
                oldLocation.Y < endPointOfWindow.Y && oldLocation.Y >= startPointOfWindow.Y)
                this.s.Location = new Point(this.s.Location.X + 10, this.s.Location.Y + 10);
            else if (oldLocation.Y + 10 >= endPointOfWindow.Y && oldLocation.Y + 10 > startPointOfWindow.Y)
                timer1.Enabled = false;

            else if (oldLocation.X + 10 >= endPointOfWindow.X && oldLocation.X + 10 > startPointOfWindow.X)
                this.s.Location = new Point(this.s.Location.X, this.s.Location.Y + 10);

            else if (oldLocation.X < endPointOfWindow.X && oldLocation.X >= startPointOfWindow.X)
                this.s.Location = new Point(this.s.Location.X + 10, this.s.Location.Y);
            else if (oldLocation.Y < endPointOfWindow.Y && oldLocation.Y >= startPointOfWindow.Y)
                this.s.Location = new Point(this.s.Location.X, this.s.Location.Y + 10);
            else timer1.Enabled = false;
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            Graphics g = this.CreateGraphics();
            g.DrawRectangle(new Pen(Color.Red), 10, 10, 350, 250);
            startPointOfWindow = new Point(10, 10);
            endPointOfWindow = new Point(350, 250);
            Process();

        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            var x = this.s.Location;
            var size = this.s.Size;
            //capture left arrow key
            if (keyData == Keys.Left && x.X > 0 && x.Y + this.s.Height < 250)
            {
                this.s.Location = new System.Drawing.Point(x.X - 10, x.Y);
                return true;
            }
            //capture right arrow key
            if (keyData == Keys.Right && x.X + this.s.Width < 350 && x.Y + this.s.Height < 250)
            {
                this.s.Location = new System.Drawing.Point(x.X + 10, x.Y);
                return true;
            }

            if (keyData == Keys.Down && x.Y + this.s.Height < 250)
            {
                this.s.Location = new System.Drawing.Point(x.X, x.Y + 10);
                return true;
            }


            return base.ProcessCmdKey(ref msg, keyData);
        }
    }
}

这是我的 Shape1 和 Shape2:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Forms;

namespace Tetris
{
    public class Shape1 : UserControl 
    {

        protected override void OnPaint(PaintEventArgs pevent)
        {
            Graphics g = this.CreateGraphics();
            Brush brush = new SolidBrush(Color.Red);
            g.FillRectangle(brush, 0, 0, 80, 20);
            base.Width = 80;
            base.Height = 20;
        }
    }

    public class Shape2 : UserControl 
    {
        protected override void OnPaint(PaintEventArgs pevent)
        {
            Graphics g = this.CreateGraphics();
            Brush brush = new SolidBrush(Color.MediumVioletRed);
            g.FillRectangle(brush, 0, 0, 40, 40);
            base.Width = 40;
            base.Height = 40;
        }
    }
}

问题是计时器适用于选定的第二个形状。

这是图像,当 value=2 并且计时器正常工作时,选择了紫色方块。但是当 value=1 时,计时器对于红色矩形不能正常工作。

【问题讨论】:

    标签: c# winforms timer


    【解决方案1】:

    所以上面的代码有很多错误。但我得到了我的解决方案。所以我只用了一个计时器,下面是代码。

    在计时器的每个滴答声中,我都使用它来更新我的形状的位置(即向下、向左、向右移动),当形状到达底部时,我调用了随机选择的下一个形状。我还使用了 UserControl 的 Paint() 方法在计时器的每个刻度处绘制形状。因此,每当在 timer1_tick() 中更新位置时,我都会调用 UserControl 的 Invalidate() 方法来更新 UserControl 的位置。

    Form1.cs

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace Tetris
    {
        public partial class Form1 : Form
        {
    
            Control s;
            int value = 1;
            Point startPointOfWindow;//red square-left top corner
            Point endPointOfWindow;//red square- right bottom corner 
            public System.Windows.Forms.Timer timer3;
    
            List<string> list;
            public Form1()
            {
                InitializeComponent();
                Shape1 s1 = new Shape1();//rectangle
                Shape2 s2 = new Shape2();//square
                list = new List<string>();
    
                list.Add("Shape1");
                list.Add("Shape2");
    
                timer3 = new System.Windows.Forms.Timer();
                timer3.Interval = 800;
    
                timer3.Tick += new System.EventHandler(timer1_Tick);
                timer3.Enabled = true;
                Process();
            }
    
            private void Process()
            {
                switch (ChooseOneShape())
                {
                    case "Shape1":
                        this.s = new Shape1();break;
                    case "Shape2":
                        this.s = new Shape2();break;
                }
    
                this.s.Location = new System.Drawing.Point(10, 10);
                this.Controls.Add(this.s);
            }
    
    
    
            private string ChooseOneShape()
            {
                Random r = new Random();
                int index = r.Next(list.Count);
                return list[index];
            }
    
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                var oldLocation = new Point(this.s.Location.X + this.s.Width, this.s.Location.Y + this.s.Height);
    
                if (oldLocation.X < endPointOfWindow.X && oldLocation.X >= startPointOfWindow.X &&
                    oldLocation.Y < endPointOfWindow.Y && oldLocation.Y >= startPointOfWindow.Y)
                {
                    s.Location = new Point(this.s.Location.X + 30, this.s.Location.Y + 30);
                    s.Invalidate();
                }
                else if (oldLocation.Y + 10 >= endPointOfWindow.Y && oldLocation.Y + 10 > startPointOfWindow.Y)
                    Process();
    
                else if (oldLocation.X + 10 >= endPointOfWindow.X && oldLocation.X + 10 > startPointOfWindow.X)
                {
                    this.s.Location = new Point(this.s.Location.X, this.s.Location.Y + 30);
                    s.Invalidate();
                }
    
                else if (oldLocation.X < endPointOfWindow.X && oldLocation.X >= startPointOfWindow.X)
                {
                    this.s.Location = new Point(this.s.Location.X + 30, this.s.Location.Y);
                    s.Invalidate();
                }
                else if (oldLocation.Y < endPointOfWindow.Y && oldLocation.Y >= startPointOfWindow.Y)
                {
                    this.s.Location = new Point(this.s.Location.X, this.s.Location.Y + 10);
                    s.Invalidate();
                }
                else Process();
                //Refresh();
                //Invalidate();
            }
    
    
    
    
            private void Form1_Shown(object sender, EventArgs e)
            {
                Graphics g = this.CreateGraphics();
                g.DrawRectangle(new Pen(Color.Red), 0, 0, 350, 250);
                startPointOfWindow = new Point(0, 0);
                endPointOfWindow = new Point(350, 250);
            }
    
            protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
            {
                var x = this.s.Location;
                var size = this.s.Size;
                //capture left arrow key
                if (keyData == Keys.Left && x.X > 0 && x.Y + this.s.Height < 250)
                {
                    this.s.Location = new System.Drawing.Point(x.X - 10, x.Y);
                    return true;
                }
                //capture right arrow key
                if (keyData == Keys.Right && x.X + this.s.Width < 350 && x.Y + this.s.Height < 250)
                {
                    this.s.Location = new System.Drawing.Point(x.X + 10, x.Y);
                    return true;
                }
    
                if (keyData == Keys.Down && x.Y + this.s.Height < 250)
                {
                    this.s.Location = new System.Drawing.Point(x.X, x.Y + 10);
                    return true;
                }
    
                return base.ProcessCmdKey(ref msg, keyData);
            }
    
        }
    }
    

    这里是创建的 2 个用户控件:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace Tetris
    {
        public class Shape1 : UserControl //Control
        {
            //rectangle
             protected override void OnPaint(PaintEventArgs e)
            {
                Brush brush = new SolidBrush(Color.Red);
                e.Graphics.FillRectangle(brush, 0, 0, 80, 20);
                base.Width = 80;
                base.Height = 20;
            }
        }
    
        public class Shape2 : UserControl// Control
        {
            //square 
            protected override void OnPaint(PaintEventArgs e)
            {
                Graphics g = e.Graphics;
                Brush brush = new SolidBrush(Color.MediumVioletRed);
                g.FillRectangle(brush, 0, 0, 40, 40);
                base.Width = 40;
                base.Height = 40;
            }
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-03
      • 2019-02-02
      相关资源
      最近更新 更多