鼠标一个谜两片向下 [英] Mouse down between two pieces of a puzzle

查看:152
本文介绍了鼠标一个谜两片向下的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建设的WinForms一个益智游戏,我要承认在鼠标按下任何一块,并用鼠标移动移动。
中的问题是,当我触碰一块拼图的透明部分,我想验证是否存在背后,一个任何一块,如果是这样,开始了另一片的鼠标移动,懂吗?

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 part of the puzzle piece, i want to verify if there is any piece behind that one, and if so, start the mousemove of that other piece, got it?

我也能够认识到,如果鼠标按下是在图像,或者如果它在一块拼图的透明部分发生。我的问题是要获得通过鼠标事件到片后面的最佳方式。

I am also able to recognize if the mousedown was over the image, or if it happens in the transparent part of the puzzle piece. My problem is to get the best way to pass the mouse event to the piece behind.

预先非常感谢

更新1

下面是一块拼图类:

class Peça : DrawingArea
{
    private Point _Offset = Point.Empty;
    public Image imagem
    {
        get;
        set;
    }


    protected override void OnDraw()
    {
        Rectangle location = new Rectangle(0, 0, imagem.Width, imagem.Height);
        this.graphics.DrawImage(imagem, location);
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        if (_Offset != Point.Empty)
        {
            Point newlocation = this.Location;
            newlocation.X += e.X - _Offset.X;
            newlocation.Y += e.Y - _Offset.Y;
            this.Location = newlocation;
        }
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        _Offset = Point.Empty;
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        Down(e);
        //Console.WriteLine(color.ToString());
    }

    public void Down(MouseEventArgs e)
    {
        Bitmap b = new Bitmap(imagem);
        Color? color = null;
        try
        {
            color = b.GetPixel(e.X, e.Y);
            if (color.Value.A != 0 && color != null)
            {
                if (e.Button == MouseButtons.Left)
                {
                    _Offset = new Point(e.X, e.Y);
                    this.BringToFront();
                }
            }
        }
        catch {
             }
    }
} 

下面的代码,是我的绘图区(面板),我为了与透明度的工作创造:

The following code, is my DrawingArea (Panel) that i create in order to work with transparency:

abstract public class DrawingArea : Panel
{
    protected Graphics graphics;
    abstract protected void OnDraw();

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT

            return cp;
        }
    }

    public DrawingArea()
    {

    }

    protected override void OnPaintBackground(PaintEventArgs pevent)
    {

    }

    protected override void OnPaint(PaintEventArgs e)
    {

        this.graphics = e.Graphics;


        this.graphics.TextRenderingHint =
            System.Drawing.Text.TextRenderingHint.AntiAlias;
        this.graphics.InterpolationMode =
            System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
        this.graphics.PixelOffsetMode =
            System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
        this.graphics.SmoothingMode =
            System.Drawing.Drawing2D.SmoothingMode.HighQuality;


        OnDraw();
    } 
}

和你也可以看到我的表单代码:

And you can also see my Form code:

 public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true);
    }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams handleParam = base.CreateParams;
            handleParam.ExStyle |= 0x02000000;       
            return handleParam;
        }
    }
}



这些都是我的作品,和当我在第一块触摸透明的空间,我想拿起第二个并将其移动mouseMouse而不是无所事事...

Those are my pieces, and when i touch the transparent space in the first piece, i want to pick up the second one and move it on mouseMouse instead of doing nothing...

它看起来像这样

道歉我的英语不好。

更新2

我觉得我已经非常接近了解决方案,但一些奇怪的事情发生了,现在,当我触片背后还有一个,它消失了......
我究竟做错了什么?

I think i am getting very close to the solution, but something strange happens now, when i touch the piece behind another one, it disappear... What am i doing wrong?

一些代码更新

片类:

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 void Move(MouseEventArgs e)
    {
        if (_Offset != Point.Empty)
        {
            Point newlocation = this.Location;
            newlocation.X += e.X - _Offset.X;
            newlocation.Y += e.Y - _Offset.Y;
            this.Location = newlocation;
        }
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        _Offset = Point.Empty;
        movable = false;
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        Down(e);
        //Console.WriteLine(color.ToString());
    }

    public Boolean Down(MouseEventArgs e, bool propaga=true)
    {
        Form parentForm = (this.Parent as Form);
        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)
            {
                if (e.Button == MouseButtons.Left)
                {
                    _Offset = new Point(e.X, e.Y);
                    this.BringToFront();
                    flag = true;
                    movable = true;
                }
            }
            else
            {
                if(propaga)
                (this.Parent as Form1).propagaEvento(this, e);
                flag = false;

            }
            return flag; 
        }
        catch {
            return flag; }
    }
}



Form1中:

Form1:

public partial class Form1 : Form
{
    private List<Peça> peças;
    private Point _Offset = Point.Empty;
    public Form1()
    {
        InitializeComponent();

        peças = new List<Peça>();
        SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true);
        criaListaPecas();
        associaEventosPecas();      
    }

    private void associaEventosPecas()
    {
        foreach (Peça p in peças)
        {
            p.MouseMove += Form1_MouseMove;
        }
    }

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

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams handleParam = base.CreateParams;
            handleParam.ExStyle |= 0x02000000;       
            return handleParam;
        }
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        label1.Text = e.Location.ToString();
        gereMovimento(e);
    }

    private void gereMovimento(MouseEventArgs e)
    {
        foreach (Peça p in peças)
        {
            if (p.movable)
            {
                p.Move(e);
            }
        }
    }

    internal void propagaEvento(Peça peça, MouseEventArgs e)
    {
        foreach (Peça p in peças)
        {
            if (p != peça)
            {
                if (p.Down(e, false))
                    break;
            }
        }
    }
}



谢谢提前再次:)

Thanks in advance again :)

推荐答案

解决:)

我已经想通了......
下面的代码给任何人需要怎样
(我已现在,所以代码不干净还):

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的:

Form1:

public partial class Form1 : Form
{
    private List<Peça> 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ça>();

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

这篇关于鼠标一个谜两片向下的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆