morther Posted May 14, 2014 at 10:58 AM Report #555577 Posted May 14, 2014 at 10:58 AM (edited) Boas pessoal, estou a desenvolver um jogo em winforms (c#). Trata-se basicamente de um puzzle, com peças que são imagens com transparência. Pretendo que seja reconhecido o toque sobre qualquer peça, e que a peça selecionada com o "MouseDown" acompanhe o "MouseMove" para se deslocar. O problema surge quando existe um toque numa das partes transparentes da peça, e quero verificar se existe alguma peça por baixo, de forma a trazer essa para a frente e começar a mover-se. Já consigo identificar se o toque do rato foi feito na peça ou numa das partes transparentes, no entanto, não estou a conseguir passar o evento do rato corretamente para a peça que se encontra por baixo. Qual a melhor forma para conseguir o que pretendo? O que estou a fazer de errado? Deixo aqui algum código para perceberem o que estou a tentar fazer: FORM: 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); } } } } PEÇA: 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); } 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 { flag = false; } return flag; } catch { return flag; } } } DRAWING AREA (PANEL): 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; } } 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(); } } Deixo também uma pequena imagem ilustrativa das peças: Qualquer ajuda é bem-vinda 😉 Obrigado Edited May 14, 2014 at 05:10 PM by morther
morther Posted May 14, 2014 at 05:14 PM Author Report #555664 Posted May 14, 2014 at 05:14 PM Consegui Resolver o problema agora mesmo, deixo aqui as alterações no código para quem precisar: (Não liguem à confusão do código, ainda não tive tempo para juntar partes repetidas etc.) PEÇA: 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; } } } FORM: 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; } } Alguma questão disponham 😉
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now