Eat or Be Eaten e едноставна игра направена со Windows Forms која наликува на веќе постоечката игра Agar.io.
Играта започнува со иницијално мало топче околу курсорот, а во околината, топчиња со random големина се појавуваат на random локација и се движат во random насока на екранот. Движејќи го глувчето, нашето топче се зголемува доколку погодиме ("изедеме") топче со помала големина од моменталната големина на нашето топче. Меѓутоа, играта завршува доколку погодиме топче со поголема големина од нашата, т.е. ќе бидеме "изедени".
Ако успееме нашето топче да го доведеме до победничката големина без притоа да бидеме "изедени", ја победуваме играта. На крајот од играта, ќе биде прикажана статистика за тоа колку топчиња сме "изеле" и колку долго сме останале "живи" (колку време траела играта додека не сме изгубиле / победиле).
Фајлот именуван како EatOrBeEaten.exe во овој GitHub репозиториум претставува извршната верзија на играта која треба да ја download-ирате доколку сакате да ја пробате играта.
- Играта започнува кога играчот ќе притисне на копчето (или ќе притисне Enter на тастатурата) при што се отвара форма за селекција на нивото на тежина на играта.
- На почеток, околу курсорот се исцртува бело топче со радиус од 20 единици. Зависно од нивото на тежина на играта, на одреден временски интервал, на екранот ќе се појавуваат топчиња со random големина, на random локација кои ќе се движат во random насока.
- Целта на играта е движејќи го глувчето, играчот да погодува ("јаде") топчиња кои имааат помал радиус од неговото топче (белото топче околку курсорот).
- Со секој удар на топче со помал радиус од моменталниот радиус на топчето на играчот, радиусот на неговото топче се зголемува за 10% од радиусот на топчето кое било "изедено".
- Играчот победува доколку неговото топче (белото топче околу курсорот) достигне радиус поголем од 150 единици.
- Меѓутоа, играчот губи доколку погоди топче со поголем радиус од моменталниот радиус на неговото топче односно ќе биде "изеден".
- За време на играта, во долниот лев агол од екранот, се прикажува моменталниот број на "изедени" топчиња и прикажан е тајмер кој покажува колку време е поминато од стартот на играта (изглед: ).
- Доколку играчот победи, на крајот од играта се прикажува статистика за тоа колку топчиња "изел" и колку време му било потребно за да ја победи играта.
- Доколку играчот изгуби, на крајот од играта се прикажува статистика за тоа колку топчиња "изел" и колку време бил "жив" (колку време траела играта додека не изгубил т.е. бил "изеден" од страна на поголемо топче).
- Играта може да се заврши предвремено доколку играчот притисне на копчето (или притисне Escape на тастатурата). Во тој случај ќе биде прикажана статистика за тоа колку топчиња "изел" и колку време поминало од моментот кога започнала играта до моментот кога играчот решил да ја заврши играта.
- Играта може да се игра на три нивоа на тежина: Easy, Medium, Hard. На најлесното ниво (Easy), нови топчињата на екранот ќе се појавуваат најбавно и брзината на движење на топчињата ќе биде најбавна. Доколку се избере некое од повисоките нивоа на тежина како Medium или Hard, топчињата соодветно ќе се движат побрзо и почесто ќе се појавуваат нови топчиња на екранот. Нивото на тежина, играчот може да го избере кога започува нова игра односно кога ќе кликне на копчето (или ќе притисне Enter на тастатурата). Default-ното ниво на тежина на играта е Easy.
- Кога селектираното ниво на тежина на играта е Easy, на временски интервал од 1500ms на екранот ќе се појавуваат три нови топчиња кои ќе се движат со бризна од една единица на секои 50ms.
- Кога селектираното ниво на тежина на играта е Medium, на временски интервал од 1000ms на екранот ќе се појавуваат три нови топчиња кои ќе се движат со бризна од една единица на секои 20ms.
- Кога селектираното ниво на тежина на играта е Hard, на временски интервал од 500ms на екранот ќе се појавуваат три нови топчиња кои ќе се движат со бризна од една единица на секои 10ms.
Оваа класа го претставува главното топче односно топчето на играчот. Содржи информации за центарот, почетниот радиус, моменталниот радиус и бојата на топчето. Почетниот радиус на топчето е статичка integer променлива со вредност 20. Бојата на топчето е исто така статичка променлива која е поставена на бела боја.
PlayerBall.cs има еден конструктор со еден параметар - точка што го претсавува центарот на топчето на играчот, а има и еден Draw(Graphics g) метод за исцртување на топчето.
Оваа класа е модел за топчињата што ќе се појавуваат на random локација на екранот и ќе се движат во random насока. Содржи информации за центарот, радиусот, бојата на топчето, ширината и висината на прозорецот и променлива (MovingDirection) која означува во која насока се движи топчето.
Променливата MovingDirection е integer променлива која ги прима вредностите: 0, 1, 2, 3, 4, 5, 6, 7. Секоја од овие вредности означува определена насока на движење т.е.:
0 - топчето се движи нагоре
1 - топчето се движи надоле
2 - топчето се движи на лево
3 - топчето се движи на десно
4 - топчето се движи дијагонално нагоре и на лево
5 - топчето се движи диајгонално нагоре и на десно
6 - топчето се движи дијагонално надоле и на лево
7 - топчето се движи дијагонално надоле и на десно
Покрај конструкторот со сите параметри и методот Draw(Graphics g) за исцртување на топчето, во класата Ball.cs има уште неколку битни методи. Со повикување на методот Move(), зависно од вредноста на променливата MovingDirection и менувајќи го центарот на топчето, тоа се придвижува во соодветната насока за една единица. Во методот IsOutOfBounds(), користејќи го центарот на топчето и големината на прозорецот, се пресметува дали топчето има излезено од рамките на прозорецот. Доколку има излезено од рамките, методот враќа true, а во спортивно враќа false. Методот IsHit() исто така враќа boolean променлива true/false во однос на тоа дали топчето е погодено од страна на главното топче - топчето на играчот. Пресметката за тоа дали дошло до допир меѓу топчињата се добива со тоа што се споредува дали растојанието меѓу центрите на топчињата е помало или еднакво на збирот на радиусот на топчињата.
Класата Scene.cs содржи листа од топчиња од класата Ball.cs (тоа се топчињата кои ќе се појавуваат на екранот), еден објект од класата PlayerBall (тоа е главното топче кое го движи играчот), еден објект од типот Random, чува информации за ширината и висината на прозорецот, една integer променлива за бројот на погодени топчиња, две boolean променливи (едната означува дали играчот ја победил играта, а другата за дали тој/таа изгубил) и исто така, оваа класа содржи статичка низа од бои и статичка променлива која го означува почетниот радиус на главното топче.
Има еден конструктор со два параметри - ширината и висината на прозорецот. Во конструкторот се иницијализираат листата од топчиња и Random објектот, главното топче се посатвува на null, бројот на погодени топчиња, за почеток, се поставува на нула и двете boolean променливи се поставуваат на false.
Методот Resized(int width, int height) ја поставува ширината и висината на прозорецот на сцената и на сите топчиња во листата според добиените влезни аргументи.
Во методот AddBall() се избира random насока, random боја на топчето (некоја од боите во статичката низа од бои), радиусот на топчето (random вредност меѓу 10 единици помалку од стартниот радиус на PlayerBall и 10 единици повеќе од моменталниот радиус на PlayerBall) и се избира random точка на екранот што ќе претставува центар на топчето. Потоа од сите овие вредности се генерира топче и тоа се додава во листата со топчиња на сцената.
Методот Draw(Graphics g) ги исцртува сите топчиња од листата со топчиња изминувајќи ја целата листа со foreach циклус во кој за секое топче посебно се повикува неговиот метод за исцртување. Исто така, доколку PlayerBall не е еднаков на null т.е. играта е во тек, тогаш се исцртува и топчето на играчот (PlayerBall).
Во методот Move() се изминуваат сите топчиња во еден циклус и за секое топче се повикува методот Move() од Ball.cs класата за секое топче од листата соодветно да се придвижи. По секое придвижување, користејќи го методот IsOutOfBounds() од Ball.cs класата, се проверува дали топчето излегло од границите на прозорецот за да може да се отстрани истото.
Во методот checkHits() се проверува дали топчето на играчот дошло во судир со некое од топчињата во листата Balls. Доколку дошло до судир на PlayerBall со некое топче со помал радиус од PlayerBall, во тој случај тоа топче се остранува, се зголемува бројот на погодоци (Hits) и радиусот на PlayerBall се зголемува за 10% од радиусот на "изеденото" топче. Исто така, после секој погодок се врши проверка дали играчот ја победил играта (т.е. дали радиусот на PlayerBall преминал 150 единици) и доколку тоа е точно, променливата hasWon се поставува на true. Во случај PLayerBall да погоди топче со поголем радиус од неговиот, играчот губи така што променливата hasLost веднаш се поставува на true, а PlayerBall на null.
NewGame.cs е формата за започување на нова игра. Има три radio buttons (со текст: Easy, Medium, Hard) и зависно кое од нив е селектирано, променливата gameMode од NewGame.cs се поставува на соодветното ниво на тежина. Со клик на копчето се започнува нова игра со селектираното ниво на тежина.
Form.cs е главната форма каде се одвива целата игра.
Во кодот на Form.cs има една променлива што ја претставува сцената (scene), boolean променлива isPlaying која означува дали играта е во тек и содржи две integer променливи, едната за водење евиденција колку време траела играта (timeAlive) и другата за нивото на тежина на играта (gameMode). Наведените променливи за кои се чуваат информации во оваа форма, се иницијализираат во методот initializeScene() кој се повикува во Form1() контрукторот и во други методи по потреба.
Во горниот лев агол, гледајќи го дизајнот на формата, се наоѓаат две копчиња: и . Со притискање на копчето , се отвара формата NewGame.cs и доколку DialogResult-от е еднаков на DialogResult.OK, започнува играта во соодвтениот gameMode. Променливата gameMode се иницијализира според вредноста на gameMode од формата NewGame.cs. Вредности кои може gameMode да ги прими се: 0 - Easy, 1 - Medium, 2 - Hard.
Во формата Form.cs има вкупно три тајмери и со старт на играта сите три тајмери се стартуваат. timerTimeAlive е поставен на интервал од 1000ms и означува колку време трае играта. timerGenerateNewBalls на секој tick генерира три нови топчиња на сцената. Интервалот на овој тајмер се поставува на 1500ms за easy mode, 1000ms за medium mode и 500ms за hard mode. timerMoveBalls на секој tick ги поместува сите топчиња од сцената повикувајќи scene.Move(), а потоа се повикува scene.checkHits() и методот checkEndGame(). Интервалот на овој тајмер се поставува на 50ms за easy mode, 20ms за medium mode и 10ms за hard mode.
Во продолжение на табелата е претставена споредба меѓу трите нивоа на тежина на оваа игра:
Во долниот лев агол се наоѓа status bar со моментална статистика за текот на играта, во однос на тоа колку помали топчиња успеал играчот да погоди - "изеде" (Food Eaten) и колку време трае играта (Time Alive). Овие labels се update-ираат постојано користејќи ги повиците на методите updateFoodEaten() и updateTimeAlive().
Со секое придвижување на глувчето, се менува центарот на PlayerBall од scene за да може топчето на играчот соодветно да ја следи позицијата на глувчето. Исто така, при секое придвижување, се повикува scene.checkHits() за да се провери дали дошло до допир со некое топче. Потоа се повикува методот checkEndGame() во кој се прават проверки за да се утврди дали играта е победена или пак можеби дошло до крај на играта и играчот изгубил. Доколку дошло до победа или пораз, со помош на MessageBox се прикажува соодветна порака и статистика за играта, а потоа се повикуваат методите timersStop() (за да се стопираат трите тајмери) и initializeScene() (со цел сите променливи да се вратат на почетната вредност).
Доколку играчот притисне на копчето додека играта е сè уште во тек, таа се прекинува и се прикажува MessageBox со статистика за играта до моментот на притискање на копчето.
Други побитни методи во Form1.cs се Form1_Paint(object sender, PaintEventArgs e) и Form1_Resize(object sender, EventArgs e). Во Form1_Paint(object sender, PaintEventArgs e) се повикува scene.Draw() и понатаму со повик на Inavlidate() во другите методи од формата се исцртува сè што е потребно на екранот. При промена на големината на прозорецот на формата, во методот Form1_Resize(object sender, EventArgs e) соодветно се менуваат ширината и висината на сцената.