Elevator rush [Custom game]
Здравейте,
предаставям ви играта, върху която работя. Кръстил съм я Elevator rush. Крайният вариант трябва да представлява нещо подобно на: Mini metro и Mini motorways само че с асансьори :)
Вчера след като чух изискванията се зарадвах, защото някои от нещата вече ги бях направил, така че се боря за най-високия резултат в краткото оставащо време, за което и пиша тук, тъй като имам доста въпроси и проблеми за решаване.
Линк с код-а: https://github.com/Smeshan/Elevator-rush (мисля, че се справих)
Идеята на играта:
Всяко ниво има сграда, на която в random момент се появяват хората (сини кръгчета за сега), които искат да се качат или слязат от някой етаж. Има шахти за асансьори, при които ще се поставят с мишката асансьори, които ще се движат автоматично (според зависи дали хората отиват някъде или офисите имат нужда от хора, още не съм решил кой ще управлява).
Ще има таймер горе, който отмерва едно денонощие (30-60 сек) и на следващия ден се появява на екрана избор за играча, измежду нов асансьор, нова шахта, по-голям аснасьор, стъпала дори, и всякакви такива, които той събира и разполага по картата. Ще избира само едно от две. И тези различни асансьори ще се разполагат по картата или ще се пазят, изобразени някъде по екрана.
В същото време с всеки ден се забързва появяването на хората и офисите, до момента в който губиш играта, ако някой човек(или офис) е чакал прекалено много време и не е бил взет от асансьор. Всеки човек е една точка и се бориш за high score.
Какво съм направил до сега:
Има главно меню с динамичен бекраунд и гейм меню, което зарежда ниво. Там съм разположил офиси (квадратите с числа 1-2..) и един асаньор и един човек (кръгчето). Както и tile map на асаньора, която ще ползвам за поставяне на асаньори според стратегията на играча. Хората имат число над себе си и това етажа на който искат да отидат (ще отпадне по нататък). Офисите пък също има индикатор, който показва колко хора са нужни да се закарат там. За проба съм нагласил бутони + и -, както и 1 и 2.
Проблемите:
1. Кода поддържа звуци и музика, НО има някакво забавяне в изпълнението. Първо ако мините с мишка през главното меню хвърля грешка от Mix_GetError() -> Mix_PlayChannel() failed. Error: Surface doesn't have a colorkey. Която е супер странна и не разбирам как да я оправя. Рових в нета - нищо свързано с миксера от тази грешка. Но може би от там идва това забавяне след като се сложи мишката върху бутон от менюто и не произлиза веднага звук.
2. В MenuButton.cpp функцията, която оцветява текста, по някакви причини не работи с WHITE и GREY, отново никаква идея защо е това странно поведение.
3. В text.cpp в void Text::destroy() , която се обсъждаше добавянето unLoadText при мен се чупи в момента, в който го добавя.
Архитектурни питанки:
1. След като стартираш играта от менюто, обектите и анимацията от main menu си остават на заден план, но просто не се рисуват нали? Какво трябва да ги направя, да ги деинициализирам в която фунцкия всеки обект ще се дестройва? Или?
2. Създал съм LevelPos, който за по-лесно преизчислява кординатите по етажи и шахти(колони), но ми се струва, че не съм го направил много добре. Но то и самия grid map е различен за чакащите хора, асансьорите и офисите, като се предполага, че като добавяш нови шахти, офисите и хората ще мърдат сътоветно настрани.
3. В даден момент, когато съм готов ще трябва да направя PersonGenerator и OfficeGenerator, които да генерира съотвените обекти на нивото. Само че просто random не би било яко. Как да го персонализирам, така че да може едно ниво да бъде горе-долу еднакво или като цяло да мога да го контролирам. Скоростта на създаване е ясна на теория, но примерно в началото на деня да пуска повече хора долу (отиващи хора да работят в офис), на обяд друго, вечерта трето. Просто този генератор как да го контролирам и все пак да е рандом, за да не е напълно еднакво нивото.
4. Придвижването на хора. Вижте в Elevator.cpp съм докарал process() фунцкията, която да гледа ако аснасьора е спрял и ако не е пълен, да вземе хора от етажа. Само че хората са в Level обекта. Бях написал прокси, което взема и прехвърля човек. Това ли е начина? Или да сложа още един флаг в Level, който в процесс да пита isThereElevator и ако има, да маха от себе си хора и да казва на асансьора да ги пълни? Поне това ми хрумна вчера. И същото с офисите, ако има асансьор и ако има пътници да слизат, да намали request-ите на офиса и да махне хора от асансьора. :?
Todo:
1. Да добавя повече цветове или форми на Person и Office обектите, за да махна текста, показващ къде искат да отидат.
2. Да добавя поне още 4-5 нива до края на срока.
3. Да направя заключени нива и само определен score отключва следващото.
4. Background и background анимация за всяко ниво (имам идея какви)
5. Още звуци
6. И други.. (приемам идеи)
Ще се радвам за мнение. Да ме поправите ако съм написал нещо тъпо. И за всякакъв вид друга помощ. За пръв път пиша нещо такова, така че доста се вълнувам и отдлено се уча в движение (ако забележите странни неща в кода).
Мисля да редактирам, този въпрос директно при следващите промени/въпроси, за да може първото, което излиза да е това и да се вижда какво направено и какво не. Така че може да няма нови постове отдолу, но ще редактирам този текст тук. Като запазвам старите неща, за да са свързани коментарите.
Поздрави,
Илиян
П.С. Повечето неща си ги рисувам аз :D
Щом е segmentation fault най-вероятно имаш pointer,който сочи към uninitialized memory и като играта го access-не става memory leak/undefined behavior.За да го оправиш опитай да изолираш по някакъв начин грешката,един вид да може да я предизвикваш всеки път.Ако успееш това,почваш да коментираш функции да видиш без коя крашва,.Ако крашва без нея значи проблема не е в нея.
Не виждаш никаква информация, защото нямаш дебъг символи.
Билдни си проекта за дебъг чрез CMake и повтори операцията с gdb.
Това ти е най-добрия ориентир, защото с gdb ще видиш точно кое ти гърми и ще можеш да разгледаш стойността на останалите променливи по време на crash-a.
Valgrind също може да ти помогне.
valgrind --leak-check=full --track-origins=yes ./myAppName
Готово, но #5 нагоре нищо не ми говори :?
Всичко тръгва от Text::setColor. Този метод приема само един параметър - референция към Color, която е трудно да бъде невалидна, но все пак прегледай дали в извикването на метода ползваш само предефинираните цветове. Виж също дали я трансформираш (до SDL_Color) и предаваш правилно към TTF_RenderText_Blended.
Друга вероятната причина за проблема е, този метод да е извикан върху неинициализиран обект, но от текста в грешката не изглежда да е така:
- става дума за текст "3", което най-вероятно е някой от бутоните в MenuButton
- TextContainer::reloadText е извикан от инициализиран обект: (this=0x555555951348, text=0x5555561468d0 "3", color=..., fontId=2, textId=10, outTextWidth=@0x555556146890: 23, outTextHeight=@0x555556146894: 41)
- Texture::createTextureFromText също изглежда да е получила валидни параметри: (text=0x5555561468d0 "3", color=..., font=0x55555607d200, outTexture=@0x555556137f20: 0x0, outTextWidth=@0x555556146890: 23, outTextHeight=@0x555556146894: 41)
Евентуален проблем може да има, ако паметта за textId=10 (т.е. outTexture=@0x555556137f20: 0x0) вече не принадлежи на приложението, т.е. била е освободена и този адрес вече е чужд.
Забелязвам, че в MenuButton::handleEvent викаш директно Text::setColor(Colors::WHITE); или Text::setColor(Colors::GRAY);
Това работи, но е доста странно като запис, особено като се има предвид, че този метод е няколко нива надолу в йерархията на наследяването на MenuButton. По-четимо ще е използването на this->setColor(...)