在运行时从许多userControl中添加一个UserControl到winform中,一个接一个地随机添加,并将计时器附加到选定的Usercontrols

问题描述 投票:0回答:1

我正在尝试使用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时,计时器无法正常显示红色矩形。

enter image description here

c# winforms timer
1个回答
0
投票

因此上述代码中存在许多错误。但是我得到了解决方案。所以我只用了一个计时器,下面是代码。

在计时器的每个滴答声中,我都使用它来更新Shape的位置(即向下,向左,向右移动),当该形状到达底部时,我就调用了下一个随机选择的形状。我还使用了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个UserControl:

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;
        }

    }
}
© www.soinside.com 2019 - 2024. All rights reserved.