PDA

View Full Version : سوال: مشکل کندی اجرا در یک بازی ساده



sadeghjun
شنبه 12 مرداد 1392, 18:53 عصر
سلام دوستان
من دارم یه بازی ساده می نویسم که یه کم کنده نمیدونم باید چیکار کنم.
البته مشکل زیاد داره. وهنوز کامل نشده فقط حرکت دادن توپه!!
ممنون میشم یه نگاهی بندازید راهنماییم کنید.


تصویر:

108433



سورس پروژه:
108432

sadeghjun
شنبه 12 مرداد 1392, 19:17 عصر
سلام
کسی نظری نداره!!

aliagamon
شنبه 12 مرداد 1392, 19:45 عصر
ببین تو الان داری اینطوری عمل میکنی که ثانیه ثانیه(کمتر از ثانیه) داری چک میکنی picturebox کجا باشه بهتره بیای و یه تابع بنویسی که هر ثانیه پیکچرباکسو ببره اونجا که موس هست(اگه کلیک کرد اونجا)یعنی جا اینکه drag&drop کنه کلیک کنه بپره اونجا....
این میتونه سرعت کارت رو بالا ببره شاید بتونی با استفاده از thread و جدا کردن پروسس picturebox از بقیه برنامه سرعت رو بالا ببری اینطوری حواب میده...
فرض من اینه که تو 22 تا از این picturebox ها میزاری که بازیکنن با استفاده از thread میتونی هر picturebox رو جداگونه پردازش کنی
چنتا نمونه (http://www.radcom.ir/kb-thread-fa.html)

sadeghjun
شنبه 12 مرداد 1392, 22:24 عصر
شرمنده
میتونی یه مثال بزنی
این آدرسی که شما لینک کردی یه کلاس هست.
من نمی تونم استفاده کنم. (یعنی بلد نیستم!!!)

sadeghjun
یک شنبه 13 مرداد 1392, 15:39 عصر
سلام
وقتی با thread می نویسم این ارور رو میده:


108476

دلیلش چیه؟


این کدشه

private void Form1_Load(object sender, EventArgs e)
{
Thread th1 = new Thread(ball_state_upd);
th1.Start();
}
void ball_state_upd()
{
x1 = BallPictureBox.Left;
y1 = BallPictureBox.Top;
x2 = pictureBox3.Left;
y2 = pictureBox3.Top;
// dl = down_left
if (dir == "dl")
{
BallPictureBox.Left -= ball_step;
BallPictureBox.Top += ball_step;
if (y1 > this.BackgroundImage.Height - BallPictureBox.Height || (y1 >= y2 - BallPictureBox.Height && y1 <= y2 + pictureBox3.Height && x1 >= x2 - BallPictureBox.Width && x1 <= x2 + pictureBox3.Width))
{ dir = "ul"; snd.Play(); }
if (x1 < 0)
{ dir = "dr"; snd.Play(); }
}
else if (dir == "ur")
{
BallPictureBox.Left += ball_step;
BallPictureBox.Top -= ball_step;
if (x1 > this.BackgroundImage.Width - BallPictureBox.Width)
{ dir = "ul"; snd.Play(); }
if (y1 < 0)
{ dir = "dr"; snd.Play(); }
}
else if (dir == "dr")
{
BallPictureBox.Left += ball_step;
BallPictureBox.Top += ball_step;
if ((x1 >= this.BackgroundImage.Width - BallPictureBox.Width))
{ dir = "dl"; snd.Play(); }
if (y1 > this.BackgroundImage.Height - BallPictureBox.Height || (y1 >= y2 - BallPictureBox.Height && y1 <= y2 + pictureBox3.Height && x1 >= x2 - BallPictureBox.Width && x1 <= x2 + pictureBox3.Width))
{ dir = "ur"; snd.Play(); }
}

else if (dir == "ul")
{
BallPictureBox.Left -= ball_step;
BallPictureBox.Top -= ball_step;
if (x1 < 0)
{ dir = "ur"; snd.Play(); }
if (y1 < 0)
{ dir = "dl"; snd.Play(); }
}
Thread.Sleep(100);
}

sadeghjun
یک شنبه 13 مرداد 1392, 17:11 عصر
هیج یاری کننده ای نیست؟!!

sadeghjun
دوشنبه 14 مرداد 1392, 00:21 صبح
سلام
مشکل thread ی که نوشتم چیه؟

مهرداد صفا
دوشنبه 14 مرداد 1392, 02:26 صبح
با سلام.
دوست عزیز لطف کنید و کمی زحمت بکشید متن خطاها و کدها (کلی بود) را تایپ کنید. بعضی از دوستان نمایش تصاویر را در مرورگر غیر فعال می کنند.
معمولا فقط thread سازنده کنترل به آن دسترسی دارد و می تواند خصوصیات آن را تغیر دهد. برای رفع این مشکل دو راه کلی دارید:
کد مربوط به تغییرات کنترل را از طریق thread سازنده کنترل invoke کنید:

PictureBox1.Invoke(()=> pictureBox1.left=n);


یا به بقیه thread ها اجازه تغییرات را بدهید:

///قبل از هر گونه کار و ترجیحا با استفاده از thread اصلی
Control.CheckForIllegalCrossThreadCalls=false;

sadeghjun
دوشنبه 14 مرداد 1392, 04:27 صبح
سلام ممنون m.safa جان

مشکل اون خطا برطرف شد ولی توپ دیگه حرکت نمیکنه.

کد:
private void Form1_Load(object sender, EventArgs e)
{
Thread th1 = new Thread(ball_state_upd);
Control.CheckForIllegalCrossThreadCalls = false;
th1.Start();
}
void ball_state_upd()
{
x1 = BallPictureBox.Left;
y1 = BallPictureBox.Top;
x2 = pictureBox3.Left;
y2 = pictureBox3.Top;
// dl = down_left
if (dir == "dl")
{
BallPictureBox.Left -= ball_step;
BallPictureBox.Top += ball_step;
if (y1 > this.BackgroundImage.Height - BallPictureBox.Height || (y1 >= y2 - BallPictureBox.Height && y1 <= y2 + pictureBox3.Height && x1 >= x2 - BallPictureBox.Width && x1 <= x2 + pictureBox3.Width))
{ dir = "ul"; snd.Play(); }
if (x1 < 0)
{ dir = "dr"; snd.Play(); }
}
else if (dir == "ur")
{
BallPictureBox.Left += ball_step;
BallPictureBox.Top -= ball_step;
if (x1 > this.BackgroundImage.Width - BallPictureBox.Width)
{ dir = "ul"; snd.Play(); }
if (y1 < 0)
{ dir = "dr"; snd.Play(); }
}
else if (dir == "dr")
{
BallPictureBox.Left += ball_step;
BallPictureBox.Top += ball_step;
if ((x1 >= this.BackgroundImage.Width - BallPictureBox.Width))
{ dir = "dl"; snd.Play(); }
if (y1 > this.BackgroundImage.Height - BallPictureBox.Height || (y1 >= y2 - BallPictureBox.Height && y1 <= y2 + pictureBox3.Height && x1 >= x2 - BallPictureBox.Width && x1 <= x2 + pictureBox3.Width))
{ dir = "ur"; snd.Play(); }
}

else if (dir == "ul")
{
BallPictureBox.Left -= ball_step;
BallPictureBox.Top -= ball_step;
if (x1 < 0)
{ dir = "ur"; snd.Play(); }
if (y1 < 0)
{ dir = "dl"; snd.Play(); }
}
Thread.Sleep(100);
}

tooraj_azizi_1035
دوشنبه 14 مرداد 1392, 13:55 عصر
CheckForIllegalCrossThreadCalls رو پاک کن.
و کدت رو اینطوری بنویس:

this.Invoke (() =>
{
x1 = BallPictureBox.Left;
....
}

sadeghjun
سه شنبه 15 مرداد 1392, 01:11 صبح
سلام
ممنون tooraj_azizi_1035 جان
کدی که شما نوشتی رو کجا باید بذارم.
در داخل تابع ball_state_upd یا داخل فرم لود.!!
هرجا میذارم خطا داره.

sadeghjun
سه شنبه 15 مرداد 1392, 14:02 عصر
CheckForIllegalCrossThreadCalls رو پاک کن.
و کدت رو اینطوری بنویس:

this.Invoke (() =>
{
x1 = BallPictureBox.Left;
....
}



سلام این کد رو باید کجا نوشت؟
هرجا مینویسم خطا میده

tooraj_azizi_1035
سه شنبه 15 مرداد 1392, 14:41 عصر
سلام
ببین داخل این متد:
void ball_state_upd()
یعنی عر چی هست داخل اون بدنه ای که گفتم باید باشه.همه چیز داخل این بلوک:

this.Invoke (() =>
{

}

sadeghjun
سه شنبه 15 مرداد 1392, 16:58 عصر
شرمنده متوجه نمیشم شما چی میگید.
میشه باتوجه به کدی که بالا گذاشتم تغییراتو توش اعمال کنید.
ممنون

aliagamon
سه شنبه 15 مرداد 1392, 17:42 عصر
منظورشون اینه که تابع ball_stat_upd اینطوری بشه:

void ball_state_upd()
{

this.Invoke(new Action(() =>
{
x1 = BallPictureBox.Left;
y1 = BallPictureBox.Top;
x2 = pictureBox3.Left;
y2 = pictureBox3.Top;
// dl = down_left
if (dir == "dl")
{
BallPictureBox.Left -= ball_step;
BallPictureBox.Top += ball_step;
if (y1 > this.BackgroundImage.Height - BallPictureBox.Height || (y1 >= y2 - BallPictureBox.Height && y1 <= y2 + pictureBox3.Height && x1 >= x2 - BallPictureBox.Width && x1 <= x2 + pictureBox3.Width))
{ dir = "ul"; snd.Play(); }
if (x1 < 0)
{ dir = "dr"; snd.Play(); }
}
else if (dir == "ur")
{
BallPictureBox.Left += ball_step;
BallPictureBox.Top -= ball_step;
if (x1 > this.BackgroundImage.Width - BallPictureBox.Width)
{ dir = "ul"; snd.Play(); }
if (y1 < 0)
{ dir = "dr"; snd.Play(); }
}
else if (dir == "dr")
{
BallPictureBox.Left += ball_step;
BallPictureBox.Top += ball_step;
if ((x1 >= this.BackgroundImage.Width - BallPictureBox.Width))
{ dir = "dl"; snd.Play(); }
if (y1 > this.BackgroundImage.Height - BallPictureBox.Height || (y1 >= y2 - BallPictureBox.Height && y1 <= y2 + pictureBox3.Height && x1 >= x2 - BallPictureBox.Width && x1 <= x2 + pictureBox3.Width))
{ dir = "ur"; snd.Play(); }
}

else if (dir == "ul")
{
BallPictureBox.Left -= ball_step;
BallPictureBox.Top -= ball_step;
if (x1 < 0)
{ dir = "ur"; snd.Play(); }
if (y1 < 0)
{ dir = "dl"; snd.Play(); }
}
Thread.Sleep(100);
}));
}

البته تو خود ادیتور اینجا درست کردم ببین درسته یا نه...
و اینکه اون دستور:

Control.CheckForIllegalCrossThreadCalls = false;

رو از لود فرم بردار ارورا درست میشن
احتمالا الان دیگه کندی کار رفع شده:چشمک::متفکر:

sadeghjun
سه شنبه 15 مرداد 1392, 18:32 عصر
ممنون aliagamon
الان با کد شما هیچ خطایی نداره ولی مکان توپ ثابته!!

aliagamon
سه شنبه 15 مرداد 1392, 18:35 عصر
Control.CheckForIllegalCrossThreadCalls = false;

رو پاک کردین؟

sadeghjun
سه شنبه 15 مرداد 1392, 18:37 عصر
Control.CheckForIllegalCrossThreadCalls = false;

رو پاک کردین؟


بله این کارو انجام داده بودم ولی مشکل حل نشد

aliagamon
سه شنبه 15 مرداد 1392, 18:42 عصر
حتما تایمر رو از کار انداخته اید و یا اتفافی تو این مایه ها:لبخند:
یه نگاه بندازین ببینین شاید تناقضی چیزی داره

sadeghjun
سه شنبه 15 مرداد 1392, 18:54 عصر
به تایمر که ربطی نداره

داخل تایمر مگه چی باید بنویسم؟

مهرداد صفا
سه شنبه 15 مرداد 1392, 19:26 عصر
سلام ممنون m.safa جان

مشکل اون خطا برطرف شد ولی توپ دیگه حرکت نمیکنه.

کد:
private void Form1_Load(object sender, EventArgs e)
{
Thread th1 = new Thread(ball_state_upd);
Control.CheckForIllegalCrossThreadCalls = false;
th1.Start();
}
void ball_state_upd()
{
x1 = BallPictureBox.Left;
y1 = BallPictureBox.Top;
x2 = pictureBox3.Left;
y2 = pictureBox3.Top;
// dl = down_left
if (dir == "dl")
{
BallPictureBox.Left -= ball_step;
BallPictureBox.Top += ball_step;
if (y1 > this.BackgroundImage.Height - BallPictureBox.Height || (y1 >= y2 - BallPictureBox.Height && y1 <= y2 + pictureBox3.Height && x1 >= x2 - BallPictureBox.Width && x1 <= x2 + pictureBox3.Width))
{ dir = "ul"; snd.Play(); }
if (x1 < 0)
{ dir = "dr"; snd.Play(); }
}
else if (dir == "ur")
{
BallPictureBox.Left += ball_step;
BallPictureBox.Top -= ball_step;
if (x1 > this.BackgroundImage.Width - BallPictureBox.Width)
{ dir = "ul"; snd.Play(); }
if (y1 < 0)
{ dir = "dr"; snd.Play(); }
}
else if (dir == "dr")
{
BallPictureBox.Left += ball_step;
BallPictureBox.Top += ball_step;
if ((x1 >= this.BackgroundImage.Width - BallPictureBox.Width))
{ dir = "dl"; snd.Play(); }
if (y1 > this.BackgroundImage.Height - BallPictureBox.Height || (y1 >= y2 - BallPictureBox.Height && y1 <= y2 + pictureBox3.Height && x1 >= x2 - BallPictureBox.Width && x1 <= x2 + pictureBox3.Width))
{ dir = "ur"; snd.Play(); }
}

else if (dir == "ul")
{
BallPictureBox.Left -= ball_step;
BallPictureBox.Top -= ball_step;
if (x1 < 0)
{ dir = "ur"; snd.Play(); }
if (y1 < 0)
{ dir = "dl"; snd.Play(); }
}
Thread.Sleep(100);
}



سلام خواهش می کنم.
نمونه برای راه اول همانطور که دوستان اشاره کردند:

private void Form1_Load(object sender, EventArgs e)
{
this.Invoke((Action)this.MaximizePictureBox);
}

private void MaximizePictureBox()
{
System.Media.SystemSounds.Beep.Play();
pictureBox1.Size = this.Size;
}

sadeghjun
سه شنبه 15 مرداد 1392, 19:32 عصر
با این روش مشکل کندی برطف نشد

aliagamon
سه شنبه 15 مرداد 1392, 20:22 عصر
به تایمر که ربطی نداره

داخل تایمر مگه چی باید بنویسم؟
اگه درست یادم باشه حرکت توپو تو timer نوشته بودی و میگم ممکنه اونو پاک کرده باشی

sadeghjun
سه شنبه 15 مرداد 1392, 21:24 عصر
حرکت توپ قبلا تو تایمر بود. الآن که تو تابع ball_state_upd هست!
من اینجوری نوشتم مشکل حرکت توپ برطرف شد ولی مشکل کندی هنوز پا برجاست!!

private void Form1_Load(object sender, EventArgs e)
{

}
void ball_state_upd()
{

this.Invoke(new Action(() =>
{
x1 = BallPictureBox.Left;
y1 = BallPictureBox.Top;
x2 = pictureBox3.Left;
y2 = pictureBox3.Top;
// dl = down_left
if (dir == "dl")
{
BallPictureBox.Left -= ball_step;
BallPictureBox.Top += ball_step;
if (y1 > this.BackgroundImage.Height - BallPictureBox.Height || (y1 >= y2 - BallPictureBox.Height && y1 <= y2 + pictureBox3.Height && x1 >= x2 - BallPictureBox.Width && x1 <= x2 + pictureBox3.Width))
{ snd.Play(); dir = "ul"; }
if (x1 < 0)
{ snd.Play(); dir = "dr"; }
}
else if (dir == "ur")
{
BallPictureBox.Left += ball_step;
BallPictureBox.Top -= ball_step;
if (x1 > this.BackgroundImage.Width - BallPictureBox.Width)
{ snd.Play(); dir = "ul"; }
if (y1 < 0)
{ snd.Play(); dir = "dr"; }
}
else if (dir == "dr")
{
BallPictureBox.Left += ball_step;
BallPictureBox.Top += ball_step;
if ((x1 >= this.BackgroundImage.Width - BallPictureBox.Width))
{ snd.Play(); dir = "dl"; }
if (y1 > this.BackgroundImage.Height - BallPictureBox.Height || (y1 >= y2 - BallPictureBox.Height && y1 <= y2 + pictureBox3.Height && x1 >= x2 - BallPictureBox.Width && x1 <= x2 + pictureBox3.Width))
{ snd.Play(); dir = "ur"; }
}

else if (dir == "ul")
{
BallPictureBox.Left -= ball_step;
BallPictureBox.Top -= ball_step;
if (x1 < 0)
{ snd.Play(); dir = "ur"; }
if (y1 < 0)
{ snd.Play(); dir = "dl"; }
}
//Thread.Sleep(10);
}));

}

private void timer1_Tick(object sender, EventArgs e)
{
Thread th1 = new Thread(new ThreadStart(ball_state_upd));
if(th1.IsAlive==false)
th1.Start();
//th1.Abort();
}

sadeghjun
سه شنبه 15 مرداد 1392, 23:58 عصر
سلام
لطفا راهنمایی کنید.
ممنون

sadeghjun
چهارشنبه 16 مرداد 1392, 22:13 عصر
یعنی هیچکس نمیتونه کمک کنه؟؟!!!

tooraj_azizi_1035
چهارشنبه 16 مرداد 1392, 23:04 عصر
شما چرا داخل رویداد Tick تایمر هر بار یک Thread می سازید؟؟؟؟؟؟؟ یعنی بعد از 100 ثانیه شما 100 تا ترد می سازی؟
استفاده از Thread هم شاید خیلی کارساز نباشه چون پای Thread UI گیره یعنی شما داری به BallPictureBox در تردی دیگر دست پیدا می کنی.
بدون ترد یکبار بنویس و تست کن.

habibb
چهارشنبه 16 مرداد 1392, 23:11 عصر
تو مبحث ساخت بازی ها برای رفع کندی حرکت باید از دابل بافرینگ استفاده کنی؟

sadeghjun
چهارشنبه 16 مرداد 1392, 23:33 عصر
ممنون
میشه یه کم توضیح بدی؟؟

sadeghjun
چهارشنبه 16 مرداد 1392, 23:35 عصر
شما چرا داخل رویداد Tick تایمر هر بار یک Thread می سازید؟؟؟؟؟؟؟ یعنی بعد از 100 ثانیه شما 100 تا ترد می سازی؟
استفاده از Thread هم شاید خیلی کارساز نباشه چون پای Thread UI گیره یعنی شما داری به BallPictureBox در تردی دیگر دست پیدا می کنی.
بدون ترد یکبار بنویس و تست کن.

ممنون
من اولش کدها رو درون تایمر نوشتم (پست 1) ولی کند بود

aliagamon
پنج شنبه 17 مرداد 1392, 00:29 صبح
نگاه کن کلا استفاده از ویندوز فرم در مواردی مثل این که نیاز به جا به جایی داره دیوانگیه(بدون پرده حرف زدم:لبخند:)برا همین اصلا wpf رو ساختن....
اما تو اگه دوتا کار کنی فکر کنم بهتر شه یکی این که بیای پردازش رو در یک thread و نمایش رو به thread دیگه منتقل کنی
دوم اینکه اون عکسی که استفاده کردی رو با گرافیک درست کنی وگرنه کلا کند میمونه چون ویندوز فرم کلا ضعف اصلیش همینه که نمیشه این کارا رو کرد:عصبانی++:

plus
پنج شنبه 17 مرداد 1392, 01:22 صبح
این رو بررسی کنید ببینید بازم کنده براتون؟

sadeghjun
پنج شنبه 17 مرداد 1392, 03:42 صبح
ممنون
کندی زمانیی پیش میومد که شی مستطیلی رو حرکت میدادم
باید اونو به کد شما اضافه کنم ببینم.