Օձ .Net – Մաս 2

Շարունակենք կատարելագործել մեր Օձ .Net ծրագիրը: Հիշեցնեմ, որ առաջին մասում մենք կարճ ծանոթություն ունեցանք GDI+ գրաֆիկական API-ի հետ և մոտավոր պատկերացում կազմեցինք, թե ինչ ճարտարապետություն ունի Windows Forms ծրագիրը: Այս մասում  կսովորենք օգտագործել Timer դասը ու կիմանանք երկու եղանակ, թե ինչպես կարելի է սիստեմային պատահարներից (event) առաջացած հաղորդագրությունները (messages) կապել համապատասխան ֆունկցիաների հետ, որոնք կոչվում են պատահարը մշակող ֆունկցիաներ (event handler):

Timer-ի օգտագործումը
Timer Control-ը, որը առաջին հայացքից թվում է անպիտան մի բան, շատ բազմազան կիրառություն ունի գրաֆիկական ինտերֆեյսում ծրագրեր գրելու ժամանակ: Մեր ծրագրում  Timer-ը կօգտագործենք, որպեսզի կազմակերպենք օձի շարժումը: Նախ և առաջ պետք է ծրագրի դասում հայտարարել Timer դասի անդամ: Դրա համար դասի մեջ ավելացրեք (ֆունկցիաներից դուրս) հետևյալ տողը:

private Timer timer = new Timer();
Հարց կտաք, թե ինչու այն հայտարարեցինք private: Առայժմ կարիք չկա, որ timer անդամին հնարավոր լինի դիմել դասի դրսից: Եթե այդպիսի կարիք առաջ գա, հետագայում կարող եք դիմման ատրիբուտը փոխել: Ուշադրություն՝ մեր ծրագրում օգտագործում ենք System.Windows.Forms.Timer namespace-ում հայտարարված Timer դասը: Այլ namespace-ներում, օրինակ՝ System.Threading-ում ևս կան նույնանուն դասեր: Խուսափեք իդենտիֆիկատորի հետ կապված կոնֆլիկտներից: Այժմ, երբ timer անդամն արդեն ունենք, պետք է ծրագրի դասի կառուցիչում արժեքներ տալ նրա որոշ անդամների: public Snakes()

ֆունկցիայի մեջ ավելացրեք հետևյալ տողերը՝

timer.Interval = 500;

timer.Tick += new EventHandler(OnTimerTick);

Սրանցից առաջինով տալիս ենք այն ժամանակահատվածը, որը անցնելուն պես պետք է կանչվի համապատասխան event handler-ը: Ժամանակահատվածը տրվում է միլիվայրկյաններով: Ուշադրություն դարձրեք հաջորդ տողին՝ այս տողը առանձնանում է յուրահատուկ սինտակսիսով. հենց այս տողն է վերը նշված եղանակներից մեկը, որով event handler ֆունկցիան կապում ենք event-ի հետ: Այսինքն սրանով ասում ենք, որ OnTimerTick անունով ֆունկցիան կսկսի աշխատել ամեն անգամ, երբ գրանցվի timer.Tick պատահարը:
Եթե ուշադրություն դարձնեք ծրագրի առաջին մասի կոդին, մենք արդեն կիրառել ենք event-ը event handler-ին կապելու մյուս եղանակը՝

protected override void OnPaint(PaintEventArgs e)

Այս տողով մենք գերբեռնել ենք Form դասի մեջ հայտարարված OnPaint ֆունկցիան, որը տրված է որպես Paint պատահարի մշակող ֆունկցիա: Հիշենք, որ Օձ ծրագրի դասը ժառանգել էինք Form դասից, այլապես չէինք կարողանա գերբեռնել protected դիմման ատրիբուտով մեթոդը:
Վերադառնանք խնդրին: Այժմ, երբ timer օբյեկտը արժեքավորած է և պատրաստ է աշխատանքին, մնում է միայն public Snakes()կառուցիչի վերջում ավելացնել հետևյալ տողը՝

timer.Start();

Սրանով մեր timer-ը սկսում է աշխատել և համակարգը պարբերաբար սկսում է գեներացնել timer.Tick պատահարից առաջացած հաղորդագրություններ:
Այժմ նկարագրենք OnTimerTick մեթոդը:

//Code by Jhora Zakaryan, YSU, 2010
void OnTimerTick(object sender, EventArgs e)
{
Rectangle r1 = Snake[0];
for(int i =  0; i < snakelen-1; i++)
Snake[i] = Snake[i+1];
switch (direction)
{
case 0:
snposx++;
break;
case 1:
snposy++;
break;
case 2:
snposx—;
break;
case 3:
snposy—;
break;
}
if (snposx < 0)
snposx = fieldsize;
if (snposy < 0)
snposy = fieldsize;
Snake[snakelen-1] = new Rectangle((snposx % fieldsize) * ifieldx, (snposy % fieldsize) * ifieldy, ifieldx, ifieldy);
Invalidate(Snake[snakelen — 1]);
Invalidate(r1);
Update();
}

Սկզբում ստեղծում ենք r1 ուղղանկյունը և դրա մեջ պահում ենք օձի պոչի ուղղանկյունը: Սրա միտումը պարզ կդառնա վերջում: Այնուհետև for ցիկլում Snake մասիվի էլէմենտները մեկ դիրք տեղափոխում ենք ձախ: Արդյունքում վերանում է պոչի ուղղանյկունը և գլխի ուղղանկյունից աջ հայտնվում է ևս մեկ գլխի ուղղանկյուն: Վերջինիս փոխարեն հետագայում մեկ այլ ուղղանկյուն ենք ստեղծում, որի կոորդինատները կախված են օձի շարժման ուղղությունից: Այդ կոորդինատները որոշվում են հաջորդող switch-ում: C/C++ ծրագրավորողներ, ուշադրություն դարձրեք, C#-ի switch-ում ճյուղավորման յուրաքանչյուր ճյուղից հետո break/return/goto-ն պարտադիր է: Այն կարելի է բաց թողնել միայն դատարկ ճյուղից հետո: direction անդամ-փոփոխականի միջոցով օձի շարժման ուղղությունը որոշում ենք հետևյալ սխեմայով՝

switch կառույցին հաջորդող 2 if-երը սկզբում չէի նախատեսել ավելացնել կոդի մեջ: Դրանք ավելացնելուց առաջ կանգնած էի մի թերության առաջ: Հիշենք, որ օձի գլխի դիրքը որոշելու համար օգտագործում էինք (snposx-4)%fieldsize*ifieldx, snposy%fieldsize*ifieldy արտահայտությունները, որտեղ % օպերանդը ապահովում էր, որ օձը դուրս չգա ու չկորի ծրագրին հատկացված պատուհանից ու ցիկլիկ սողա client area-ում: Սակայն երբ օրինակ snposy-ը փոքր էր դառնում 0-ից, կոորդինատը միևնույն է բացասական էր դառնում և օձը կորում էր տեսադաշտից: Այս երկու if-երով լուծվեց նշված պրոբլեմը:
Հաջոր երկու տողերում գրված Invalidate ֆունկցիաներով թարմացնում ենք client area-ի՝ օձի գլխին և նախկին պոչին համապատասխան ուղղանկյունները: Իրոք, դժվար չէ նկատել, որ ամեն անգամ, երբ օձը «քայլ է կատարում», փոխվում է միայն նրա գլխի կոորդինատը, և վերանում է պոչը նախկին դիրքից: Այսպիսով, օձին, կամ առավելևս ամբողջ client area-ն ամբողջությամբ վերանկարելու կարիք չկա: Update() ֆունկցիան ապահովում է, որ փոփոխությունները անմիջապես արտացոլվեն էկրանին, և ոչ թե հաջորդ անգամ OnPaint ֆունկցիան կանչելու ժամանակ:

Ստեղնաշարի աշխատանքի ապահովումը
Օձ .Net-ին նվիրված հոդվածների երկրորդ մասում մնաց ավելացնենք ստեղնաշարի աշխատանքի ապահովումը: Դրա համար շատ բան պետք չէ: Նախ ծրագրի դասի կառուցիչում ավելացրեք
this.KeyDown += new KeyEventHandler(OnKeyDown);
տողը, որի նշանակությունը ձեզ արդեն ծանոթ է:
Ապա դասի մեջ ավելացրեք OnKeyDown ֆունկցիան՝

void OnKeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Up:
if (direction != 1)
direction = 3;
return;
case Keys.Down:
if (direction != 3)
direction = 1;
return;
case Keys.Left:
if (direction != 0)
direction = 2;
return;
case Keys.Right:
if (direction != 2)
direction = 0;
return;
}
}

Դե, այսեղ առանձնապես բացատրելու բան չկա, միայն ասեմ, որ if-երը ավելացրել եմ նրա համար, որ օրինակ աջ շարժվող օձը չկարողանա միանգամից 180 աստիճան պտույտ գործի և ձախ շարժվի:
Հա, ու հիշում եք, մենք պայմանավորվել էինք չգծել սև ցանցը, որպեսզի ծրագիրն արագ աշխատի: Այժմ դրա կարիքը չկա, և ցանկության դեպքում ցանցը է նկարել, քանի որ օձի շարժումը OnTimerTick-ում կազմակերպել ենք այնպես, որ այն չի պահանջում ամբողջ «տախտակի» վերանկարումը:
Կեցցե՛նք մենք՝ մեր օձը շարժվում է 😉 Կցում եմ screenshot-ներ.


Առայժմ այսքանը, հոդվածին կցում եմ նաև ծրագրի ամբողջական աշխատող կոդը .docx ֆայլում:

snakepart2

Շարունակելի…

Advertisements

Մեկնաբանություններ (2)

Filed under Ծրագրավորում

2 responses to “Օձ .Net – Մաս 2

  1. Ժողովուրդ ալարում եմ շարունակությունը գրել: Եթե պետք է, ասեք ավելի կատարելագործած տարբերակի կոդը ուղարկեմ ձեր էլ. փոստին… Նոր տարբերակում օձը ուտում է խնձորներ և երկարում է և պատահական դիրքերում որոշակի ինտերվալը մեկ խնձորներ են հայտնվում:

  2. Tatev

    Bayc es cragir@ im mot chashxatec?Chem haskanum inch sxal e talis.

Թողնել պատասխան

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Փոխել )

Twitter picture

You are commenting using your Twitter account. Log Out / Փոխել )

Facebook photo

You are commenting using your Facebook account. Log Out / Փոխել )

Google+ photo

You are commenting using your Google+ account. Log Out / Փոխել )

Connecting to %s