PDA

View Full Version : QUIT در برنامه SDL



shaaadi
دوشنبه 17 اسفند 1388, 18:53 عصر
این یک تیکه از کد برنامه ی من هست ... با وجود این که QUIT گذاشتم ... اما چرا وقتی x میزنم برنامه بسته نمیشه ؟


while(quit==false)
{
x += k;
if( ( x < 0 ) || ( x + 20 > SCREEN_WIDTH ) )
{
x -= k;
k=-5;
//printf("%d",k);
}


SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface( cancer, NULL , screen, &offset );
SDL_Delay(500);
SDL_Flip( screen );
SDL_BlitSurface(sefid,clip,screen,&offset);


if (SDL_PollEvent(&event))
if( event.type == SDL_QUIT )
quit = true;

}
SDL_Quit();
در واقع چرا این تیکه برنامه رو نمیبنده؟


if (SDL_PollEvent(&event))
if( event.type == SDL_QUIT )
quit = true;

shaaadi
دوشنبه 17 اسفند 1388, 19:02 عصر
آخه وقتی داریم X میکنیم صفحه رو هم داره ی اتفاق (EVENT ) میفته و هم اون اتفاق SDL _Quit هست ! پس چرا if ها برقرار نباشه ؟

shaaadi
دوشنبه 17 اسفند 1388, 19:24 عصر
اول اینکه مرسی از راهنمایی تون و بعد اینکه
۲ تا سوال :
۱. اصلآ این تابع رو نمیشناسه ... header خاصی لازم داره ؟
۲. این تابع چی کار میکنه ؟


اینم کل تابع که فقط ی عکس میره و میخوره به دیوار و برمیگرده !



int MoveCancer(int x,int y,SDL_Surface * screen)
{
int Vy=0,Vx=0;
bool quit=false;
SDL_Surface* load;
SDL_Surface* cancer;
SDL_Event event;
int SCREEN_WIDTH=700;
int SCREEN_HEIGHT=700;
load=IMG_Load("kharchang.bmp");
cancer=SDL_DisplayFormat(load);
SDL_FreeSurface(load);
SDL_Surface* sefid;
sefid=IMG_Load("sefid.jpeg");
sefid=SDL_DisplayFormat(sefid);
SDL_Rect clip[1];
clip[0].x=0;
clip[0].y=0;
clip[0].h=32;
clip[0].w=31;
int k=5;
while(quit==false)
{
x += k;
if( ( x < 0 ) || ( x + 20 > SCREEN_WIDTH ) )
{
x -= k;
k=-5;
//printf("%d",k);
}


SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface( cancer, NULL , screen, &offset );
SDL_Delay(500);
SDL_Flip( screen );
SDL_BlitSurface(sefid,clip,screen,&offset);


if (SDL_PollEvent(&event))
{
MessageBox(0,"SDL_PollEvent(&event) != 0",0,0);
if(event.type == SDL_QUIT)
{
MessageBox(0,"event.type == SDL_QUIT",0,0);
quit = true;
}
}
}
SDL_Quit();
return 0;
}

shaaadi
دوشنبه 17 اسفند 1388, 19:41 عصر
میگه چنین header ی وجود نداره ! نمیدونم ربطی داره یا نه اما من دارم برنامه رو تو لینوکس و با کامپایلر g ++ مینویسم !

Nima_NF
سه شنبه 18 اسفند 1388, 01:15 صبح
اگر عنوان تاپیک را درست انتخاب کنید، دوستان بیشتری می توانند کمک کنند و این توضیح را هم بدهید که شما در حال استفاده از کتابخانه مالتی مدیا معروف SDL هستید.

تنها اشکالی که می بینم این هست که تابع SDL_Delay ممکن هست در کار شما اشکال ایجاد کند، چون این تابع در مدت 0.5 ثانیه کلا برنامه را freeze می کند، لذا پیام های شما در این مدت در صف انتظار قرار نمی گیرد.

برای تست، آن را حذف کنید، اگر مشکل از آن بود روش های دیگر برای این وقفه زمانی انتخاب کنید.
دقت کنید که شما از while استفاده می کنید و داخل آن پیام ها را از صف دریافت می کنید، چون ممکن هست در هر ثانیه میلیون ها پیام ارسال شود که تنها یکی از آن ها Quit هست. پس نباید جلوی آن را با delay بگیرید و فقط 1 مرتبه این طوری تست کنید.

shaaadi
سه شنبه 18 اسفند 1388, 10:43 صبح
خیلی ممنون ... هم از اینکه عنوان رو درست کردین هم از جوابتون !
امتحان کردم ... درست شد ! فقط سرعت کلی رفت بالا ! راه دیگه ای هم بلد نیستم ...میشه کمک کنید ؟
یک سوال دیگه هم داشتم :
این if اول رو برای چی میزاریم ؟ خوب از همون اول event رو بررسی کنیم دیگه ! چون وقتی داریم X میکنیم پس حتما یک event وجود داره !

Nima_NF
سه شنبه 18 اسفند 1388, 13:37 عصر
راه دیگه ای هم بلد نیستم ...میشه کمک کنید ؟
اگر قرار هست از delay استفاده کنید باید در یک thread جداگانه باشد تا thread اصلی که پیام ها را می گیرد freeze نشود.

کلا در برنامه ها گرافیکی/مالتی مدیا هدف این هست که شما نهایت استفاده از CPU را داشته باشید، پس راهکار دیرگ این هست که بازه حرکت را کم کنید. فکر می کنم در برنامه شما K مقدار حرکت هست، آن را به جای 5 به یک عدد کوچک اعشاری تبدیل کنید تا در یک ثانیه شکل شما به اندازه مورد نیاز جابجا شود.


این if اول رو برای چی میزاریم ؟ خوب از همون اول event رو بررسی کنیم دیگه ! چون وقتی داریم X میکنیم پس حتما یک event وجود داره !
if اول منظورتان کدام هست؟ اگر منظورتان SDL_PollEvent هست، که برای دریافت پیام از صف هست. هر پیامی می تواند باشد.
با SDL_PollEven پیام کنونی در event کپی می شود. اگر X را کلیک می کنید قرار نیست فورا ارسال شود، در همان لحظه صدها پیام حرکت mouse غیره نیز ارسال می شود. پس ابتدا بررسی می کنید که آیا کلا پیامیدر صف هست، اگر بود، آیا یکی از آنها پیام quit هست با خیر.
دقت کنید که همیشه باید while باشد، استثنائا در این برنامه که می دانم از یکی از سایت های آموزشی هست به این شکل عمل شده، چون پیام باید بارها بررسی شود که آیا وجود دارد یا خیر.

shaaadi
سه شنبه 18 اسفند 1388, 14:32 عصر
اره منظورم همین بود ... اما اگه while باشه که چون همیشه داره یک اتفاقی میفته چه جوری از while میاد بیرون ...؟؟
(راستی درسته ... دارم از lazy foo برای نوشتنش کمک میگیرم )

shaaadi
چهارشنبه 19 اسفند 1388, 15:51 عصر
یک سوال دیگه هم اینکه :
اگه عدد سرعت رو کم کنم در زمانی که برنامه به اون تیکه میرسه همه ی چیزای متحرک می ایستند ! در واقع انگار در اون مدت زمان اون قسمت خاص گیر میکنه ! اینم که گفتین در ی thread جدا گانه ... منظورتون رو نفهمیدم ! آخه باید تو همون while که داره حرکت رو ایجاد میکنه delay بذارم دیگه ! جای دیگه که نمیشه ! میشه لطفآ راهنمایی کنید !!

Nima_NF
چهارشنبه 19 اسفند 1388, 19:14 عصر
در واقع انگار در اون مدت زمان اون قسمت خاص گیر میکنه !
منظورتان کدام قسمت خاص هست؟ در کدام قطعه کد گیر می کند؟

نگاه کنید، شما باید برنامه را طوری بنویسید که مثلا نهایت 60 فریم داشته باشید(البته بستگی به شما دارد، اما برای برنامه شما بیش از این نیاز نیست).
پس اگر قرار هست از Delay استفاده کنید نهایت 16 میلی ثانیه باشد. به این شکل پیام ها را راحت می توانید دریافت کنید و delay هم مشکلی ایجاد نمی کند. اما وقتی می نویسید 500 میلی ثانیه، یعنی هر ثانیه نهایت 2 فریم، پس فقط در همین 2 فریم می توانید پیام ها را دریافت کنید.
درنتیجه بازه حرکت را اندازه ای قرار دهید که برنامه شما نهایت 60 فریم شود. (محاسبه کنید، با توجه به زمان کنونی هر فریم یا هر دور حلقه و زمان قبلی هر فریم)


اینم که گفتین در ی thread جدا گانه ... منظورتون رو نفهمیدم
یک روش برای کار با thread به این شکل هست: شما کدهای پردازش پیام ها را در حلقه while در thread-1 قرار می دهید و کاری ندارید که کی از حلقه خارج می شود. سپس در thread-2 کلیه کارهای رسم شکل را انجام می دهید، لذا اگر delay استفاده کنید فقط thread-2 متوقف می شود و همچنان پیام ها بدون توجه به در thread-1 قابل دریافت هست. متغیر ها بین دو thread نیز مشترکند، پس می توانید برای خروج و تغییرات استفاده کنید.