Я создаю игру-головоломку в winforms, и я хочу распознать наведение мыши на любую часть и переместить ее с помощью мыши. Проблема в том, что когда я прикасаюсь к прозрачной части кусочка головоломки, я хочу проверить, есть ли за ним какой-нибудь кусочек, и если да, то начать движение мыши этого другого кусочка, понял?
Я также могу распознать, было ли наведение мыши над изображением или это произошло в прозрачной части кусочка головоломки. Моя проблема состоит в том, чтобы найти лучший способ передать событие мыши на часть позади.
Спасибо заранее.
ОБНОВЛЕНИЕ 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 {
}
}
}
Следующий код — это моя DrawingArea (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;
}
}
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();
}
}
И вы также можете увидеть мой код формы:
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;
}
}
}
Это мои части, и когда я касаюсь прозрачного пространства в первой части, я хочу взять вторую и переместить ее на мышке вместо того, чтобы ничего не делать...
Это выглядит так:
Извините за мой плохой английский.
ОБНОВЛЕНИЕ 2
Я думаю, что подобрался очень близко к разгадке, но сейчас происходит что-то странное, когда я касаюсь части за другой, она исчезает... Что я делаю не так?
НЕКОТОРЫЕ ОБНОВЛЕНИЯ КОДА
Класс изделия:
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; }
}
}
Форма1:
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;
}
}
}
}
Заранее спасибо еще раз :)
puzzle
Control
?Drawing
? или что? - person Sriram Sakthivel   schedule 13.05.20140;0
. Лучше иметь выделенную переменнуюbool
для состояния (например,isDragging
,isNotMoving
и т. д.), чем использовать специальные значения (Point.Empty
). - person Sinatr   schedule 13.05.2014