Reputation: 27
I have made a Canvas (playArea) on which I added 1 Bee (by using playArea.children.Add(bee)
). And I also add new box
every X seconds at random points on the playArea
. I'm able to move my bee
from the current point to the point I click using Storyboard
and DoubleAnimation
.
What I want to do is I want to delete the box
which bee
is passing through (like it should just do playAre.Children.Remove(box)
. I just can't figure it out how to check it.
Here's an example. If I would click on A, my bee
would go to that point and remove the 3 boxes on it's way. I was thinking I should probably use my own EventHandler
(I'm not sure how to make my own yet, but that's another problem). So any ides what should I do, or what condition I should make?
EDIT: Here's how my methods I use looks like. What I do at the beggining, I just draw a bee and add it to my canvas, and every X seconds I just add a new box at random location
//moving the bee to the position which I got from Point p = Mouse.GetPosition(playArea);
public static void MoveBee(UIElement element, double toX, double toY)
{
double fromX = Canvas.GetLeft(element);
double fromY = Canvas.GetTop(element);
Storyboard storyboard = new Storyboard();
DoubleAnimation animationX = CreateDoubleAnimation(element,
fromX, toX, new PropertyPath(Canvas.LeftProperty));
DoubleAnimation animationY = CreateDoubleAnimation(element,
fromY, toY, new PropertyPath(Canvas.TopProperty));
storyboard.Children.Add(animationX);
storyboard.Children.Add(animationY);
storyboard.Begin();
}
public static DoubleAnimation CreateDoubleAnimation(UIElement element,
double from, double to, PropertyPath propertyToAnimate)
{
DoubleAnimation animation = new DoubleAnimation();
Storyboard.SetTarget(animation, element);
Storyboard.SetTargetProperty(animation, propertyToAnimate);
animation.From = from;
animation.To = to;
animation.Duration = TimeSpan.FromSeconds(3);
return animation;
}
public void DrawBox()
{
BoxControl newBox = new BoxControl();
playArea.Children.Add(newBox);
Canvas.SetTop(newBox, random.Next(0, 419));
Canvas.SetLeft(newBox, random.Next(0, 792));
}
Upvotes: 1
Views: 91
Reputation: 72
You could use the CurrentTimeInvalidated event handler on your animations. See code below for details.
public partial class MainWindow : Window
{
public Random Rng { get; set; }
public MainWindow()
{
InitializeComponent();
Rng = new Random(0);
do
{
AddBoxToRandomPointInPlayArea();
} while (PlayArea.Children.Count < 10);
}
private void AddBoxToRandomPointInPlayArea()
{
var x = Rng.Next(0, Convert.ToInt32(PlayArea.Width));
var y = Rng.Next(0, Convert.ToInt32(PlayArea.Height));
var box = new Rectangle
{
Height = 10,
Width = 30,
Fill = Brushes.Brown
};
PlayArea.Children.Add(box);
Canvas.SetLeft(box, x);
Canvas.SetTop(box, y);
}
private void PlayArea_MouseDown(object sender, MouseButtonEventArgs e)
{
var x = Canvas.GetLeft(Bee);
var y = Canvas.GetTop(Bee);
var storyboard = new Storyboard();
var xTranslation = new DoubleAnimation(x, e.GetPosition(PlayArea).X, new Duration(new TimeSpan(0, 0, 5)));
Storyboard.SetTargetProperty(xTranslation, new PropertyPath(Canvas.LeftProperty));
xTranslation.CurrentTimeInvalidated += CheckForCollidingBoxesAndRemoveIfNeeded;
storyboard.Children.Add(xTranslation);
var yTranslation = new DoubleAnimation(y, e.GetPosition(PlayArea).Y, new Duration(new TimeSpan(0, 0, 5)));
Storyboard.SetTargetProperty(yTranslation, new PropertyPath(Canvas.TopProperty));
yTranslation.CurrentTimeInvalidated += CheckForCollidingBoxesAndRemoveIfNeeded;
storyboard.Children.Add(yTranslation);
Bee.BeginStoryboard(storyboard);
}
private void CheckForCollidingBoxesAndRemoveIfNeeded(object sender, EventArgs eventArgs)
{
var idxToRemoveAt = GetIndexOfBoxCollidingWithBee;
if ( idxToRemoveAt != -1 )
{
PlayArea.Children.RemoveAt(idxToRemoveAt);
}
}
/// <summary>
/// returns 0 if no boxes collide, otherwise the number is the index of the box in the
/// </summary>
public int GetIndexOfBoxCollidingWithBee
{
get
{
var beeTopLeft = PointToScreen(new Point(Canvas.GetLeft(Bee), Canvas.GetTop(Bee))); // local to world coordinates
var beeCentroid = new Point((beeTopLeft.X + Bee.ActualWidth) * 0.5, (beeTopLeft.Y + Bee.ActualHeight) * 0.5); // center point of bee
for (var idx = 0; idx < PlayArea.Children.Count; idx++)
{
var child = PlayArea.Children[idx];
var currentBoxInSearch = child as Rectangle;
if (currentBoxInSearch != null)
{
var boxTopLeft = PointToScreen(new Point(Canvas.GetLeft(currentBoxInSearch), Canvas.GetTop(currentBoxInSearch))); // local to world coordinates
var boxCentroid = new Point((boxTopLeft.X + currentBoxInSearch.ActualWidth) * 0.5, (boxTopLeft.Y + currentBoxInSearch.ActualHeight) * 0.5); // center point of bee
var xCollided = false;
var yCollided = false;
if (Math.Abs(beeCentroid.X - boxCentroid.X) < Bee.ActualWidth*0.5)
xCollided = true;
if (Math.Abs(beeCentroid.Y - boxCentroid.Y) < Bee.ActualHeight*0.5)
yCollided = true;
if (xCollided && yCollided)
return idx;
}
}
return -1;
}
}
}
Upvotes: 2