I want to create a simple windows phone app that has a ball bouncing around. Is there any chance creating this app without using XNA?
Thanks.
Sure, you can do it using XAML. Create a ball in canvas. Then change its position using Canvas.Left, and Canvast.Top properties. Create DispatcherTimer to have a game loop.
MainPage.xaml
<Canvas>
<Ellipse x:Name="MyBall"
Width="64"
Height="64"
Fill="Red" />
</Canvas>
Change ball position with timer (code below).
MainPage.xaml.cs
// Your "game loop" timer
DispatcherTimer timer;
// Ball position
int x = 0;
int y = 0;
public MainPage()
{
InitializeComponent();
timer = new DispatcherTimer();
timer.Tick += OnTimerTick;
timer.Interval = TimeSpan.Zero; // It's about 60 fps
timer.Start();
}
// This is your "game loop", where you can change things, move, animate, etc.
private void OnTimerTick(object sender, EventArgs e)
{
// Change ball position
x++;
y++;
// Apply new position
Canvas.SetLeft(MyBall, x); // Set x
Canvas.SetTop(MyBall, y); // Set y
}
you could use Physics Helper Xaml from Codeplex to do this:
https://physicshelperxaml.codeplex.com/
here is some older examples that does it in silverlight using an older version of the library might be useful:
http://channel9.msdn.com/coding4fun/articles/Creating-a-Pinball-Game-in-Silverlight-Using-the-Physics-Helper-Library--Farseer-Physics
Related
I have a Grid which is as high as the application and has the width of 50. I have got a button in it on the left top with the width of 50 also. I want to move this button along the vertical left axis by dragging it with the mouse. But it should be stil able to be clicked normally. I tried to do this with the drag-and-drop sample by microsoft but the procedure I want to implement is not quite drag-and-drop. How can I implement this by using XAML and c++-cx as code behind in an universal windows app ?
My XAML-Code for the Grid/Button:
<Grid x:Name="Grid1" Width="50" >
<Button x:Name="btnMove" Content="Move me!" Background="PaleGreen" Click="btnMove_Click" VerticalAlignment="Top" HorizontalAlignment="Left" Width="50" Height="50"></Button>
</Grid>
For your requirement, you could move the button on the vertical axis by using ManipulationDelta class. And you could achieve it with the following code.
For more please refer to Handle pointer input. Here is official code sample.
MainPage::MainPage()
{
InitializeComponent();
InitManipulationTransforms();
btnMove->ManipulationDelta += ref new ManipulationDeltaEventHandler(this, &MainPage::btnMove_ManipulationDelta);
btnMove->ManipulationMode = ManipulationModes::TranslateX;
}
void App14::MainPage::InitManipulationTransforms()
{
transforms = ref new TransformGroup();
previousTransform = ref new MatrixTransform();
previousTransform->Matrix = Matrix::Identity;
deltaTransform = ref new CompositeTransform();
transforms->Children->Append(previousTransform);
transforms->Children->Append(deltaTransform);
// Set the render transform on the rect
btnMove->RenderTransform = transforms;
}
void App14::MainPage::btnMove_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
}
void MainPage::btnMove_ManipulationDelta(Platform::Object^ sender, ManipulationDeltaRoutedEventArgs^ e)
{
previousTransform->Matrix = transforms->Value;
// Get center point for rotation
Point center = previousTransform->TransformPoint(Point(e->Position.X, e->Position.Y));
deltaTransform->CenterX = center.X;
deltaTransform->CenterY = center.Y;
// Look at the Delta property of the ManipulationDeltaRoutedEventArgs to retrieve
// the rotation, scale, X, and Y changes
deltaTransform->Rotation = e->Delta.Rotation;
deltaTransform->TranslateX = e->Delta.Translation.X;
deltaTransform->TranslateY = e->Delta.Translation.Y;
}
You could change the scrolling direction of the button by modifying the ManipulationMode of button.
btnMove->ManipulationMode = ManipulationModes::TranslateY;
In Windows 8.1, I'm using the new SettingsFlyout control. The flyout animates in correctly and will animate out if you use the control's built-in back button to return to the Settings Charm flyout. But if you light dismiss by clicking outside the flyout, it disappears without a transition animation.
How do you animate a transition out when you light dismiss the SettingsFlyout? (I don't want to return to the Settings Charm flyout, I just want it to slide out on a light dismiss.)
Matt, what you want to do should be easily achievable but is currently not supported by the XAML SettingsFlyout API out of the box. As Jerry points out, there are transitions that allow an animate out effect (in XAML you want EdgeUIThemeTransition). Unfortunately, there is no API support on SettingsFlyout to add this transition, but you can get it to work using your own private popup to host the SettingsFlyout (more on this below):
public sealed partial class SettingsFlyout1 : SettingsFlyout
{
Popup _p;
Border _b;
public SettingsFlyout1()
{
this.InitializeComponent();
BackClick += SettingsFlyout1_BackClick;
Unloaded += SettingsFlyout1_Unloaded;
Tapped += SettingsFlyout1_Tapped;
}
void SettingsFlyout1_BackClick(object sender, BackClickEventArgs e)
{
_b.Child = null;
SettingsPane.Show();
}
void SettingsFlyout1_Unloaded(object sender, RoutedEventArgs e)
{
if (_p != null)
{
_p.IsOpen = false;
}
}
void SettingsFlyout1_Tapped(object sender, TappedRoutedEventArgs e)
{
e.Handled = true;
}
public void ShowCustom()
{
_p = new Popup();
_b = new Border();
_b.ChildTransitions = new TransitionCollection();
// TODO: if you support right-to-left builds, make sure to test all combinations of RTL operating
// system build (charms on left) and RTL flow direction for XAML app. EdgeTransitionLocation.Left
// may need to be used for RTL (and HorizontalAlignment.Left on the SettingsFlyout below).
_b.ChildTransitions.Add(new EdgeUIThemeTransition() { Edge = EdgeTransitionLocation.Right });
_b.Background = new SolidColorBrush(Colors.Transparent);
_b.Width = Window.Current.Bounds.Width;
_b.Height = Window.Current.Bounds.Height;
_b.Tapped += b_Tapped;
this.HorizontalAlignment = HorizontalAlignment.Right;
_b.Child = this;
_p.Child = _b;
_p.IsOpen = true;
}
void b_Tapped(object sender, TappedRoutedEventArgs e)
{
Border b = (Border)sender;
b.Child = null;
}
}
Full solution for this sample: https://github.com/finnigantime/Samples/tree/master/examples/Win8Xaml/SettingsFlyout_AnimateOut
I think SettingsFlyout should have API support for your scenario, so I filed a work item on the XAML team. In the future, such requests/issues can be raised on the MSDN forum as well (moderated by MSFT folks). The limitation here is that SettingsFlyout is implemented on top of Popup with IsLightDismissEnabled="True", and the light-dismiss event currently closes the Popup immediately without allowing unloading child transitions to run. I think this can be overcome and transitions can be supported at the SettingsFlyout API level to enable your scenario.
You need to use the HideEdgeUI animation
Read this: http://msdn.microsoft.com/en-us/library/windows/apps/jj655412.aspx
I wrote a UserControl in WinRT and I want to make it moveable with a finger.
When I move it using a pen or mouse it is still moving but not when i use a finger.
The PointerMoved is not triggert when I use a finger.
Here is the simple xaml:
<UserControl>
<Rectangle PointerPressed="PointerPressed" PointerMoved="PointerMoved"/>
</UserControl>
and here is the code:
private Point position;
void PointerPressed(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
Rectangle r = sender as Rectangle;
var pointerPoint = e.GetCurrentPoint(r);
position = pointerPoint.Position;
}
void PointerMoved(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
Rectangle r = sender as Rectangle;
var delta = e.GetCurrentPoint(r).Position;
r.Margin = new Thickness(r.Margin.Left + delta.X - position.X, r.Margin.Top + delta.Y - position.Y, 0, 0);
}
What do I miss here?
Edit:
I am working with Windows 8.1 and VisualStudio 2013.
Maybe it's a new feature^^
It's simpler than you think!
<Rectangle Width="100" Height="100" Fill="White"
ManipulationMode="TranslateX,TranslateY"
ManipulationDelta="Rectangle_ManipulationDelta_1" />
private void Rectangle_ManipulationDelta_1(object sender, ManipulationDeltaRoutedEventArgs e)
{
var _Rectangle = sender as Windows.UI.Xaml.Shapes.Rectangle;
var _Transform = (_Rectangle.RenderTransform as CompositeTransform)
?? (_Rectangle.RenderTransform = new CompositeTransform()) as CompositeTransform;
_Transform.TranslateX += e.Delta.Translation.X;
_Transform.TranslateY += e.Delta.Translation.Y;
}
Best of luck!
First, don't sure you can move by pen or mouse because in PointerMoved event you should check the e.Pointer.IsInContact boolean value to ensure you are selected the object when moving. It make your moving action looks better.
Second, Sorry that I don't know why in your machine the PointerMoved is not triggered when uses finger. Anyway it will better if you set the name of your handler function not same as event name.
If you can share more information, we can discuss.
I am making a Windows 8 application in visual studio 2012 c#.
I am having an image '1.png' and I want to rotate it at any angle as an animation along its center point.
But i want to do it with the help of c# code rather than XAML code.
Thank You in Advance.
In your XAML, have the following image:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Image Source="/Assets/Logo.png" Width="300" RenderTransformOrigin="0.5, 0.5">
<Image.RenderTransform>
<RotateTransform x:Name="rotateTransform"/>
</Image.RenderTransform>
</Image>
</Grid>
Then, in code, write the following when you want to animate (you create the Storyboard programmatically, then add to it a relevant Timeline. Note that you can also create the RotateTransform in code if you want.
async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
await Task.Delay(500);
Storyboard board = new Storyboard();
var timeline = new DoubleAnimationUsingKeyFrames();
Storyboard.SetTarget(timeline, rotateTransform);
Storyboard.SetTargetProperty(timeline, "Angle");
var frame = new EasingDoubleKeyFrame() { KeyTime = TimeSpan.FromSeconds(1), Value = 360, EasingFunction = new QuadraticEase() { EasingMode = EasingMode.EaseOut } };
timeline.KeyFrames.Add(frame);
board.Children.Add(timeline);
board.Begin();
}
This will rotate the object 360 degrees.
BTW: I am writing a set of posts that show an even better way of animating. It's not done yet, but it will give you a general idea on how to get a framework for certain types of animations..
First part of the series
Thanks Shahar! I took your example and made a custom control. It's actually an infinite spinning of one ring image.
Spinner.xaml:
<UserControl x:Class="MyControls.Spinner"
...
<Grid >
<Image Source="/Assets/Images/spinner.png" Width="194" RenderTransformOrigin="0.5, 0.5">
<Image.RenderTransform>
<RotateTransform x:Name="rotateTransform"/>
</Image.RenderTransform>
</Image>
</Grid>
</UserControl>
Spinner.cs:
namespace MyControls
{
public partial class Spinner: UserControl
{
public Spinner()
{
InitializeComponent();
this.Loaded += Spinner_Loaded;
}
private void PlayRotation()
{
Storyboard board = new Storyboard();
var timeline = new DoubleAnimationUsingKeyFrames();
Storyboard.SetTarget(timeline, rotateTransform);
Storyboard.SetTargetProperty(timeline, new PropertyPath("(Angle)"));
var frame = new EasingDoubleKeyFrame() { KeyTime = TimeSpan.FromSeconds(5), Value = 360, EasingFunction = new QuadraticEase() { EasingMode = EasingMode.EaseOut } };
timeline.KeyFrames.Add(frame);
board.Children.Add(timeline);
board.RepeatBehavior = RepeatBehavior.Forever;
board.Begin();
}
private async void Spinner_Loaded(object sender, RoutedEventArgs e)
{
PlayRotation();
}
}
}
Then when you want to use Spinner in another xaml, it's very simple:
Just add a line for it inside any Grid etc:
<include:Spinner/>
(of course you need to define include as something like:
xmlns:include="MyControls"
on top of your xaml)
Does anyone have any insight into how to implement a draggable pushpin on a map on a WP7 client running Mango? I have a pushpin bound to a geo-location on a map and I want the user to be able to drag it on a map and record its new location. I've seen some resources, but they're for non-WP7 Bing Maps control. Any help would be appreciated.
Thanks!
e.GetPosition(element) gives the position relative to the element passed on the parameter. Also, the point to convert using ViewportPointToLocation has to be relative to the position of the map. So, you have to do the following:
Pushpin myPin = sender as Pushpin;
Point p = e.GetPosition(**Map**);
g = Map.ViewportPointToLocation(p);
I know this is a late response but I was working on a similar project and using a similar approach, so I thought I'd share. The approach that I used was:
Create two global double variables to hold X,Y coord's:
double mapLocX;
double mapLocY;
Set these global doubles to the location of the point of your pushpin in your DragStarted event:
Point point = myMap.LocationToViewportPoint(myPin.Location);
mapLocX = point.X;
mapLocY = point.Y;
In your dragDelta event, change these variables as your would your pushpin:
mapLocX += e.HorizontalChange;
mapLocY += e.VerticalChange;
Now on DragCompleted create a new point that takes in our rendered global variables, and map them to a geocoordinate, and here's the kicker; Remove our old pin from the ObservableCollection (Mine is Locations) and add in a new pushpin at our new coordinate:
Point point = new Point(mapLocX, mapLocY);
GeoCoordinate geoCoord = new GeoCoordinate();
geoCoord = myMap.ViewportPointToLocation(point);
Locations.Remove(myPin.Location);
Locations.Add(geoCoord);
Hope this helps
If anyone is curious, this is the solution I came up with:
XAML:
<map:Map x:Name="Map" Height="400" HorizontalAlignment="Left" Margin="6,10,0,0" VerticalAlignment="Top" Width="444" ZoomLevel="19" >
<map:Map.Mode><map:AerialMode /></map:Map.Mode>
<map:Pushpin x:Name="Pin" Background="Green" IsHitTestVisible="True" IsEnabled="True">
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener DragDelta="Pushpin_OnDragDelta" DragStarted="Pushpin_OnDragStarted" DragCompleted="Pushpin_OnDragCompleted">
</toolkit:GestureListener>
</toolkit:GestureService.GestureListener>
<map:Pushpin.RenderTransform>
<TranslateTransform></TranslateTransform>
</map:Pushpin.RenderTransform>
</map:Pushpin>
</map:Map>
.cs:
private void Pushpin_OnDragDelta(object sender, DragDeltaGestureEventArgs e)
{
Pushpin myPin = sender as Pushpin;
TranslateTransform transform = myPin.RenderTransform as TranslateTransform;
transform.X += e.HorizontalChange;
transform.Y += e.VerticalChange;
}
private void Pushpin_OnDragStarted(object sender, DragStartedGestureEventArgs e)
{
Map.IsEnabled = false; // prevents the map from dragging w/ pushpin
}
private void Pushpin_OnDragCompleted(object sender, DragCompletedGestureEventArgs e)
{
Map.IsEnabled = true;
}
Does anyone have any ideas on how to extract the geocoordinates of the pushpin's new location?? I tried the code below in the event handler and it doesn't give correct coordinates:
Pushpin myPin = sender as Pushpin;
Point p = e.GetPosition(myPin);
g = Map.ViewportPointToLocation(p);
myPin.location gives the old coordinates
You want to have the origin of your UI element not your finger right? Try this:
Point pM = e.GetPosition(**Map**);
Point pE = e.GetPosition(**UIElement**);
Point origin = new Point(pM.X - pE.X, pM.Y - pE.Y);
GeoCoordinate g = Map.ViewportPointToLocation(origin);