ورود

View Full Version : سوال: حرکت آبجکت با سرعت ثابت!



Saman_12
شنبه 06 اسفند 1390, 18:07 عصر
سلام.
فرض کنید یه آبجکت داریم میخوایم واسش یه ِStorybord درست کنیم که آبجکت رو حرکت بده!
تا اینجاش مشکلی نیست مشکل اینکه چجوری آبجکت از جای که هست به میزانی که قبلا واسش گذاشتیم حرکت رو ادامکه بده مثلا کاربر کلید w را میفشارد میخوام تا وقتی که ایونت کی آپ اجرا نشده آبجکت به رفتنش ادامه بده بعد هروقت اجرا شد آبجکت سر جاش وایسه!:متعجب:

>> :متفکر:<<
خوب توی منطق برنامه میشه پیادش کرد؟؟

یه مشکل دیگه اینه که وقتی کلیدی رو میفشارند اصلا آبجکت(دایره) ایونت کی آپ یا ... ش اجرا نمیشه!!!(ببخشید من تازه اومد از VB.NET به Wpf اینجا یکم چیزا فرق میکنه واس این کار تو وی بی کافیه کی پریویو رو فعال کنی!)

مهدی فرزاد
دوشنبه 08 اسفند 1390, 11:29 صبح
سلام
من یک چیزی برای شما اماده کردم شاید دقیقا اون چیزی که میخواید نباشه اما میتونه برای رسیدن به هدف بهتون کمک کنه
من کل انیمیشن رو با کد C#‎‎‎ نوشتم (اگه vb میخواید خودتون تبدیل کنید)
با فشار دادن کلید W شروع به حرکت میکنه و با برداشتن دست استاپ میشه

public partial class MainWindow : Window
{


Storyboard st;
bool start;
public MainWindow()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
this.KeyDown += new KeyEventHandler(MainWindow_KeyDown);
this.KeyUp += new KeyEventHandler(MainWindow_KeyUp);
}



void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
this.WindowState = System.Windows.WindowState.Maximized;
this.rg1.Margin = new Thickness(0, 0, this.Width-100, 0);

ThicknessAnimation tk = new ThicknessAnimation();
tk.From = this.rg1.Margin;
tk.To = new Thickness(0,0,-this.ActualWidth +100,0);
tk.Duration = new Duration(new TimeSpan(0, 0, 0, 4));
tk.RepeatBehavior = RepeatBehavior.Forever;
tk.AutoReverse = true;


this.st = new Storyboard();
this.st.Children.Add(tk);
Storyboard.SetTargetName(tk, this.rg1.Name);
Storyboard.SetTargetProperty(tk, new PropertyPath(Rectangle.MarginProperty));
this.st.Begin(this, true);
this.st.Pause(this);

}

void MainWindow_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.W && this.start == false)
{

this.start = true;
this.st.Resume(this);


}
}


void MainWindow_KeyUp(object sender, KeyEventArgs e)
{

if (e.Key == Key.W)
{
this.start = false;
this.st.Pause(this);
}
}
}

Saman_12
دوشنبه 08 اسفند 1390, 18:19 عصر
این دقیقا همون چیزیه که میخواستم متشکرم!(من با سی شارپ مشکلی ندارم باهاش کار کردم.)
:لبخندساده:

مهدی فرزاد
سه شنبه 09 اسفند 1390, 12:38 عصر
سلام
من یک نمونه ساده دیگه آماده کردم که نیاز به انیمیشن و استارت و استاپ نداره بسیار ساده هست اینو حتما امتحان کنید
با دکمه های Up & Down & Left & Right کیبورد حرکت میکنه


public partial class MainWindow : Window
{
double intTop, intLeft;
public MainWindow()
{
InitializeComponent();
this.KeyDown += new KeyEventHandler(MainWindow_KeyDown);
this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
this.ResizeMode = System.Windows.ResizeMode.CanMinimize;

}

void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
this.WindowState = System.Windows.WindowState.Maximized;
this.intLeft = (this.canvas1.ActualWidth / 2 - (this.rectangle1.Width/2));
this.intTop = (this.canvas1.ActualHeight / 2 - (this.rectangle1.Height/2));
Canvas.SetLeft(this.rectangle1, this.intLeft);
Canvas.SetTop(this.rectangle1, this.intTop);

}

void MainWindow_KeyDown(object sender, KeyEventArgs e)
{


if (e.Key == Key.Up)
{
if (this.intTop > 0)
this.intTop -= int.Parse(this.comboBox1.Text);
Canvas.SetTop(this.rectangle1, this.intTop);
}
else if (e.Key == Key.Down)
{
if (this.intTop < this.canvas1.ActualHeight -this.rectangle1.ActualHeight)
this.intTop += int.Parse(this.comboBox1.Text);
Canvas.SetTop(this.rectangle1, this.intTop);
}
else if (e.Key == Key.Left)
{
if (this.intLeft > 0)
this.intLeft -= int.Parse(this.comboBox1.Text);
Canvas.SetLeft(this.rectangle1, this.intLeft);
}
else if (e.Key == Key.Right)
{
if (this.intLeft < this.canvas1.ActualWidth-this.rectangle1.ActualWidth)
this.intLeft += int.Parse(this.comboBox1.Text);
Canvas.SetLeft(this.rectangle1, this.intLeft);
}

}


}

Saman_12
سه شنبه 09 اسفند 1390, 21:02 عصر
بازهم تشکر میکنم که دنباله مباحث رو میگیرین قبل از پست اولتون در نظر داشتم از همین روش (نه دقیقا یکم فرق داشت) استفاده کنم اما این کار درست جواب نمیده یه جور حالت لگ زدن ایجاد میشه که مطلوب نیست.(یه بازی خیلی ساده و ابتدایی رو مینویسم واسه یکی از درس ها!)

واسه ساخت StoryBord از این تابع استفاده میکنم :


Private Function CreateTranslateStorybord(ByVal obj As Object, ByVal Speed As Double, ByVal TrPro As String) As Storyboard

If obj.RenderTransform.GetType.Name = "MatrixTransform" Then obj.RenderTransform = New TranslateTransform

Dim trform As TranslateTransform = obj.RenderTransform
Dim Stbord As New Storyboard
Dim DAnime As New DoubleAnimation
Dim DeltaX As Double = Me.ActualWidth - obj.ActualWidth
Dim DeltaY As Double = Me.ActualHeight - obj.ActualHeight
Dim DeltaT As New Double

If TrPro = "X" Then

DAnime.To = DeltaX * (Speed / Math.Abs(Speed))
DeltaT = Math.Abs(DeltaX / Speed)
ElseIf TrPro = "Y" Then

DAnime.To = DeltaY * (Speed / Math.Abs(Speed))
DeltaT = Math.Abs(DeltaY / Speed)
End If

DAnime.Duration = TimeSpan.FromSeconds(DeltaT)

Storyboard.SetTargetName(DAnime, obj.Name)
Storyboard.SetTargetProperty(DAnime, New PropertyPath("(RenderTransform).(TranslateTransform." & TrPro & ")"))

Stbord.Children.Add(DAnime)

Return Stbord
End Function