遊戲內容非常單純,移動3 x 3或 N x N的圖片區塊,恢復為完整的圖即成功。
本篇內容,先建立Puzzles的骨架及基本動作,其中我們一共會建立兩個 .xaml檔及一個.cs檔,另外需匯入一張圖片,檔案名稱如下:
a. MainPage.xaml
b. imageBox.xaml
c. myRecorder.cs
d. 圖片:imgs/Orz.png
1.建立一個新的Silverlight Applciation專案,在這裡我將專案名稱命為
<UserControl x:Class="ImageClip_Puzzles.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480" Loaded="loadImg">
<Grid Background="Gray" Width="500" Height="500"
VerticalAlignment="Center" HorizontalAlignment="Center" >
<Grid x:Name="PuzzlesTop" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="*"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Grid Grid.Column="1" Grid.Row="1">
<Rectangle Fill="Black"/>
</Grid>
</Grid>
<TextBlock Text="sys" x:Name="sysMsg" FontSize="12"
VerticalAlignment="Top" HorizontalAlignment="Center">
<TextBlock.RenderTransform>
<TranslateTransform X="0" Y="-20"/>
</TextBlock.RenderTransform>
</TextBlock>
</Grid>
</UserControl>
2.接著是
<UserControl x:Class="ImageClip_Puzzles.imageBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="Auto" Height="Auto" x:Name="imageTop" >
<Canvas Height="600" Width="600" x:Name="imageCanvas">
<Canvas.Resources>
<Storyboard x:Name="moveImage_Direct_Up" SpeedRatio="5">
<DoubleAnimation x:Name="UpAnima"
Storyboard.TargetName="imageGrid"
Storyboard.TargetProperty="(Canvas.Top)"
From="0" To="0" Duration="0:0:1" AutoReverse="False"/>
<DoubleAnimation x:Name="borderAnima_Up"
Storyboard.TargetName="imageBorder"
Storyboard.TargetProperty="(Border.RenderTransform).Y"
From="0" To="0" Duration="0:0:1" AutoReverse="False"/>
</Storyboard>
<Storyboard x:Name="moveImage_Direct_Left" SpeedRatio="5">
<DoubleAnimation x:Name="LeftAnima"
Storyboard.TargetName="imageGrid"
Storyboard.TargetProperty="(Canvas.Left)"
From="0" To="0" Duration="0:0:1" AutoReverse="False"/>
<DoubleAnimation x:Name="borderAnima_Left"
Storyboard.TargetName="imageBorder"
Storyboard.TargetProperty="(Border.RenderTransform).X"
From="0" To="0" Duration="0:0:1" AutoReverse="False"/>
</Storyboard>
</Canvas.Resources>
<Grid Canvas.Top="0" Canvas.Left="0"
Width="480" Height="480" x:Name="imageGrid" >
<Image Source="imgs/Orz.png" Stretch="Fill" x:Name="imageContent">
<Image.Clip>
<RectangleGeometry Rect="0,0,160,160 " >
<RectangleGeometry.Transform>
<TranslateTransform X="0" Y="0" x:Name="ImageAreaTransform"/>
</RectangleGeometry.Transform>
</RectangleGeometry>
</Image.Clip>
</Image>
</Grid>
<Border BorderBrush="#FF666666" BorderThickness="5" x:Name="imageBorder">
<Border.RenderTransform>
<TranslateTransform X="0" Y="0" x:Name="boardPosition"/>
</Border.RenderTransform>
<Rectangle x:Name="imageColor"
Width="155" Height="155" Fill="Red" Opacity="0.01"/>
</Border>
<Grid Visibility="Visible">
<Grid.RenderTransform>
<TranslateTransform X="5" Y="10" x:Name="msgPos"/>
</Grid.RenderTransform>
<Grid.RowDefinitions>
<RowDefinition Height="14"/>
<RowDefinition Height="14"/>
<RowDefinition Height="14"/>
<RowDefinition Height="14"/>
<RowDefinition Height="14"/>
</Grid.RowDefinitions>
<TextBlock x:Name="imgSysMsg1" Text="" FontSize="12" Grid.Row="0"/>
<TextBlock x:Name="imgSysMsg2" Text="" FontSize="12" Grid.Row="1"/>
<TextBlock x:Name="imgSysMsg3" Text="" FontSize="12" Grid.Row="2"/>
<TextBlock x:Name="imgSysMsg4" Text="" FontSize="12" Grid.Row="3"/>
<TextBlock x:Name="imgSysMsg5" Text="" FontSize="12" Grid.Row="4"/>
</Grid>
</Canvas>
</UserControl>
3.別忘了
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace ImageClip_Puzzles
{
public partial class MainPage : UserControl
{
private void SysMsg(string msg)
{
sysMsg.Text = msg;
}
int gridNum = 3;
int imageSize = 160;
Point[,] imagePos;
imageBox[] IBArray;
public MainPage()
{
InitializeComponent();
}
private void loadImg(object sender, RoutedEventArgs e)
{
imagePos = new Point[gridNum, gridNum];
IBArray = new imageBox[gridNum * gridNum];
for (int i = 0; i < gridNum; i++)
{
for (int j = 0; j < gridNum; j++)
{
imageBox ib = new imageBox();
int indexOfAll = i * gridNum + j;
IBArray[indexOfAll] = ib;
ib.MouseLeftButtonDown += onImageClick;
ib.moveImage_Direct_Up.Completed += moveIsFinish;
ib.moveImage_Direct_Left.Completed += moveIsFinish;
ib.setInfo(indexOfAll,i, j, gridNum, imageSize);
PuzzlesTop.Children.Add(ib);
ib.setGridPosition(1, 1);
imagePos[i, j] =
new Point(j * imageSize, i * imageSize);
}
}
BArray[0].setImageColor(0xFF, 0x00, 0x00);
}
bool imgIsMoving = false;
private void onImageClick(object sender, MouseButtonEventArgs e)
{
SysMsg("imgIsMoving : " + imgIsMoving.ToString());
if (imgIsMoving) return;
imgIsMoving = true;
imageBox uc = sender as imageBox;
string dir = getPic1(IBArray[uc.indexOfAllIBArray].rowIndex,
IBArray[uc.indexOfAllIBArray].colIndex);
uc.moveImageTo(dir);
switch (dir)
{
case "up":
IBArray[0].moveImageTo("down");
break;
case "down":
IBArray[0].moveImageTo("up");
break;
case "left":
IBArray[0].moveImageTo("right");
break;
case "right":
IBArray[0].moveImageTo("left");
break;
default:
imgIsMoving = false;
break;
}
}
private void moveIsFinish(object sender, EventArgs e)
{
Storyboard sb = (Storyboard)sender;
imageBox tmpImageBox =
(imageBox) sb.GetValue(myRecorder.record_ImageBox);
if (tmpImageBox.indexOfAllIBArray == 0) return;
int tmpRIndex = tmpImageBox.rowIndex;
int tmpCIndex = tmpImageBox.colIndex;
tmpImageBox.resetCurrentPosition(IBArray[0].rowIndex,
IBArray[0].colIndex);
IBArray[0].resetCurrentPosition(tmpRIndex, tmpCIndex);
imgIsMoving = false;
}
private string getPic1(int r, int c)
{
if (((r - 1) == IBArray[0].rowIndex)
&& (c == IBArray[0].colIndex))
// at down of Pic0 - - -> (r-1,c) then the imagemove 'up'
{
return "up";
}
else if (((r + 1) == IBArray[0].rowIndex)
&& (c == IBArray[0].colIndex))
//at top of Pic0 - - -> (r+1,c) then the image move 'down'
{
return "down";
}
else if ((r == IBArray[0].rowIndex)
&& ((c-1) == IBArray[0].colIndex))
//at right of Pic0 - - -> (r,c-1) then the image move 'left'
{
return "left";
}
else if ((r == IBArray[0].rowIndex)
&& ((c + 1) == IBArray[0].colIndex))
{
return "right";
}
else
{
return "stay";
}
}
private void showImageBoxMsg(imageBox ib)
{
ib.SysMsg("ib name : " + ib.Name,
", indexOfArrlyIBArray : " + ib.indexOfAllIBArray.ToString(),
", IBArray postion on " + ib.indexOfAllIBArray.ToString(),
", rowIndex : " + IBArray[ib.indexOfAllIBArray].rowIndex.ToString(),
", cowIndex : " + IBArray[ib.indexOfAllIBArray].colIndex.ToString());
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace ImageClip_Puzzles
{
public partial class imageBox : UserControl
{
int separaNum = 3;
int imgSize = 160;
public int rowIndex = 0;
public int colIndex = 0;
public int orgiRowIndex = 0;
public int orgiColIndex = 0;
public int indexOfAllIBArray = 99;
Point currentBorderPosition = new Point();
public imageBox()
{
InitializeComponent();
}
public void setInfo(int indexOfArray,int rIndex,
int cIndex,int separateNum,int imageSize)
{
indexOfAllIBArray = indexOfArray;
separaNum = separateNum;
imgSize = imageSize;
imageUV(rIndex, cIndex);
this.Name =
"R(" + rIndex.ToString() + ")C(" + cIndex.ToString() + ")";
rowIndex = rIndex;
colIndex = cIndex;
orgiRowIndex = rIndex;
orgiColIndex = cIndex;
animaRecordInfo(indexOfArray);
}
private void animaRecordInfo(int index)//, string name)
{
moveImage_Direct_Up.SetValue(myRecorder.record_ImageBox, this);
moveImage_Direct_Left.SetValue(myRecorder.record_ImageBox, this);
}
private void imageUV(int indexU,int indexV)
{
ImageAreaTransform.X = indexV * 160;
ImageAreaTransform.Y = indexU * 160;
this.boardPosition.X = ImageAreaTransform.X;
this.boardPosition.Y = ImageAreaTransform.Y;
currentBorderPosition =
new Point(ImageAreaTransform.X,ImageAreaTransform.Y);
msgPos.X = ImageAreaTransform.X;
msgPos.Y = ImageAreaTransform.Y;
}
public void setGridPosition(int rowIndex, int colIndex)
{
this.SetValue(Grid.RowProperty, rowIndex);
this.SetValue(Grid.ColumnProperty, colIndex);
}
public void setImageColor(byte r, byte g, byte b)
{
Color c = Color.FromArgb(255, r, g, b);
imageColor.Fill = new SolidColorBrush(c);
imageColor.Opacity = 0.7;
}
public void SysMsg(string msg)
{
imgSysMsg1.Text = msg;
}
public void SysMsg(string msg1, string msg2)
{
imgSysMsg1.Text = msg1;
imgSysMsg2.Text = msg2;
}
public void SysMsg(string msg1, string msg2, string msg3)
{
imgSysMsg1.Text = msg1;
imgSysMsg2.Text = msg2;
imgSysMsg3.Text = msg3;
}
public void SysMsg(string msg1, string msg2,
string msg3, string msg4)
{
imgSysMsg1.Text = msg1;
imgSysMsg2.Text = msg2;
imgSysMsg3.Text = msg3;
imgSysMsg4.Text = msg4;
}
public void SysMsg(string msg1, string msg2,
string msg3, string msg4, string msg5)
{
imgSysMsg1.Text = msg1;
imgSysMsg2.Text = msg2;
imgSysMsg3.Text = msg3;
imgSysMsg4.Text = msg4;
imgSysMsg5.Text = msg5;
}
public void moveImageTo(string dir)
{
SysMsg("");
switch (dir)
{
case "up":
this.UpAnima.From =
Convert.ToDouble( imageGrid.GetValue(Canvas.TopProperty));
this.UpAnima.To = this.UpAnima.From - imgSize;
this.borderAnima_Up.From = this.boardPosition.Y;
this.currentBorderPosition.Y -= imgSize;
this.borderAnima_Up.To = this.currentBorderPosition.Y;
this.moveImage_Direct_Up.Begin();
break;
case "down":
this.UpAnima.From =
Convert.ToDouble(imageGrid.GetValue(Canvas.TopProperty));
this.UpAnima.To = this.UpAnima.From + imgSize;
this.borderAnima_Up.From = this.currentBorderPosition.Y;
this.currentBorderPosition.Y += imgSize;
this.borderAnima_Up.To = this.currentBorderPosition.Y;
this.moveImage_Direct_Up.Begin();
break;
case "left":
this.LeftAnima.From =
Convert.ToDouble(imageGrid.GetValue(Canvas.LeftProperty));
this.LeftAnima.To = this.LeftAnima.From - imgSize;
this.borderAnima_Left.From = this.currentBorderPosition.X;
this.currentBorderPosition.X -= imgSize;
this.borderAnima_Left.To = this.currentBorderPosition.X;
this.moveImage_Direct_Left.Begin();
break;
case "right":
this.LeftAnima.From = Convert.ToDouble(imageGrid.GetValue(Canvas.LeftProperty));
this.LeftAnima.To = this.LeftAnima.From + 160;
this.borderAnima_Left.From =
this.currentBorderPosition.X;
this.currentBorderPosition.X += imgSize;
this.borderAnima_Left.To =
this.currentBorderPosition.X;
this.moveImage_Direct_Left.Begin();
break;
default:
SysMsg("default in dir");
break;
}
msgPos.X = this.currentBorderPosition.X + 5;
msgPos.Y = this.currentBorderPosition.Y + 10;
}
public void resetCurrentPosition(int r,int c)
{
this.rowIndex = r;
this.colIndex = c;
showInfo();
}
public void showInfo()
{
SysMsg("boardPosition(X,Y): (" + this.boardPosition.X.ToString() +
","+ this.boardPosition.Y.ToString() +")",
"TopLeft: (" + imageGrid.GetValue(Canvas.TopProperty).ToString() +
"," + imageGrid.GetValue(Canvas.LeftProperty).ToString() ,
"RowIndex : " + this.rowIndex.ToString(),
"ColIndex : " + this.colIndex.ToString(),
"name : "+this.Name);
}
}
}
4.最後是
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace ImageClip_Puzzles
{
public class myRecorder
{
public static readonly DependencyProperty record_ImageBox =
DependencyProperty.RegisterAttached(
"recordImageBox",
typeof(imageBox),
typeof(myRecorder),
null);
public static void recordImageBox(DependencyObject obj,
imageBox ib)
{
obj.SetValue(record_ImageBox, ib);
}
public static imageBox readImageBox(DependencyObject obj)
{
return (imageBox)obj.GetValue(record_ImageBox);
}
}
}
先前已有介紹如何在Silverlight元件裡額外加入一個屬性,「myRecorder.cs」的內容即新增的屬性的Class。
就本篇內容來說,遊戲時「圖片區塊的移動」的動作已寫好。此外為了除蟲方便,程式中加入了「SysMsg」Function,執行時我們能夠簡單看到目前圖片位置的屬性值。
執行結果
沒有留言:
張貼留言