ps: 1.处理silverlight 工作流(1)基类
2.处理在活动 拖动过程中 活动与活动不能重叠
3.提供 一个方法获取 所有活动列表
4.提供一个方法根据坐标获取活动实例(为后面的活动之间连线做准备)
效果:
先贴出基类代码:
定义 一些基本的属性
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
public
class
baseActive : Canvas
{
// 保存节点
protected Point movePoint;
// 是否可以移动
protected bool IsMove = false ;
public double Canvas_Top
{
get { return Canvas.GetTop( this ); }
set { Canvas.SetTop( this , value); }
}
public double Canvas_Left
{
get { return Canvas.GetLeft( this ); }
set { Canvas.SetLeft( this , value); }
}
// 是否是模板
private bool isbase = true ;
public bool Isbase
{
get { return isbase; }
set { isbase = value; }
}
public baseActive()
{
}
}
{
// 保存节点
protected Point movePoint;
// 是否可以移动
protected bool IsMove = false ;
public double Canvas_Top
{
get { return Canvas.GetTop( this ); }
set { Canvas.SetTop( this , value); }
}
public double Canvas_Left
{
get { return Canvas.GetLeft( this ); }
set { Canvas.SetLeft( this , value); }
}
// 是否是模板
private bool isbase = true ;
public bool Isbase
{
get { return isbase; }
set { isbase = value; }
}
public baseActive()
{
}
}
模板类:
主要定义 事件处理
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
//
定义委托
public delegate FrameworkElement TempleElement();
public class templateActive : baseActive
{ // 创建的孩子element
private templateActive Chilren = null ;
// 委托 用于调用方法 生成 element
TempleElement Tetemple;
public templateActive(TempleElement temp)
{ // 保存委托 及方法引用地址(个人理解:委托有点像 C++里面的指针)
Tetemple = temp;
this .MouseMove += (sender, e) =>
{
if (IsMove)
{
templateActive element = sender as templateActive;
Obsacles obs = Obsacles.Instance;
if (element.Isbase)
{
// 生成element
Chilren = new templateActive(Tetemple);
// 并且新 element 为模板
Chilren.Isbase = true ;
// 指定新element的位置为原来element 地址
Chilren.Canvas_Left = Canvas_Left;
Chilren.Canvas_Top = Canvas_Top;
Chilren.Opacity = 1 ;
Canvas parent = element.Parent as Canvas;
Canvas.SetZIndex(Chilren, 0 );
// 添加到Canvas
parent.Children.Add(Chilren);
// 改变原 element不为模板,保证一次拖动产生一个element
element.Isbase = false ;
element.Opacity = 0.5 ;
// 添加障碍物
obs.AddElement(element);
}
// 判断前方是否是障碍物,(移动过快可能穿过障碍物,但是不是设计需要,只用 活动之间不覆盖就ok,在游戏中就要考虑越界的回退问题)
if ( ! Isbase)
{
double newtop = e.GetPosition(element).Y - movePoint.Y;
double newleft = e.GetPosition(element).X - movePoint.X;
double NowTop = newtop + ( double )element.GetValue(Canvas.TopProperty);
double NowLeft = newleft + ( double )element.GetValue(Canvas.LeftProperty);
bool isobs = obs.CheckIsObs(element, NowTop, NowLeft);
Canvas.SetZIndex(element, 1000 );
if ( ! isobs)
{
element.SetValue(Canvas.TopProperty, NowTop);
element.SetValue(Canvas.LeftProperty, NowLeft);
movePoint = e.GetPosition(element);
}
}
}
};
this .MouseLeftButtonUp += (sender, e) =>
{
FrameworkElement element = sender as FrameworkElement;
Obsacles obs = Obsacles.Instance;
obs.UpDateObs(element);
IsMove = false ;
element.ReleaseMouseCapture();
element.Cursor = null ;
element.Opacity = 1.0 ;
movePoint.X = movePoint.Y = 0 ;
};
this .MouseLeftButtonDown += (sender, e) =>
{
FrameworkElement element = sender as FrameworkElement;
if (element != null )
{
movePoint = e.GetPosition(element);
element.CaptureMouse();
element.Cursor = Cursors.Hand;
IsMove = true ;
}
};
this .Children.Add(temp());
}
}
public delegate FrameworkElement TempleElement();
public class templateActive : baseActive
{ // 创建的孩子element
private templateActive Chilren = null ;
// 委托 用于调用方法 生成 element
TempleElement Tetemple;
public templateActive(TempleElement temp)
{ // 保存委托 及方法引用地址(个人理解:委托有点像 C++里面的指针)
Tetemple = temp;
this .MouseMove += (sender, e) =>
{
if (IsMove)
{
templateActive element = sender as templateActive;
Obsacles obs = Obsacles.Instance;
if (element.Isbase)
{
// 生成element
Chilren = new templateActive(Tetemple);
// 并且新 element 为模板
Chilren.Isbase = true ;
// 指定新element的位置为原来element 地址
Chilren.Canvas_Left = Canvas_Left;
Chilren.Canvas_Top = Canvas_Top;
Chilren.Opacity = 1 ;
Canvas parent = element.Parent as Canvas;
Canvas.SetZIndex(Chilren, 0 );
// 添加到Canvas
parent.Children.Add(Chilren);
// 改变原 element不为模板,保证一次拖动产生一个element
element.Isbase = false ;
element.Opacity = 0.5 ;
// 添加障碍物
obs.AddElement(element);
}
// 判断前方是否是障碍物,(移动过快可能穿过障碍物,但是不是设计需要,只用 活动之间不覆盖就ok,在游戏中就要考虑越界的回退问题)
if ( ! Isbase)
{
double newtop = e.GetPosition(element).Y - movePoint.Y;
double newleft = e.GetPosition(element).X - movePoint.X;
double NowTop = newtop + ( double )element.GetValue(Canvas.TopProperty);
double NowLeft = newleft + ( double )element.GetValue(Canvas.LeftProperty);
bool isobs = obs.CheckIsObs(element, NowTop, NowLeft);
Canvas.SetZIndex(element, 1000 );
if ( ! isobs)
{
element.SetValue(Canvas.TopProperty, NowTop);
element.SetValue(Canvas.LeftProperty, NowLeft);
movePoint = e.GetPosition(element);
}
}
}
};
this .MouseLeftButtonUp += (sender, e) =>
{
FrameworkElement element = sender as FrameworkElement;
Obsacles obs = Obsacles.Instance;
obs.UpDateObs(element);
IsMove = false ;
element.ReleaseMouseCapture();
element.Cursor = null ;
element.Opacity = 1.0 ;
movePoint.X = movePoint.Y = 0 ;
};
this .MouseLeftButtonDown += (sender, e) =>
{
FrameworkElement element = sender as FrameworkElement;
if (element != null )
{
movePoint = e.GetPosition(element);
element.CaptureMouse();
element.Cursor = Cursors.Hand;
IsMove = true ;
}
};
this .Children.Add(temp());
}
}
算法类:
考虑到 只存在一个障碍物实例 所有运用单件设计模式
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
public
sealed
class
Obsacles
{
// 障碍物集合
List < FrameworkElement > elements = new List < FrameworkElement > ();
// 2惟矩阵 和 障碍物关联
Dictionary < Point, FrameworkElement > obs_element = new Dictionary < Point, FrameworkElement > ();
static readonly Obsacles Ob = new Obsacles();
// 构建2维矩阵 0表示不是障碍,1表示 是障碍
static int [,] obs = new int [ 1024 , 1024 ];
static Obsacles()
{
}
private int pre = 1 ;
public int Pre
{
get { return pre; }
set { pre = value;}
}
Obsacles()
{
}
public static Obsacles Instance
{
get
{
return Ob;
}
}
/// <summary>
/// 添加障碍物
/// </summary>
/// <param name="element"></param>
public void AddElement(FrameworkElement element)
{
elements.Add(element);
baseActive active = element as baseActive;
// 获取元素属性
int Canvas_left = ( int )(active.Canvas_Left);
int Canvas_top = ( int )(active.Canvas_Top);
int width = ( int )active.Width;
int height = ( int )active.Height;
// 添加障碍物 80,40 可以通过活动的 宽和 高获取 这里只是比较规则的 障碍物
Point p = new Point();
for ( int i = Canvas_left / pre; i < (Canvas_left + 80 ) / pre; i ++ )
{
for ( int j = Canvas_top / pre; j < (Canvas_top + 40 ) / pre; j ++ )
{
obs[i, j] = 1 ;
p.X = i;
p.Y = j;
if (obs_element.ContainsKey(p))
{
obs_element[p] = element;
}
else
{
obs_element.Add( new Point(i, j), element);
}
}
}
}
// 获取所有活动
public List < FrameworkElement > getAllElement()
{
return elements;
}
// 更新 element 障碍物位置
public void UpDateObs(FrameworkElement element)
{
// 是否包含障碍物
elements.Remove(element);
if (obs_element.ContainsValue(element))
{
foreach (KeyValuePair < Point, FrameworkElement > keyvalue in obs_element)
{
if (keyvalue.Value == element)
{
obs[( int )keyvalue.Key.X / pre, ( int )keyvalue.Key.Y / pre] = 0 ;
}
}
}
// 添加障碍物
AddElement(element);
}
// 根据坐标获取element
public FrameworkElement GetElementByPiont(Point point)
{
if (obs[( int )point.X / pre, ( int )point.Y / pre] == 1 )
{
return obs_element[point];
}
else
return null ;
}
/// <summary>
///
/// </summary>
/// <param name="element"></param>
/// <param name="oldpoint"></param>
/// <returns> bool </returns>
public bool CheckIsObs(FrameworkElement element, double top, double left)
{
baseActive active = element as baseActive;
// 获取元素属性
int Canvas_left = ( int )(left);
int Canvas_top = ( int )(top);
bool Isobs = false ;
// 判断是否是障碍物 80,40 可以通过活动的 宽和 高获取 这里只是比较规则的 障碍物
Point p = new Point();
for ( int i = Canvas_left / pre; i < (Canvas_left + 80 ) / pre; i ++ )
{
for ( int j = Canvas_top / pre; j < (Canvas_top + 40 ) / pre; j ++ )
{
p.X = i;
p.Y = j;
if (obs[i, j] == 1 && GetElementByPiont(p) != element)
{
Isobs = true ;
}
}
}
// is line
return Isobs;
}
}
{
// 障碍物集合
List < FrameworkElement > elements = new List < FrameworkElement > ();
// 2惟矩阵 和 障碍物关联
Dictionary < Point, FrameworkElement > obs_element = new Dictionary < Point, FrameworkElement > ();
static readonly Obsacles Ob = new Obsacles();
// 构建2维矩阵 0表示不是障碍,1表示 是障碍
static int [,] obs = new int [ 1024 , 1024 ];
static Obsacles()
{
}
private int pre = 1 ;
public int Pre
{
get { return pre; }
set { pre = value;}
}
Obsacles()
{
}
public static Obsacles Instance
{
get
{
return Ob;
}
}
/// <summary>
/// 添加障碍物
/// </summary>
/// <param name="element"></param>
public void AddElement(FrameworkElement element)
{
elements.Add(element);
baseActive active = element as baseActive;
// 获取元素属性
int Canvas_left = ( int )(active.Canvas_Left);
int Canvas_top = ( int )(active.Canvas_Top);
int width = ( int )active.Width;
int height = ( int )active.Height;
// 添加障碍物 80,40 可以通过活动的 宽和 高获取 这里只是比较规则的 障碍物
Point p = new Point();
for ( int i = Canvas_left / pre; i < (Canvas_left + 80 ) / pre; i ++ )
{
for ( int j = Canvas_top / pre; j < (Canvas_top + 40 ) / pre; j ++ )
{
obs[i, j] = 1 ;
p.X = i;
p.Y = j;
if (obs_element.ContainsKey(p))
{
obs_element[p] = element;
}
else
{
obs_element.Add( new Point(i, j), element);
}
}
}
}
// 获取所有活动
public List < FrameworkElement > getAllElement()
{
return elements;
}
// 更新 element 障碍物位置
public void UpDateObs(FrameworkElement element)
{
// 是否包含障碍物
elements.Remove(element);
if (obs_element.ContainsValue(element))
{
foreach (KeyValuePair < Point, FrameworkElement > keyvalue in obs_element)
{
if (keyvalue.Value == element)
{
obs[( int )keyvalue.Key.X / pre, ( int )keyvalue.Key.Y / pre] = 0 ;
}
}
}
// 添加障碍物
AddElement(element);
}
// 根据坐标获取element
public FrameworkElement GetElementByPiont(Point point)
{
if (obs[( int )point.X / pre, ( int )point.Y / pre] == 1 )
{
return obs_element[point];
}
else
return null ;
}
/// <summary>
///
/// </summary>
/// <param name="element"></param>
/// <param name="oldpoint"></param>
/// <returns> bool </returns>
public bool CheckIsObs(FrameworkElement element, double top, double left)
{
baseActive active = element as baseActive;
// 获取元素属性
int Canvas_left = ( int )(left);
int Canvas_top = ( int )(top);
bool Isobs = false ;
// 判断是否是障碍物 80,40 可以通过活动的 宽和 高获取 这里只是比较规则的 障碍物
Point p = new Point();
for ( int i = Canvas_left / pre; i < (Canvas_left + 80 ) / pre; i ++ )
{
for ( int j = Canvas_top / pre; j < (Canvas_top + 40 ) / pre; j ++ )
{
p.X = i;
p.Y = j;
if (obs[i, j] == 1 && GetElementByPiont(p) != element)
{
Isobs = true ;
}
}
}
// is line
return Isobs;
}
}
准备完成后:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
public
MainPage()
{
InitializeComponent();
Initialize();
}
/// <summary>
/// 添加活动模板
/// </summary>
protected void Initialize()
{
templateActive demo2 = new templateActive(() => {
Rectangle rt = new Rectangle();
rt.Width = 80 ;
rt.Height = 40 ;
rt.Fill = new SolidColorBrush(Colors.Red);
rt.RadiusX = 40 ;
rt.RadiusY = 20 ;
return rt;
});
demo2.Canvas_Left = 100 ;
demo2.Canvas_Top = 100 ;
templateActive demo3 = new templateActive(() =>
{
return new Approve();
});
demo3.Canvas_Left = 100 ;
demo3.Canvas_Top = 300 ;
MainZone.Children.Add(demo2);
MainZone.Children.Add(demo3);
}
// test
private void button1_Click( object sender, RoutedEventArgs e)
{
Obsacles ob = Obsacles.Instance;
List < FrameworkElement > lists = ob.getAllElement();
foreach (FrameworkElement element in lists)
{
templateActive ba = element as templateActive;
MessageBox.Show(ba.Canvas_Left.ToString() + " --- " + ba.Canvas_Top.ToString());
templateActive bb = ob.GetElementByPiont( new Point(ba.Canvas_Left, ba.Canvas_Top)) as templateActive;
MessageBox.Show(bb.Canvas_Left.ToString() + " --- " + bb.Canvas_Top.ToString());
}
}
{
InitializeComponent();
Initialize();
}
/// <summary>
/// 添加活动模板
/// </summary>
protected void Initialize()
{
templateActive demo2 = new templateActive(() => {
Rectangle rt = new Rectangle();
rt.Width = 80 ;
rt.Height = 40 ;
rt.Fill = new SolidColorBrush(Colors.Red);
rt.RadiusX = 40 ;
rt.RadiusY = 20 ;
return rt;
});
demo2.Canvas_Left = 100 ;
demo2.Canvas_Top = 100 ;
templateActive demo3 = new templateActive(() =>
{
return new Approve();
});
demo3.Canvas_Left = 100 ;
demo3.Canvas_Top = 300 ;
MainZone.Children.Add(demo2);
MainZone.Children.Add(demo3);
}
// test
private void button1_Click( object sender, RoutedEventArgs e)
{
Obsacles ob = Obsacles.Instance;
List < FrameworkElement > lists = ob.getAllElement();
foreach (FrameworkElement element in lists)
{
templateActive ba = element as templateActive;
MessageBox.Show(ba.Canvas_Left.ToString() + " --- " + ba.Canvas_Top.ToString());
templateActive bb = ob.GetElementByPiont( new Point(ba.Canvas_Left, ba.Canvas_Top)) as templateActive;
MessageBox.Show(bb.Canvas_Left.ToString() + " --- " + bb.Canvas_Top.ToString());
}
}
后面 将处理活动于 活动之间的 连线