25 июля 2010

Поиск багов.


Баг (bug) - слово, которым программисты поясняют, что с программой что-то не так. Найти баг в чужой программе - это просто праздник, ты сразу чувствуешь себя настоящим гуру, способным перехитрить создателя программы, не предусмотревшего особое состояние, в которое удалось ввести программу. Найти баг в своей собственной программе - это беда. Как будто твое собственное детище делает тебе вызов, как будто оно живое и протестует против издевательств с твоей стороны. Но ничего, берешь себя в руки, запасаешься deBUGger'ом, и вперед, в потайные лазы методов и функций, внутри которых кроется ошибка, приводящая к странным и порой необъяснимым последствиям.
Сегодня я расскажу про пару багов, которые я ловил недавно в срочном порядке, и из-за которых у меня чуточку болела голова, стараясь выявить и уничтожить их как можно скорее. Первый баг был связан с безумно странным поведением некоторых физических объектов, второй - с прекращением отрисовки сцены при переходе между оконным/полноэкранном режимами.

Итак, первый баг заключался в сложности его отлавливания. Дело в том, что оба компьютера, на которых производятся основные тесты, напрочь отказывались воспроизводить ошибку. Также осложняли дело фразы, которые поступали от людей, у которых проявился баг. Что-то вроде "шарик выкатывается". Вся штука в том, что это следствие, по которому мне было чертовски сложно сказать что-то конкретное. Но потом мне повезло, и FA~SHISH прислал мне набор последовательных скриншотов экрана игры. Все стало сразу на свои места. Дело в том, что я не меняю разрешение монитора в игре в принципе. На мой взгляд так картинка выглядит наиболее приятно. Из-за этого приходится масштабировать сцену, чтобы все необходимые физические объект влезали на экран. В общем, причина бага была в том, что оба монитора компьютеров, на которых я тестировал сам - широкоформатные. Из-за этого игровой уровень быстрее "упирался" по высоте в размеры экрана и масштабировался по высоте так, чтобы он полностью влезал на экран именно по этой оси. Но на неширокорфатных мониторах игровой уровень быстрее "уперся" в края экрана по ширине, и масштабировался уже исходя из отношения ширины игрового уровня к ширине экрана. (Уфф... не знаю, как можно яснее объяснить...) Так вот у двух уровней я неверно указал ширину игровой области, из-за этого на мониторах, где уровень упирался по ширине, некоторые объект выходили за пределы экрана (я указал меньшую ширину, чем она была на самом деле, и весь уровень промасштабировался до этой, маленькой, величины). Я же этот баг не мог отследить у себя, так как на моем мониторе масштабирование происходило по другой оси. Баг дурацкий, согласен. Но зато я сделал Light-версию игры с одним уровнем, без Splash'ей, настроек, профилей и другого. Только один игровой уровень. Думаю, еще пригодится.

Второй баг оказался интереснее. Итак, все началось с того, что я не сделал опцию "Полноэкранный режим" стартово в "Настройках" игры. Почему? Не знаю, может быть лень, а может быть на тот момент я не знал, как лучше реализовать эту опцию. Так или иначе, её не было довольно продолжительное время, но тут я решил: опции быть! И начал делать. Сначала все шло хорошо, нарисовали картинку, вставили в игру, я отработал нажатие, чуть переделал логику применения опций (теперь применяются при выходе из подменю в главное меню, а не сразу по нажатии, как было раньше). Все сделал - все работает: был полноэкранник, убрал галочку, нажал "В Меню" и вуаля - уже все отображается в окошке. Потом на ночь глядя я добавил еще изменение BorderStyle (чтобы в полноэкранном режиме не было рамки), не стал компилировать (свойство-то тривиальное) и лёг спать. На следующий день, когда уже что-то поменял в проекте, перекомпилировал и случайно нажал опцию я ахнул - на экране было чёрти что, а не игра. Промучившись долгое время я пришел к выводу о несовместимости изменения BorderStyle формы и рендера GlScene.
Я даже завел тему, чтобы локализовать ошибку и понять природу бага.
В итоге (тру-ля-ля), на следующий день я победил досадный баг! Здорово помог С4, который скинул мне свою версию скомпилированного им на новой версии Delphi моего проекта. Все работало на ура и я быстро увидел отличие - в моем ехе, при смене BorderStyle происходит перемаргивание окошка - как будто оно создается заново. Это меня натолкнуло на мысль, что слишком много всяких вещей затрагивается при смене этого свойства. В итоге, сделал все "по-старинке" через прямое обращение к WS_Border и WS_Caption. Работает!

В общем, присутствие багов неизбежно, когда проект делается продолжительное время, когда очень долго ковыряешься в каком-то элементе, не тестируя постоянно весь функционал игры. Отсюда мораль: чем больше людей тестируют программу, чем на большем количестве разнообразного железа пробовали запускать игру, тем быстрее можно отловить баги и тем меньше проблем будет в конечном итоге.

Сообщения, схожие по тематике:

0 коммент.:

Отправить комментарий