Ajout du Drag de plusieurs image

master
cldupland 6 years ago
parent 6b249a7b42
commit e30805be57

@ -1,11 +1,11 @@
#pragma warning disable 1591
//------------------------------------------------------------------------------
// <auto-generated>
// Ce code a été généré par un outil.
// Version du runtime :4.0.30319.42000
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si
// le code est régénéré.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

@ -71,10 +71,12 @@
<None Include="Entitlements.plist" />
<None Include="Info.plist" />
<Compile Include="Properties\AssemblyInfo.cs" />
<None Include="Resources\Apple.png" />
<BundleResource Include="Resources\FontStyle\IndieFlower.ttf" />
<BundleResource Include="Resources\FontStyle\ENSOTYPE License &amp; FAQ - DO READ THIS!.pdf" />
<BundleResource Include="Resources\FontStyle\Ruhaniyat DEMO.otf" />
<BundleResource Include="Resources\Apple.png">
<LogicalName>TheGameExtreme.iOS.Resources.Apple.png</LogicalName>
</BundleResource>
</ItemGroup>
<ItemGroup>
<InterfaceDefinition Include="Resources\LaunchScreen.storyboard" />

@ -21,7 +21,6 @@
<Folder Include="model\gameActions\extreme\" />
<Folder Include="model\gameActions\classic\" />
<Folder Include="Media\" />
<Folder Include="view\Image\" />
</ItemGroup>
<ItemGroup>
<Compile Remove="model\effect\StopColm.cs" />

@ -7,15 +7,20 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
xmlns:tt="clr-namespace:TouchTracking.Forms;assembly=TouchTracking.Forms"
xmlns:local="clr-namespace:TheGameExtreme.view"
mc:Ignorable="d"
x:Class="TheGameExtreme.view.MainPage">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="10*"/>
<RowDefinition Height="90*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15*"/>
<ColumnDefinition Width="70*"/>
<ColumnDefinition Width="15*"/>
</Grid.ColumnDefinitions>
<Grid.Effects>
<tt:TouchEffect
@ -27,42 +32,127 @@
<Label
x:Name="pseudo"
Text="Pseudo"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Start"
TextColor="{DynamicResource WhiteColor}"
Margin="30"
FontSize="28" Grid.Row="0"/>
<ImageButton
Source="HomeIcon.png"
HorizontalOptions="Start"
VerticalOptions="Start"
WidthRequest="45"
Margin="20,20,0,0"
HeightRequest="45"
BackgroundColor="{DynamicResource BlackColor}"
<StackLayout
Grid.Row="0"
Grid.Column="1">
<Label
x:Name="pseudo"
Text="Pseudo"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
TextColor="{DynamicResource WhiteColor}"
FontSize="28"/>
<Picker Title="Touch Mode"
Grid.Row="0"
SelectedIndexChanged="OnTouchModePickerSelectedIndexChanged">
<Picker.ItemsSource>
<x:Array Type="{x:Type local:TouchManipulationMode}">
<x:Static Member="local:TouchManipulationMode.None" />
<x:Static Member="local:TouchManipulationMode.PanOnly" />
<x:Static Member="local:TouchManipulationMode.IsotropicScale" />
<x:Static Member="local:TouchManipulationMode.AnisotropicScale" />
<x:Static Member="local:TouchManipulationMode.ScaleRotate" />
<x:Static Member="local:TouchManipulationMode.ScaleDualRotate" />
</x:Array>
</Picker.ItemsSource>
<Picker.SelectedIndex>
4
</Picker.SelectedIndex>
</Picker>
</StackLayout>
<StackLayout
Grid.Row="0"
Grid.Column="0">
<ImageButton
Source="HomeIcon.png"
HorizontalOptions="Center"
VerticalOptions="Center"
WidthRequest="45"
HeightRequest="45"
BackgroundColor="{DynamicResource BlackColor}"
Clicked="PlayToHome"/>
</StackLayout>
<StackLayout
Grid.Row="0"
Clicked="PlayToHome"/>
<Button
Text="End Turn"
HorizontalOptions="End"
VerticalOptions="Start"
BackgroundColor="{DynamicResource SkyBlueColor}"
HeightRequest="35"
Margin="0,30,20,0"
Grid.Row="0"/>
Grid.Column="2">
<Button
Text="End Turn"
HorizontalOptions="End"
VerticalOptions="Start"
BackgroundColor="{DynamicResource SkyBlueColor}"
HeightRequest="35"/>
</StackLayout>
<!--<Grid
Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<StackLayout
Grid.Column="0">
<Image
x:Name="pile1"
Source="UsersExiticon.png"
HeightRequest="45"
WidthRequest="45"/>
</StackLayout>
<StackLayout
Grid.Column="1">
<Image
x:Name="pile2"
Source="UsersExiticon.png"
HeightRequest="45"
WidthRequest="45"/>
</StackLayout>
<StackLayout
Grid.Column="2">
<Image
x:Name="pioche"
Source="UsersExiticon.png"
HeightRequest="45"
WidthRequest="45"/>
</StackLayout>
<StackLayout
Grid.Column="3">
<Image
x:Name="pile4"
Source="UsersExiticon.png"
HeightRequest="45"
WidthRequest="45"/>
</StackLayout>
<StackLayout
Grid.Column="4">
<Image
x:Name="pile5"
Source="UsersExiticon.png"
HeightRequest="45"
WidthRequest="45"/>
</StackLayout>
</Grid>-->
<skia:SKCanvasView
x:Name="canvasView"
PaintSurface="OnCanvasViewPaintSurface"
Grid.Row="0"
Grid.RowSpan="3"/>
Grid.RowSpan="2"
Grid.Column="0"
Grid.ColumnSpan="3"/>

@ -19,17 +19,14 @@ namespace TheGameExtreme.view
{
private bool isFirst = true;
private Main viewmodel;
private List<CheckBox> stacks = new List<CheckBox>();
private List<SKRect> stacks = new List<SKRect>();
Button button = new Button();
List<string> playersNames;
SKBitmap bitmap;
SKBitmap bitmap2;
SKMatrix matrix = SKMatrix.MakeIdentity();
// Touch information
long touchId = -1;
SKPoint previousPoint;
TouchManipulationBitmap bitmap;
List<TouchManipulationBitmap> bitmapCollection = new List<TouchManipulationBitmap>();
Dictionary<long, TouchManipulationBitmap> bitmapDictionary = new Dictionary<long, TouchManipulationBitmap>();
public MainPage(List<string> playersNames)
@ -39,17 +36,29 @@ namespace TheGameExtreme.view
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, false);
string resourceID = "TheGameExtreme.Media.thegame.jpg";
string resourceID2 = "TheGameExtreme.Media.moon.jpg";
Assembly assembly = GetType().GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream(resourceID);
bitmap = SKBitmap.Decode(stream);
string[] resourceIDs = assembly.GetManifestResourceNames();
Stream stream2 = assembly.GetManifestResourceStream(resourceID2);
bitmap2 = SKBitmap.Decode(stream2);
SKPoint position = new SKPoint();
foreach (string resourceID in resourceIDs)
{
if (resourceID.EndsWith(".png") ||
resourceID.EndsWith(".jpg"))
{
using (Stream stream = assembly.GetManifestResourceStream(resourceID))
{
SKBitmap bitmap = SKBitmap.Decode(stream);
bitmapCollection.Add(new TouchManipulationBitmap(bitmap)
{
Matrix = SKMatrix.MakeTranslation(position.X, position.Y),
});
position.X += 100;
position.Y += 100;
}
}
}
//stacks.Add(checkbox0);
@ -75,60 +84,76 @@ namespace TheGameExtreme.view
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args) // Faire plusieurs canvas
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
SKCanvas canvas = args.Surface.Canvas;
canvas.Clear();
// Display the bitmap
canvas.SetMatrix(matrix);
canvas.DrawBitmap(bitmap, new SKPoint());
//canvas.DrawBitmap(bitmap2, new SKPoint(500, 500));
foreach (TouchManipulationBitmap bitmap in bitmapCollection)
{
bitmap.Paint(canvas);
}
}
void OnTouchEffectAction(object sender, TouchActionEventArgs args)
{
// Convert Xamarin.Forms point to pixels
TouchTrackingPoint pt = args.Location;
SKPoint point =
new SKPoint((float)(canvasView.CanvasSize.Width * pt.X / canvasView.Width),
(float)(canvasView.CanvasSize.Height * pt.Y / canvasView.Height));
{
// Convert Xamarin.Forms point to pixels
TouchTrackingPoint pt = args.Location;
SKPoint point =
new SKPoint((float)(canvasView.CanvasSize.Width * pt.X / canvasView.Width),
(float)(canvasView.CanvasSize.Height * pt.Y / canvasView.Height));
switch (args.Type)
{
case TouchActionType.Pressed:
// Find transformed bitmap rectangle
SKRect rect = new SKRect(0, 0, bitmap.Width, bitmap.Height);
rect = matrix.MapRect(rect);
switch (args.Type)
{
case TouchActionType.Pressed:
for (int i = bitmapCollection.Count - 1; i >= 0; i--)
{
TouchManipulationBitmap bitmap = bitmapCollection[i];
// Determine if the touch was within that rectangle
if (rect.Contains(point))
if (bitmap.HitTest(point))
{
touchId = args.Id;
previousPoint = point;
}
break;
// Move bitmap to end of collection
bitmapCollection.Remove(bitmap);
bitmapCollection.Add(bitmap);
case TouchActionType.Moved:
if (touchId == args.Id)
{
// Adjust the matrix for the new position
matrix.TransX += point.X - previousPoint.X;
matrix.TransY += point.Y - previousPoint.Y;
previousPoint = point;
// Do the touch processing
bitmapDictionary.Add(args.Id, bitmap);
bitmap.ProcessTouchEvent(args.Id, args.Type, point);
canvasView.InvalidateSurface();
break;
}
break;
}
break;
case TouchActionType.Released:
case TouchActionType.Cancelled:
touchId = -1;
break;
}
case TouchActionType.Moved:
if (bitmapDictionary.ContainsKey(args.Id))
{
TouchManipulationBitmap bitmap = bitmapDictionary[args.Id];
bitmap.ProcessTouchEvent(args.Id, args.Type, point);
canvasView.InvalidateSurface();
}
break;
case TouchActionType.Released:
case TouchActionType.Cancelled:
if (bitmapDictionary.ContainsKey(args.Id))
{
TouchManipulationBitmap bitmap = bitmapDictionary[args.Id];
bitmap.ProcessTouchEvent(args.Id, args.Type, point);
bitmapDictionary.Remove(args.Id);
canvasView.InvalidateSurface();
}
break;
}
}
void OnTouchModePickerSelectedIndexChanged(object sender, EventArgs args)
{
if (bitmap != null)
{
Picker picker = (Picker)sender;
bitmap.TouchManager.Mode = (TouchManipulationMode)picker.SelectedItem;
}
}

@ -0,0 +1,103 @@
using System;
using SkiaSharp;
namespace TheGameExtreme.view
{
public class MatrixDisplay
{
public SKPaint MatrixPaint { set; get; } = new SKPaint
{
Color = SKColors.Black,
TextSize = 48,
StrokeWidth = 2
};
public string PerspectiveFormat { set; get; } = "F0";
public SKSize Measure(SKMatrix matrix)
{
return MeasureAndPaint(null, matrix, new SKPoint(), false);
}
public void Paint(SKCanvas canvas, SKMatrix matrix, SKPoint location)
{
MeasureAndPaint(canvas, matrix, location, true);
}
SKSize MeasureAndPaint(SKCanvas canvas, SKMatrix matrix, SKPoint location, bool doPaint)
{
float[] values = matrix.Values;
string[] texts = new string[9];
SKRect[] bounds = new SKRect[9];
float[] widths = new float[3];
for (int i = 0; i < 9; i++)
{
int row = i % 3;
int col = i / 3;
// Format string differently based on row
texts[i] = values[i].ToString(row == 2 ? "F0" : (col == 2 ? PerspectiveFormat : "F2"));
// Measure string with a '-' even if one is not present
bool isNegative = texts[i][0] == '-';
string text = (isNegative ? "" : "-") + texts[i];
MatrixPaint.MeasureText(text, ref bounds[i]);
// Get maximum width for each column
widths[col] = Math.Max(widths[col], bounds[i].Width);
// Measure the text again without the '-' in front
MatrixPaint.MeasureText(texts[i], ref bounds[i]);
}
// Some formatting constants
float horzGap = MatrixPaint.TextSize;
float horzMarg = MatrixPaint.TextSize;
float vertMarg = MatrixPaint.FontSpacing / 4;
// Calculate the total width and height of the matrix display
float totalWidth = widths[0] + widths[1] + widths[2] + 2 * horzGap + 2 * horzMarg;
float totalHeight = 3 * MatrixPaint.FontSpacing + 2 * vertMarg;
if (doPaint)
{
SKPaintStyle saveStyle = MatrixPaint.Style;
for (int i = 0; i < 9; i++)
{
int row = i % 3;
int col = i / 3;
// Find x, y of upper-left corner of text
float x = location.X + horzMarg;
for (int c = 0; c < col; c++)
{
x += widths[c] + horzGap;
}
float y = location.Y + vertMarg + row * MatrixPaint.FontSpacing;
// Adjust for right-justified text
x += widths[col] - bounds[i].Width;
y += (MatrixPaint.FontSpacing - bounds[i].Height) / 2 - bounds[i].Top;
// Draw the text
MatrixPaint.Style = SKPaintStyle.Fill;
canvas.DrawText(texts[i], x, y, MatrixPaint);
}
// Display vertical lines at the sides of the matrix
MatrixPaint.Style = SKPaintStyle.Stroke;
canvas.DrawLine(location.X + horzMarg / 2, location.Y + vertMarg,
location.X + horzMarg / 2, location.Y + totalHeight - vertMarg, MatrixPaint);
canvas.DrawLine(location.X + totalWidth - horzMarg / 2, location.Y + vertMarg,
location.X + totalWidth - horzMarg / 2, location.Y + totalHeight - vertMarg, MatrixPaint);
MatrixPaint.Style = saveStyle;
}
return new SKSize(totalWidth, totalHeight);
}
}
}

@ -6,84 +6,111 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TheGameExtreme.view.Settings">
<Grid>
<Grid
Margin="20,20,20,20">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="15*"/>
<RowDefinition Height="28*"/>
<RowDefinition Height="28*"/>
<RowDefinition Height="28*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ImageButton Source="ArrowSettingsBack.png"
Grid.Row="0" Grid.Column="0"
<StackLayout
Grid.Row="0">
<ImageButton Source="ArrowSettingsBack.png"
VerticalOptions="Start"
HorizontalOptions="StartAndExpand"
HeightRequest="40"
WidthRequest="50"
Clicked="SettingToHomePage"
BackgroundColor="{DynamicResource BlackColor}"
Margin="10,10,0,0"/>
<Label HorizontalTextAlignment="Start"
Text ="Langage" Grid.Column="0"
Grid.Row="0" FontSize="25"
TextColor="{DynamicResource WhiteColor}"
Margin="40,58,0,0"/>
<Label Text="English"
Grid.Column="1" Grid.Row="0"
FontSize="25"
TextColor="{DynamicResource WhiteColor}"
Margin="80,58,0,0"/>
BackgroundColor="{DynamicResource BlackColor}"
Margin="10,10,0,0"/>
</StackLayout>
<CheckBox IsChecked="False"
Grid.Column="1" Grid.Row="0"
x:Name="CBBr"
CheckedChanged="CBBr_CheckedChanged"
Color="{DynamicResource SkyBlueColor}"
Margin="40,63,0,0"/>
<Grid
Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="33*"/>
<ColumnDefinition Width="33*"/>
<ColumnDefinition Width="33*"/>
</Grid.ColumnDefinitions>
<Label
Grid.Column="0"
HorizontalTextAlignment="Start"
Text ="Langage"
FontSize="25"
TextColor="{DynamicResource WhiteColor}"
VerticalTextAlignment="Center"/>
<StackLayout
Grid.Column="1"
Orientation="Horizontal">
<Label
Text="English"
FontSize="25"
TextColor="{DynamicResource WhiteColor}"
VerticalTextAlignment="Center"/>
<Label Text="Français"
Grid.Column="2" Grid.Row="0"
FontSize="25"
TextColor="{DynamicResource WhiteColor}"
Margin="80,58,0,0"/>
<CheckBox
IsChecked="False"
x:Name="CBBr"
CheckedChanged="CBBr_CheckedChanged"
Color="{DynamicResource SkyBlueColor}"
/>
</StackLayout>
<StackLayout
Grid.Column="2"
Orientation="Horizontal">
<Label
Text="Français"
FontSize="25"
TextColor="{DynamicResource WhiteColor}"
VerticalTextAlignment="Center"/>
<CheckBox IsChecked="True"
Grid.Column="2" Grid.Row="0"
x:Name="CBFr"
CheckedChanged="CBFr_CheckedChanged"
Color="{DynamicResource SkyBlueColor}"
Margin="40,63,0,0"/>
<CheckBox
IsChecked="True"
x:Name="CBFr"
CheckedChanged="CBFr_CheckedChanged"/>
</StackLayout>
</Grid>
<StackLayout
Grid.Row="2"
Orientation="Horizontal">
<Label HorizontalTextAlignment="Start"
Text="Mode Extreme" Grid.Column="0"
Grid.Row="2" FontSize="25"
TextColor="{DynamicResource WhiteColor}"
Margin="40,25,0,0"/>
<Label
HorizontalTextAlignment="Start"
Text="Mode Extreme"
FontSize="25"
TextColor="{DynamicResource WhiteColor}"/>
<Switch
Grid.Column="1" Grid.Row="2"
<Switch
OnColor="{DynamicResource SkyBlueColor}"
ThumbColor="WhiteSmoke"/>
<Label Text="Thème Clair"
Grid.Column="0" Grid.Row="3"
FontSize="25"
TextColor="{DynamicResource WhiteColor}"
Margin="40,25,0,0"/>
</StackLayout>
<StackLayout
Grid.Row="3"
Orientation="Horizontal">
<Label
Text="Thème Clair"
FontSize="25"
TextColor="{DynamicResource WhiteColor}"/>
<Switch
Grid.Column="1" Grid.Row="3"
Toggled="Switch_Toggled_Theme" x:Name="swTheme"
OnColor="{DynamicResource SkyBlueColor}" ThumbColor="WhiteSmoke"/>
<Switch
Toggled="Switch_Toggled_Theme"
x:Name="swTheme"
OnColor="{DynamicResource SkyBlueColor}"
ThumbColor="WhiteSmoke"/>
</StackLayout>
</Grid>
</ContentPage>

@ -0,0 +1,113 @@
using System.Collections.Generic;
using SkiaSharp;
using TouchTracking;
namespace TheGameExtreme.view
{
public class TouchManipulationBitmap
{
SKBitmap bitmap;
Dictionary<long, TouchManipulationInfo> touchDictionary = new Dictionary<long, TouchManipulationInfo>();
public TouchManipulationBitmap(SKBitmap bitmap)
{
this.bitmap = bitmap;
Matrix = SKMatrix.MakeIdentity();
TouchManager = new TouchManipulationManager
{
Mode = TouchManipulationMode.ScaleRotate
};
}
public TouchManipulationManager TouchManager { set; get; }
public SKMatrix Matrix { set; get; }
public void Paint(SKCanvas canvas)
{
canvas.Save();
SKMatrix matrix = Matrix;
canvas.Concat(ref matrix);
canvas.DrawBitmap(bitmap, 0, 0);
canvas.Restore();
}
public bool HitTest(SKPoint location)
{
// Invert the matrix
SKMatrix inverseMatrix;
if (Matrix.TryInvert(out inverseMatrix))
{
// Transform the point using the inverted matrix
SKPoint transformedPoint = inverseMatrix.MapPoint(location);
// Check if it's in the untransformed bitmap rectangle
SKRect rect = new SKRect(0, 0, bitmap.Width, bitmap.Height);
return rect.Contains(transformedPoint);
}
return false;
}
public void ProcessTouchEvent(long id, TouchActionType type, SKPoint location)
{
switch (type)
{
case TouchActionType.Pressed:
touchDictionary.Add(id, new TouchManipulationInfo
{
PreviousPoint = location,
NewPoint = location
});
break;
case TouchActionType.Moved:
TouchManipulationInfo info = touchDictionary[id];
info.NewPoint = location;
Manipulate();
info.PreviousPoint = info.NewPoint;
break;
case TouchActionType.Released:
touchDictionary[id].NewPoint = location;
Manipulate();
touchDictionary.Remove(id);
break;
case TouchActionType.Cancelled:
touchDictionary.Remove(id);
break;
}
}
void Manipulate()
{
TouchManipulationInfo[] infos = new TouchManipulationInfo[touchDictionary.Count];
touchDictionary.Values.CopyTo(infos, 0);
SKMatrix touchMatrix = SKMatrix.MakeIdentity();
if (infos.Length == 1)
{
SKPoint prevPoint = infos[0].PreviousPoint;
SKPoint newPoint = infos[0].NewPoint;
SKPoint pivotPoint = Matrix.MapPoint(bitmap.Width / 2, bitmap.Height / 2);
touchMatrix = TouchManager.OneFingerManipulate(prevPoint, newPoint, pivotPoint);
}
else if (infos.Length >= 2)
{
int pivotIndex = infos[0].NewPoint == infos[0].PreviousPoint ? 0 : 1;
SKPoint pivotPoint = infos[pivotIndex].NewPoint;
SKPoint newPoint = infos[1 - pivotIndex].NewPoint;
SKPoint prevPoint = infos[1 - pivotIndex].PreviousPoint;
touchMatrix = TouchManager.TwoFingerManipulate(prevPoint, newPoint, pivotPoint);
}
SKMatrix matrix = Matrix;
SKMatrix.PostConcat(ref matrix, touchMatrix);
Matrix = matrix;
}
}
}

@ -0,0 +1,12 @@
using System;
using SkiaSharp;
namespace TheGameExtreme.view
{
public class TouchManipulationInfo
{
public SKPoint PreviousPoint { set; get; }
public SKPoint NewPoint { set; get; }
}
}

@ -0,0 +1,107 @@
using System;
using SkiaSharp;
namespace TheGameExtreme.view
{
public class TouchManipulationManager
{
public TouchManipulationMode Mode { set; get; }
float Magnitude(SKPoint point)
{
return (float)Math.Sqrt(Math.Pow(point.X, 2) + Math.Pow(point.Y, 2));
}
public SKMatrix OneFingerManipulate(SKPoint prevPoint, SKPoint newPoint, SKPoint pivotPoint)
{
if (Mode == TouchManipulationMode.None)
{
return SKMatrix.MakeIdentity();
}
SKMatrix touchMatrix = SKMatrix.MakeIdentity();
SKPoint delta = newPoint - prevPoint;
if (Mode == TouchManipulationMode.ScaleDualRotate) // One-finger rotation
{
SKPoint oldVector = prevPoint - pivotPoint;
SKPoint newVector = newPoint - pivotPoint;
// Avoid rotation if fingers are too close to center
if (Magnitude(newVector) > 25 && Magnitude(oldVector) > 25)
{
float prevAngle = (float)Math.Atan2(oldVector.Y, oldVector.X);
float newAngle = (float)Math.Atan2(newVector.Y, newVector.X);
// Calculate rotation matrix
float angle = newAngle - prevAngle;
touchMatrix = SKMatrix.MakeRotation(angle, pivotPoint.X, pivotPoint.Y);
// Effectively rotate the old vector
float magnitudeRatio = Magnitude(oldVector) / Magnitude(newVector);
oldVector.X = magnitudeRatio * newVector.X;
oldVector.Y = magnitudeRatio * newVector.Y;
// Recalculate delta
delta = newVector - oldVector;
}
}
// Multiply the rotation matrix by a translation matrix
SKMatrix.PostConcat(ref touchMatrix, SKMatrix.MakeTranslation(delta.X, delta.Y));
return touchMatrix;
}
public SKMatrix TwoFingerManipulate(SKPoint prevPoint, SKPoint newPoint, SKPoint pivotPoint)
{
SKMatrix touchMatrix = SKMatrix.MakeIdentity();
SKPoint oldVector = prevPoint - pivotPoint;
SKPoint newVector = newPoint - pivotPoint;
if (Mode == TouchManipulationMode.ScaleRotate ||
Mode == TouchManipulationMode.ScaleDualRotate)
{
// Find angles from pivot point to touch points
float oldAngle = (float)Math.Atan2(oldVector.Y, oldVector.X);
float newAngle = (float)Math.Atan2(newVector.Y, newVector.X);
// Calculate rotation matrix
float angle = newAngle - oldAngle;
touchMatrix = SKMatrix.MakeRotation(angle, pivotPoint.X, pivotPoint.Y);
// Effectively rotate the old vector
float magnitudeRatio = Magnitude(oldVector) / Magnitude(newVector);
oldVector.X = magnitudeRatio * newVector.X;
oldVector.Y = magnitudeRatio * newVector.Y;
}
float scaleX = 1;
float scaleY = 1;
if (Mode == TouchManipulationMode.AnisotropicScale)
{
scaleX = newVector.X / oldVector.X;
scaleY = newVector.Y / oldVector.Y;
}
else if (Mode == TouchManipulationMode.IsotropicScale ||
Mode == TouchManipulationMode.ScaleRotate ||
Mode == TouchManipulationMode.ScaleDualRotate)
{
scaleX = scaleY = Magnitude(newVector) / Magnitude(oldVector);
}
if (!float.IsNaN(scaleX) && !float.IsInfinity(scaleX) &&
!float.IsNaN(scaleY) && !float.IsInfinity(scaleY))
{
SKMatrix.PostConcat(ref touchMatrix,
SKMatrix.MakeScale(scaleX, scaleY, pivotPoint.X, pivotPoint.Y));
}
return touchMatrix;
}
}
}

@ -0,0 +1,13 @@
using System;
namespace TheGameExtreme.view
{
public enum TouchManipulationMode
{
None,
PanOnly,
IsotropicScale, // includes panning
AnisotropicScale, // includes panning
ScaleRotate, // implies isotropic scaling
ScaleDualRotate // adds one-finger rotation
}
}
Loading…
Cancel
Save