|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
|
Опции темы | Поиск в этой теме |
12.09.2012, 22:48 | #1 |
Пользователь
Регистрация: 06.09.2012
Сообщений: 14
|
Игра "Змейка" на Delphi
Здравствуйте, уважаемые форумчане, поздравляю Вас с прошедшим праздником!
Решил я тоже заняться программированием, написал несколько программ: прогноз погоды, парсер логинов, конвертер, редактор для работы с БД и т.д. Но подумал, что интереснее будет постигать азы программирования, если заняться геймдевом, решил написать игру "Змейка". Но тут у меня возникли небольшие проблемы. Движение головы змейки, еду - я написал, рост - наполовину, с ним у меня и проблемы. Дело в том, что когда змейка "съедает" еду, то создается shape с координатами головы, первый созданный сегмент двигается за головой, а остальные - остаются на месте первого сегмента и все, первый сегмент продолжает двигаться за головой, а другие - остаются на месте создания. Вот код движения (привожу обработчик только для кнопки вверх, остальные-аналогично): Код:
Код:
Код:
После съедания 1 "еды", все хорошо, сегмент двигается за головой: После того, как съедено еще 2 "еды": Кто подскажет, почему так получается? Весь проект вот: Простая змейка.rar Последний раз редактировалось Slin; 12.09.2012 в 22:50. |
13.09.2012, 07:36 | #2 |
personality
Старожил
Регистрация: 28.04.2009
Сообщений: 2,883
|
Такс.
Желательно такую тему постить сразу в раздел игр, если согласны, попросите модераторов о переносе. Написано неплохо для новичка. То, что Вы там до этого писали, я не считаю (ибо пока склонен думать, что писалось по урокам), а уровень кода тут говорит об уровне новичка. Похвально, что есть стремление заниматься программированием, могу только пожелать успеха, ну, а будет желание - могу учить, консультировать. Итак, код, во вложении пофиксеный файл модуля, мои исправления там по комментариям видно. Советую пробежаться в уме по коду и раскомментировывая код, смотреть последствия, чтобы понять, что и как. По реализации - змейка бегает сквозь себя, хотя, по идее должна либо "врезаться" в себя, либо менять хвост и голову(когда вытянута в длину) - могу посоветовать сделать обе эти вещи и менять способ в настройках. Также, еда появляется чисто рандомом, и бывает, что попадает в змейку - лучше исключить это дело, переписав генерацию еды корректнее. Ну, и критика. много критики. но во благое дело - сразу привить хороший кодстайл. 1. Кодстайл: именование - плохое, не надо писать транслитом, использовать сразу ёмкие, говорящие англ идентификаторы. Следить за форматированием кода. Писать говорящий код, либо , где просятся - комментарии. 2. Литералы - убирать в константы/поля всё, что можно (первые кандидаты - размер клетки 20, имена файлов, размеры поля в клетках и пикселях и т.п.) 3. Код - лапша, много копипасты, выделять больше кода по процедурам, выносить похожие вещи, разносить разные вещи. 4. Делить вообще на модель игры и на интерфейс. Пробовать уйти от контроло-зависимого кода, пробовать рисовать всё ручками, а не шейпами. Реогранизовать ход программы - начало игры написать так, чтобы оно работало также и для переигровки (сейчас длина сохраняется и т.п.), загрузку данных(рисунки) сделать динамическую. 5. Особняком (ибо, скорее к грамотности и расширяемости кода относится, а не кодстайлу) стоит слежение за временем жизни и областью видимости элементов кода - удаление созданных объектов, уменьшение числа глобальных переменных, повышение параметризации методов. Матчасть от GunSmoker (и его переводы) КодСтайл Комменты, Рефакторинг Многое из Разного На всякий случай Программирование Ну, и чисто от себя хочу посоветовать один из лучших курсов, из которого особое внимание советую уделить на ООП Курс Дельфи Последний раз редактировалось phomm; 13.09.2012 в 07:39. |
13.09.2012, 20:48 | #3 |
Пользователь
Регистрация: 06.09.2012
Сообщений: 14
|
Благодарю за ответ!
Вы правы, писал вначале по урокам, потом решил писать сам, а если не понятно или что-то не получалось - гугл помогал. Реализацией "врезания" я пока не занимался, т.к. змейки, как таковой, и не было- врезаться не во что. Про еду я думал, но как-то вылетело из головы- забыл. Надо исправить. Спасибо за критику, буду работать над собой и своим кодом. Отдельное спасибо за статьи, очень интересные и познавательные! Последний раз редактировалось Slin; 13.09.2012 в 22:08. |
13.09.2012, 22:12 | #4 |
Пользователь
Регистрация: 06.09.2012
Сообщений: 14
|
Реализовал "Врезания", теперь играть интересней стало.=)
Также улучшил читаемость кода, как Вы и советовали. phomm, не могли бы Вы помочь с генерацией еды? Написал код: Код:
И как можно "очистить" массив? Хочу очистить массив сегментов при проигрыше. Как Вы ранее заметили, при проигрыше и затем начале новой игры- длина змейки сохраняется, чтобы обнулить длину, думаю, необходимо "очистить" массив, так ли это? Последний раз редактировалось Slin; 13.09.2012 в 22:15. |
13.09.2012, 22:36 | #5 |
personality
Старожил
Регистрация: 28.04.2009
Сообщений: 2,883
|
Вызов Randomize надо делать один раз при запуске программы - обычно в Oncreate.
Перебор сегментов змейки сделать в цикле - и проверять, куда попало случайное число, при попадании в змейку заново генерировать и проверять в цикле, но это если в лоб, по уму надо просто "запомнить" все клетки где нет змейки , и сгененрировать по их количеству случайное число, и сопоставляя число клетке - поставить еду (алгоритм будет не ресурсоёмкий, в отличие от первого, но его посложнее написать). Очищать массив, конечно же, надо ( snake[i].free ), ну и саму переменную длины тоже. |
20.09.2012, 18:10 | #6 | ||
Пользователь
Регистрация: 06.09.2012
Сообщений: 14
|
Здравствуйте! Мне опять нужна Ваша помощь. Появилось свободное время и я опять занялся своим "грандиозным" проектом. Начал редактировать рандомную генерацию еды. Попробовал сначала так:
Цитата:
Цитата:
Добавил глобальную переменную: Код:
Процедура, в которой я провожу проверку: Код:
Код:
И вот еще одна менее значимая проблема: После того, как змейка съедает еду, происходит пересчет пустых (занятых) клеток на поле. И все время координаты последнего элемента ранвны 0;0 почему такое возможно? Вот обрезок кода: Код:
UPD: Смотрю я на свой скриншот и понимаю, что проверка поля на занятые клетки- криво как-то работает... UPD2: Хотя вроде бы хорошо работает.. только между головой и первым сегментом разница не в 20, а в 40, по Y... странно, код тот же самый.. UPD3: Вообще непонятки какие-то: если змейка горизонтально, то различается по X на 40, а если змейка вертикально, то различается по Y на 40. UPD4: Оказывается, это почему-то первый сегмент после головы пропускается => отсюда и разница в 40 pxl... P.s: думается мне, что таких UPD будет много...=) Последний раз редактировалось Slin; 20.09.2012 в 21:29. |
||
20.09.2012, 22:05 | #7 |
personality
Старожил
Регистрация: 28.04.2009
Сообщений: 2,883
|
Да я заметил , что количество записей не соответствует числу сегментов, отсюда и непонятки - думаю просчеты в циклах, и последний элемент читается из незанятой памяти, потому и 0. для случаев на скрине, для 4 вертикальных сегментов - только 2 записи (по коордам видно) - отсюда и предполагаю что по циклам не срастается.
Ну и киньте опять же архивчиком проект, завтра с утра по-бырику разберу, что там с едой. Ну и опять же замечания насчет лапши - сами же запутываетесь. Надо бы улучшать технику и стиль кодирования, статьи же читаете, думаю, давайте уже применяйте )) |
20.09.2012, 22:41 | #8 |
Пользователь
Регистрация: 06.09.2012
Сообщений: 14
|
Вот проект:Змейка.rar.
Посмотрите, пожалуйста!) |
21.09.2012, 07:09 | #9 |
personality
Старожил
Регистрация: 28.04.2009
Сообщений: 2,883
|
Я недоволен, что за неделю не поступили исправления, код почти не отличается по грамотности от первого варианта. Много ошибок чисто по невнимательности, которые как раз и исключаются грамотным стилем программирования !
1. массивы гуляют по индексам - объявлено одно, в некоторых циклах другое, в иных даже третье (1..22, 0..22, 0..21), такая свистопляска только чудом не приводит к порче памяти. Во избежание лучше включить опцию компилятора Range checking (Project-Options-Compiler-Range checking), либо сразу, руководствуясь хорошим стилем, объявить 4 (или 2 - в случае только квадратного поля) константы - начала диапазона и конца диапазона (конец диапазона также можно в определённом смысле считать размером поля) и везде использовать только их - так не будет мешанины чисел. 2. Гуляют переменные-индексаторы массива - то [j,i] то [i,j] - применяя хороший стиль, поименовав их Col, Row - не запутаетесь, правда, попутно надо принять единую нотацию в проекте, что первое измерение массива - только для колонок, или только для строк. В код особо не вчитывался, но смесь всяких х, хх, х_х опять же чревата, лучше повнятнее каждую описать, чтобы код читался почти как текст. Да и единую нумерацию массивов принять - с 1 или с 0 (советую с 0), особенно учитывая, что везде происходит работа с индексами, и не отслеживается валидность - например тот же random(19)*20 выдаёт число от 0*20 до 18*20 и может быть 0, а массив по объявлению - от 1. 3. Прописаны, но не задействованы константы - конкретно числа типа 20 и 440 - советую поменять везде, хотя на данном этапе они не приводят к ошибкам, но чуть что и код поплывёт, будете рыскать при дебаге что и где сыпется. 4. Хотя и не ожидаю от Вас чудес, но напомню, что 4 метода и кой-какой ещё код дублирующийся можно свернуть в единые методы, параметризуя специфику (например, через параметр и case в коде) - таким образом, будете избегать проблем - менять 4 метода, с нехилой возможностью где-то ошибиться в каком-нибудь минусе при каждом мелком изменении, а иметь всего 1 метод, который отдебажил и забыл. 5. Опять же, не жду сразу, но советую уже обращать внимание на разделение работы логики и визуализации, и делать шаги в эту сторону. Алгоритмизация грамотного рандома не понята до конца - советую расписать на бумаге, чтобы внести ясность, а не сидеть над кодом пытаясь разными костылями подпереть в надежде, что заработает. Конкретно можно указать на то, что сделаны вложенные циклы, хотя сами top left можно сразу использовать для индексов в массиве, без этих циклов. Однако , оговорюсь - использовать внешние по отношению к алгоритму данные (а именно положение шейпов) - неправильно, лучше иметь собственные данные, в какой клетке есть сегмент змейки с каким номером, но такие изменения позже лучше делать, когда уже будет понимание. Однако, "сложный" алгоритм вообще исключает необходимость перегенерации - это Вы упустили из виду (полагая, что Вы делаете другой, на самом деле Вы просто поменяли реализацию алгоритма "в лоб"). Я потом, после всех исправлений от Вас распишу, как оно логически должно быть построено. Основываясь на текущем коде я бы написал что-то такое, вместо реализации текущей pole_r (тут я, правда, не слежу за индексами, Вам надо сперва принять во всем коде едино и потом уже выверять индексы) : Код:
Последний раз редактировалось phomm; 21.09.2012 в 07:23. |
21.09.2012, 18:16 | #10 |
Пользователь
Регистрация: 06.09.2012
Сообщений: 14
|
Здравствуйте! Спасибо еще раз за критику, проект я доделал, теперь все работает.
Еще спасибо за Ваш "пинок под зад": я пробежался по коду, объединил копипаст, который можно в отдельную процедуру засунуть, изменил названия процедур, почистил неиспользуемые переменные, прокомментировал код, правда только кое-где, начал использовать константы, таким образом код стал меньше более чем на 100 строк. Вы мне указывали на все это, верно?))) Или я до сих пор чего-то не понимаю?) Если я не понимаю, то прошу еще один пинок. Вот проект: Snake.rar Так же, я планирую поработать над интерфейсом и добавить разных бонусов в игру. Последний раз редактировалось Slin; 22.09.2012 в 11:06. |
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Игра "Змейка" на 2 персоны | [Dethklok] | Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM | 1 | 07.06.2011 14:24 |
Assembler.Игра "змейка". | Пупкин | Помощь студентам | 0 | 27.05.2010 00:08 |
Игра "Змейка" | program123 | Общие вопросы Delphi | 2 | 08.03.2009 23:49 |
Игра "Змейка" | spamer | Общие вопросы Delphi | 1 | 09.01.2009 04:22 |
Ещё одна игра "Змейка" | Simply-Art | Софт | 17 | 05.07.2007 04:10 |