Mouse down between two pieces of a puzzle

前端 未结 3 821
时光说笑
时光说笑 2021-01-28 18:30

I am building a puzzle game in winforms, and i want to recognize the mousedown over any piece, and move it with the mousemove. The issue is that when i touch the transparent par

3条回答
  •  长情又很酷
    2021-01-28 18:56

    SOLVED :)

    i have figured it out... Here's the code to anybody how needs (I have made it right now, so the code is not clean yet):

    Piece Class:

    class Peça : DrawingArea
    {
        private Point _Offset = Point.Empty;
        public Boolean movable = false;
    
        public Image imagem
        {
            get;
            set;
        }
    
        protected override void OnDraw()
        {
            Rectangle location = new Rectangle(0, 0, imagem.Width, imagem.Height);
            this.graphics.DrawImage(imagem, location);
        }
    
        public Boolean Down(Point e, bool propaga = true)
        {
            Bitmap b = new Bitmap(imagem);
            Color? color = null;
            Boolean flag = false;
            try
            {
                color = b.GetPixel(e.X, e.Y);
                if (color.Value.A != 0 && color != null)
                {
                   flag = true;
                }
                else
                {
                    flag = false;
                }
                return flag;
            }
            catch
            {
                return flag;
            }
        }
    }
    

    Form1:

    public partial class Form1 : Form
    {
        private List peças;
        private Point _Offset = Point.Empty;
        private Peça peça1, peça2, peça3, peça4;
        private bool canMove;
        private Peça atual;
        private bool other=false;
        public Form1()
        {
            FormBorderStyle = FormBorderStyle.None;
            WindowState = FormWindowState.Maximized;
            InitializeComponent();
    
            atual = new Peça();
    
            peça1 = new Peça();
            peça2 = new Peça();
            peça3 = new Peça();
            peça4 = new Peça();
            peça1.imagem = Properties.Resources._4p1_1;
            peça2.imagem = Properties.Resources._4p1_2;
            peça3.imagem = Properties.Resources._4p1_3;
            peça4.imagem = Properties.Resources._4p1_4;
    
            peças = new List();
    
            peça1.Name = "peça1";
            peça2.Name = "peça2";
            peça3.Name = "peça3";
            peça4.Name = "peça4";
    
            this.Controls.Add(peça1);
            this.Controls.Add(peça2);
            this.Controls.Add(peça3);
            this.Controls.Add(peça4);
    
            criaListaPecas();
    
            foreach (Peça p in peças)
            {
                p.Size = new Size(p.imagem.Width, p.imagem.Height);
            }
    
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true);
    
            associaEventosPecas();
            canMove = false;
        }
    
        private void associaEventosPecas()
        {
            foreach (Peça p in peças)
            {
                p.MouseMove += Form1_MouseMove;
                p.MouseDown += Form1_MouseDown;
                p.MouseUp += Form1_MouseUp;
            }
        }
    
        private void criaListaPecas()
        {
            peças.Clear();
            foreach (Control p in this.Controls)
            {
                if (p.GetType() == typeof(Peça))
                    peças.Add((Peça)p);
            }
            Console.WriteLine(peças[0].Name);
            Console.WriteLine(peças[1].Name);
            Console.WriteLine(peças[2].Name);
            Console.WriteLine(peças[3].Name);
        }
    
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams handleParam = base.CreateParams;
                handleParam.ExStyle |= 0x02000000;
                return handleParam;
            }
        }
    
        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (sender.GetType().Equals(typeof(Peça)))
            {
                label1.Text = new Point(e.Location.X + (sender as Peça).Location.X, e.Location.Y + (sender as Peça).Location.Y).ToString();
            }
            else
            label1.Text = e.Location.ToString();
            gereMovimento(sender, e);
        }
    
        private void gereMovimento(object sender, MouseEventArgs e)
        {
            if (canMove)
            {
                if (other)
                {
                    Point p = atual.PointToClient(new Point(e.X + (sender as Peça).Location.X, e.Y + (sender as Peça).Location.Y));
    
                    Point newlocation = atual.Location;
                    newlocation.X += p.X - _Offset.X;
                    newlocation.Y += p.Y - _Offset.Y;
                    atual.Location = newlocation;
                }
                else
                {
                    Point newlocation = atual.Location;
                    newlocation.X += e.X - _Offset.X;
                    newlocation.Y += e.Y - _Offset.Y;
                    atual.Location = newlocation;
                }
            }
        }
    
        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            if (sender.GetType().Equals(typeof(Peça)) && e.Button == MouseButtons.Left)
            {
                atual = sender as Peça;
                atual.BringToFront();
                criaListaPecas();
                if (atual.Down(e.Location))
                {
                    _Offset = new Point(e.X, e.Y);
                    canMove = true;
                    other = false;
                }
                else
                {
                    Console.WriteLine(peças[1].PointToClient(new Point(e.X + atual.Location.X, e.Y + atual.Location.Y)));
                    Console.WriteLine(atual.Location);
                    Point p = new Point(); 
                    if (peças[1].ClientRectangle.Contains(peças[1].PointToClient(new Point(e.X + atual.Location.X, e.Y + atual.Location.Y)))
                        && peças[1].Down(peças[1].PointToClient(new Point(e.X + atual.Location.X, e.Y + atual.Location.Y))))
                    {
                        p = peças[1].PointToClient(new Point(e.X + atual.Location.X, e.Y + atual.Location.Y));
                        atual = peças[1];
                        atual.BringToFront();
                        criaListaPecas();
                        _Offset = p;
                        canMove = true;
                        other = true;
                    }
                    else if (peças[2].ClientRectangle.Contains(peças[2].PointToClient(new Point(e.X + atual.Location.X, e.Y + atual.Location.Y)))
                        && peças[2].Down(peças[2].PointToClient(new Point(e.X + atual.Location.X, e.Y + atual.Location.Y))))
                    {
                        p = peças[2].PointToClient(new Point(e.X + atual.Location.X, e.Y + atual.Location.Y));
                        atual = peças[2];
                        atual.BringToFront();
                        criaListaPecas();
                        _Offset = p;
                        canMove = true;
                        other = true;
                    }
                    else if (peças[3].ClientRectangle.Contains(peças[3].PointToClient(new Point(e.X + atual.Location.X, e.Y + atual.Location.Y)))
                        && peças[3].Down(peças[3].PointToClient(new Point(e.X + atual.Location.X, e.Y + atual.Location.Y))))
                    {
                        p = peças[3].PointToClient(new Point(e.X + atual.Location.X, e.Y + atual.Location.Y));
                        atual = peças[3];
                        atual.BringToFront();
                        criaListaPecas();
                        _Offset = p;
                        canMove = true;
                        other = true;
                    }
                }
            }
        }
    
        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            canMove = false;
        }
    }
    

    Apologize the repeated and confused code, but as i said, i have made it seconds ago, and did not clean the code yet ;)

提交回复
热议问题