|
Уроки по созданию игр для новичков...
В этом уроке я научу вас как можно передвигать обьекты по форме с помощью клавиш...
-------------------------- Начнём. 1)Создайте новый проект File> New> Application 2)Теперь киньте на форму объект TShape 3)После этого выбираем в Object TreeView форму (Form1) 4)В Object inspector на вкладке Events ищем свойство OnKeyDown и щёлкаем на него 2 раза. 5)В созданной процедуре пишем код (я рекомендую вам не просто копировать а понять как это работает!) Цитата:
--------------------------- Попробуйте сами написать движение вниз, вправо, влево... Позже и это будет показано! |
Урок #2 Двигаем фигуру как хотим!!!
Добавьте в свою программу этот код и ваша фигура будет двигаться по всей форме! Цитата:
|
Урок №3
-------------------- Как вы уже поняли фигура может двигаться куда попало...даже за пределы формы... а это не очень то и хорошо =)... Давайте вместе напишем код который будет ограничевать движение фигуры влево и вправо... --------------------- Попробуйте написать вашу программу вот так: Код:
unit Unit1; и уже TShape не будет убегать за границы формы! Но будет двигаться только влево и вправо...попробуйте сделать самостоятельно так чтобы TShape не выходил за границы формы сверху и снизу + самостоятельно разберите код...возникнут вопросы задавайте их в этой теме... --------------------- |
Вопросы по уроку №3
Сначала хотелось бы сказать спасибо модератору за эту тему т.к. лично мне она очень помогает. =)
Теперь, собственно, к вопросам.() 1. Я не понял смысла этого кода, можешь объяснить?. У меня по оси x объект стал двигаться быстрее, а когда начинал выходить за пределы формы двигался с обычной скоростью. Не надо ли вставить что-то подобное ,чтобы он не мог выйти за пределы формы: Код:
if (Key=VK_RIGHT) and (Shape1.Left+Shape1.Width)>=Form1.ClientWidth Код:
if (key=VK_UP) and (Shape1.Top>=0) 2. Можно по-подробнее о событии OnKeyDown ? В частности что за параметры передаются переменными Key, Shift? |
Key - код клавиши, UNICOD вроде передаётся.
Shift - передаётся состояние клавишь Shift, Alt, Ctrl (нажаты или нет) Нажми f1 (справка в делфе) и введи OnKeyDown,TWinControl там полностью описание есть + есть ссылка Virtual Key codes - там тоже много полезного. |
немного усложнив эту конструкцию становится интереснее ;)
Код:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; таймер для избежания падения фокуса на какой-нить из контролов, потом стрелочка ваша ездить не будет. в конечном итоге ваша стрелочка будет бегать по клеточному полю и принажатии на пробел будет закрашивать клеточки цветом. ах да! на форму кинуть панель а на неё paintbox не забудте и image -- ваша стрелочка! зы-Shift это прежде всего множество из (ssShift, ssAlt, ssCtrl, ssLeft, ssRight, ssMiddle, ssDouble), обращаться надо к ним через квадратные скобочки -- if shift = [ssShift] then ... if shift = [ssShift,ssAlt] then... пробуй :) |
У меня назрел такой вопрос: при движении объекта с помощью клавиш появляется такой эффект, что, когда я зажимаю кнопку (например стрелочку), то объект сдвинется на n пикселов (где n это шаг, который задаётся заранее), затем остановится на, приблезительно, 0.5 с, а потом начинает нормально двигаться. Разумеется в игре такое движение неприемлемо, и хотелось бы знать как это устранить.
И второй вопрос заключается в том, что двигается объект слишком отрывисто (я предполагаю, что это из-за медленного действия компьютера, несмотря на то, что у меня очень мощная машина). Хотелось бы узнать, как сделать движение более плавным. |
причина задержки скорее всего в настройках винды (есть иакой параметр - сколько времени держиться клавиша зажатой прежде чем применить к ней залипание) Выход я вижу в том что бы отключить опцию в настройках виндовс (скорее всего через реестр), а по выходу из игры снова включать. Или создать обработчик OnKeyDown, который приводит логическую переменную движения в соответствуующую сторону в True и OnKeyUp - все переменные движения в False, а движения обрабатывать в таймере.
А торможением возможно называешь мерцание объекта, если да попробуй использоватьпараметр Form1.AlphaBlend:=True; |
Цитата:
Посмотри там последний пост, мож подойдет... |
Цитата:
Далее назрел вопрос. Как сделать, чтобы можно было вставить в программу какой-то код (не в процедуры, которые находятся в модуле). Например, я сделал пятнашки и нужно, чтобы условие победы отслеживалось не при каком-то событии, а постоянно.:confused: |
Цитата:
|
У меня может быть огромное кол-во различных событий, которые приводят к победе, при этом в случае победы реализуется большой механизм. Это получается, что мне в каждую процедуру надо вствить один и тот же код? Даже если оформить это все в отдельную процедуру и вставлять только её название, но если событий более ста?
|
Значит перемудрил :)
|
Исходник Пятняшек!
Вложений: 1
2Yogurt:
Попробую, вам уважаемый помочь! Представив вам разсосанный сорец пятнашек! :) Назовём это урок №4 для начинающего! Код:
{ Игра "15"} |
Вложений: 1
Урок № 5
Отдельный класс игрушек прадставлен, так называемыми игрушками на развитие памяти! Вот попробуем написать одну из таких! Что она будет делать!? А практически ни чего особенно сложно, просто запускаем прогу она на секунду показывает число, а потом число пропадает и появляется окно для ввода числа, там мы его по памяти вводим и если мы правильно ввели, то показывается следующее, а если неправильно, то следующее число будет показано после звукового сигнала об ошибке! Вот откоментированный исходник игры а ниже архив с исходником! Код:
unit memory_; |
Вложений: 1
Урок №6!
Теперь попробуем написать игрушку развивающую реакцию! Суть её заключается в следующем, на экране появляются смайлики и на м нужно успавать по ним кликать курсором! В конце выдаётся результат о попаданиях и промахах! Вот откоментированный исходник игры "Тир": Код:
unit tir_; |
Морской бой
Вложений: 1
Урок №7
Практчески любой и каждый уважающий себя человек в своей жизни хотя бы раз играл в эту занимательную стратегическую игрушку - Морской бой! Исходник не такой простой, как в предыдущих примерах, но и не сложный, разобраться при желании можно! При желании вы можете дороботать игру добавив новые стили игры (их существует огромное множество)! Можно доработать стратегию компа! А можно просто оптимизировать (а скорей адаптировать) интерфейс под себя! Игра в принципе работает, но компьютер довольно просто рвёт!... :) |
Вложений: 3
Урок №8
Немного теории по особенностям создания игр разных жанров! Anim_Games.rar - Анимация в компьютерных играх; Arcade_Games.rar - Аркадные игры; Prikluch_Games.rar - Приключеньческие игры. |
Вложений: 1
Урок №9
А вот исходник более серьёзной и весьма увлекательной игрухи! Игра называется "Линии"! Цель игры методом передвиженя кружков необходимо поставить в ряд 4 и более кружка одного цвета, при этом они исчезают! При каждом ходе появляется несколько новых кружков. Игра заканчивается когда заканчивается место на игровом поле! Что бы передвинуть кружок, надо по нему щёлкнуть, а потом щёлкнуть по месту назначения, но при том условии что кружок сможет доехать до места назначения не перепрыгивая (хотя можно обходить) через другие кружки! В общем кому интересно разберитесь с исходником, он там не сложный, а кому не очень это интересно, советую поиграть!!! :) |
Вложений: 1
Урок №10
Вот пример того как можно работать с возможностями 3D в Delphi! Простенький мануальнчик с примером исходника! |
Цитата:
|
Вложений: 1
Урок №11
Вот исходник программы работы с 3D объектом, его можно вращать, и изменять его размер! |
Урок №12
Что такое OpenGL? В этом уроке мы поговорим о том, что вообще такое OpenGL, для чего это нужно. Для начала, вы должны неплохо знать ОС Windows, а также язык Си++ (в данном случае, Visual C++, так как мы будем работать именно в этой среде разработки). Итак, OpenGL (Открытая Графическая Библиотека) - это программный интерфейс (API) для разработки приложений с использованием 2D и 3D графики. OpenGL стоит как бы между аппаратным обеспечением, и пользовательским уровнем. Основные особенности этой библиотеки являються: Стабильность: Это означает, что дополнение в OpenGL реализуется так, что бы сохранить совместимость с более старым программным обеспечением. Переносимость (независимость): Код программы, которую вы написали, скажем, под Windows, можно легко перенести на Linux и другие ОС. То есть, OpenGL не зависит от какой ни будь операционной системы, как, например DirectX. Простота в использовании: Приложения, написанные с помощью OpenGL, имеют сравнительно небольшой объем кода. Также эта библиотека имеет понятный интерфейс. И разобраться в коде программы очень просто. Ну и наконец OpenGL это отраслевой стандарт, т.е. вы можете взять исходники и сделать на их юызе что-нибудь своё. Основные возможности OpenGL: · Набор базовых примитивов: точки, линии, многоугольники и т.п. · Видовые и координатные преобразования · Удаление невидимых линий и поверхностей (z-буфер) · Использование сплайнов для построения линий и поверхностей · Наложение текстуры и применение освещения · Добавление специальных эффектов: тумана, изменение прозрачности, смешивание цветов (blending), устранение ступенчатости (anti-aliasing). Я думаю, что всех этих достоинств достаточно для того, чтобы выбрать OpenGL для создания 3D графики (игр, в частности). |
Урок №13
Основные термины и понятия компьютерной графики. Рендеринг- это процесс подготовки, выдачи (прорисовки) изображения на экран. В общем, это все действия, которые связаны с выдачей картинки на экран. Буфер- это область для временного хранения данных. Двойная буферизация- это один из способов рендеринга, при котором существует два буфера. Содержимое первого (переднего) буфера (front buffer) показываеться на экран и вы видите какое то изображение. В это время на заднем буфере (back buffer) подготавливается следующий кадр (рисуется). Когда кадр на заднем буфере готов, тогда передний и задний буфер меняются местами. И затем все это повторяется. С помощью такой технологии избегается мерцание экрана. Пиксель- это наименьшая точка, которую можно различить на экране. Он является единицей двухмерного изображения. Камера- это не то, что вы подумали… :) Камера- это место, из которого вы смотрите на экран. Трансформация- нахождение координат точки в заданной системе координат, используя координаты точки в другой системе (это переносы, или вращения). При трансформации положение точки не меняется. Мировая система координат- это система координат, которая считается неподвижной. Обычно относительно этой системы координат задаются положение камеры, и объектов. Примитив- это основная единица, из которой строятся сложные объекты. Примитивом может быть: точка, линия, треугольник, или что ни будь подобное… Z-buffer- также часто вместо этого слова употребляется слово Буфер Глубины (Depth Buffer). Это буфер величиной с экран, в котором хранятся Z координаты пикселей. Z-ось добавляет третью величину- глубину. Матрица- в компьютерной графике, это массив чисел (обычно 4х4), который содержит значения векторов систем координат. Проекция- это перевод координат из пространства (камеры) на экран, или с 3х мерных координат в 2х мерные. |
Вложений: 1
Урок 15
Интересный пример по проецированию курсора мыши на 3-х мерную поверхность! Данный пример будет интересен как новичкам, так и профессионалам. |
Вложений: 1
Урок №16
Данный исходник программы для игры в Русские шашки! Причем соперник имеет достаточно высокий интелект! :) |
Что за нах???
Я пытаюсь сделать арканоид, уже прописал физику мяча, но не могу теперь описать движение платформы.
записал всё как в вашем первом уроке в том же юните, и ничего не происходит. З.Ы: в чистом юните всё работает. Памагити!!! Цитата:
|
Вложений: 1
Остальное сам допишешь
|
ПАСИИИИБ!!!!!!!!!!!!!
|
ну а
ну а с моей то что?
|
люди, да что с вами, при всём желании у вас не получится создать более или менее нормальную игру используя VCL, идеальный вариат - это DirectDraw, но для некоторых он может показаться сложным, для 2D игр есть альтернатива, для начала учите WinApi, затем создаете форму сами(то есть пишете всё ручками) при этом у вас не будет ненужных бордеров и в полноэкранном режипе панель задач не будет вам мешать, затем создаёте переменные в которые вы будете грузить картинки, и пользуемся функцией BitBlt() для копирования фрагментов изображений, при этом у вас не будет ни остановок ни мерцания (если вы создаёте "оконную" игру форму сами можете не писать, но вот размер вашего приложения будет о-го-го какой)
|
Horny, я с вами полностью согласен насчет создания игр с помощью средств DX, но для начинающих игроделов очень тяжело сразу взять и начать писать своё детище на DX, я веду к тому, что следует начинать с простого и постепенно двигаться к большему.
|
Тоже согласен с комрадом Kostia, ...начинается все с элементарного Image, затем переход на Canvas (буферизация, вставка Bitmap), затем Win API (GDI), а уже к концу DirectX, вершина - ассемблер. Почему так? , ...потому, что нужно пройти весь путь, только тогда можно понять принципы и выбрать методы для решения конкретной задачи. Иногда можно обойтись и приметивными методами, если они удовлетворяют условию.
|
А где же OpenGL? Ей нет места в вашей иерархии? :)
Да, и мне кажется не стоит путать понятия создание игр и создание графических библиотек. Какое имеет отношение ассемблер к созданию игр??? |
Цитата:
Цитата:
|
Подскажите плз как сделать так, чтобы при нажатии на форму персонаж шел туда куда было нажато))???
|
Есть событие OnMouseUp в нем переменные х и у в которые передаются координаты мыши. Соответственно туда и перемещаеш своего персонажа...
|
Спс нада будет попробывать :):):)
|
Подскажите как обрабатывать сразу несколько клавишь, вот например в аркаде, надо одновременно жать W и D (вперёд и вправо). Как это реализовать?
|
Цитата:
if button = mbleft then shape1.Left:=x; shape1.Top:=y; или нужно воспользоваться таймером? если да то как?:confused: :confused: :confused: |
Цитата:
Код:
var |
Вложений: 1
Pfent, вот примерчик. Все грубо, установи смещение на картинку и будет идти туда куда ткнул мышью.
|
Огромное спасибо за пример :):):)
|
Пользоваться таймером. там прописать что то типа если координата х больше левфт то лефт=лефт+1.... то же самое с у, кроме того может быть такое что добавлять надо не единицу... можно попробовать реализовать это через уравнение прямой...
|
Вот вам в качестве урока по созданию логических игр (это не РПГ =).
Исходник игры кликомания (коллапс) на Дельфи. http://www.programmersforum.ru/attac...4&d=1196863119 |
Всем приветик=) Помогите произошел клинический ступор=) Гляньте свежим взглядом....=) Cуть задачи такова: кнопка при нажатии двигается вправо до ходя до края формы а после ползет в лево.
Procedure TForm1. для нажатия... begin if Button1.Left>600 then Button1.left:=Button1.left-5 else if Button1.left<600 then Button1.left:=Button1.left+5 else Button1.left:=Button1.left+5 end; end. Сама вижу что даю условие до 600 она доползает и начинает дергаться то +5 то _5. Тут как-то может нужно вести переменную и менять ей знак? |
Просто введи переменную булевского типа заначение фалз, если достигнут предел движени вправо изменить на тру если значение тру двигать влево при достижени крайнего левого пложение опять изминить значение на фалз...
|
Еще можешь сделать переменную Speed: integer; определяющую скорость, т.е. на сколько пикселей за раз перемещается кнопка.
При достижении стенок меняешь знак скорости +/- if (Button1.Left>600)or(Button1.left<0 ) then Speed:=0-Speed; Потом в любом случае прибавляешь эту скорость Button1.left:=Button1.left+Speed; |
Тут уже рассматривался пример движения оъекта при нажатии на кнопки с клавиатуры, а если одновременно нажаты влево и вверх?
или пользователь пользуется "перекатом"(не отпуская жмет на другую кнопку. а потом первую отпускает) |
Еще один вопрос.Как клонировать обьект
Допустим стратегия. Нужно построить дом. Допустим это Image. Как сделать так чтоб создавался image в определенной области формы (любое количество, сколько вздумается пользователю) с соответствующим изображением здания И к этому image относились бы все процедуры заранее оговоренные для данного типа сооружения Например при двойном нажатии активировлась какая-то панель или что-то вроде этого. |
Лучше создавать собственный класс...
Можно компонент. Разницы в принципе нет. |
А по подробнее...
|
Поворот
Стоп, стоп, стоп!
Лубышев, про клоны Image забудьте раз и на всегда. Пример был дан для демонстрации, применим в аркаде, квесте, может в РПГ от части, все в любительском режиме, но никак не для стратегий. Вообще, сначала стоит подумать о ресурсоемкости игры, если проба своих сил можете попробовать клон, но не советую. В основе простейшей 2D игры - один объект отображения графики. Начните с того, что создайте Image, назовите его Screen, растяните на размер формы или как угодно, и с помошью Canvas можете делать клоны чего-угодно куда-угодно в эиот Screen. Почему Canvas? 1. Топик говорит сам за себя, проще канвы нет ничего. 2. Для стратегии Canvas подойдет в виду статичности объектов. Заинтересовались? спрашивайте... |
Цитата:
Назови их например LeftPressed, UpPressed ну и дальше в таком роде. Это будут флаги обозначающие нажата данная клавиша или нет. При запуске они изначально все будут false (как и все глобальные boolean если их не инициализировать). Нам это подходит, так что пока их не трогаем. Теперь пишем обработчики событий нажатия клавиши и отпускания. OnKeyDown и OnKeyUp. Код:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; |
mutabor спасибо! Я так думаю уроки и надо было с этого начинать. Чтож за такая игра, когда нельзя одновременно нажать на две кнопки.
Что-то тело как то непонятно движеться, что-то не то я делаю. а есть готовый рабочий пример? Beermonza, не могли бы вы расказать более подробно об том, что вы говорили? могли бы вы дать маленький примерчик, чтобы я все понял. |
Подробно
Начните с главного.
- Стратегия - это игра с действиями на карте; - Карта - это клетки с объектами на них; - Информационный скелет карты - двумерный массив. Начинайте создавать игру со "скелета" карты (анализ ПО, сбор данных, типизация, ТЗ и пр. предшествующие пункты плана создания игры вы уже должны были проделать). Тип массива может быть выбран совершенно любым, ...вы должны обдумать каким образом можно представить данные, отвечающие за тот или иной объект. Допустим, вы решили представлять некоторый объект (например, дом) числом, то массив у вас будет Word типа, поскольку видов объектов в стратегиях большое множество. Но, вам совершенно не удобно использовать такой код. Попробуете сделать таблицу на все 65536 значений, где за каждым числом закреплен рисунок? ...врятли!, ...да и тип Byte, вам тоже не подходит. Что же делать? Давайте вспомним, что каждая ячейка массива может быть не только вместилищем одного типа данных, но и массивом записей или объектов, которые мы можем сами прописать, и указать нужный их тип. Вот так можно представить упрощенный массив объектов, для простой демонстрации: Код:
Type Код:
Var Код:
GameMapMas[j,i].TGOBitmap:={указатель на картинку, массив текстур}; Отображение объектов игры через Canvas Как применить Canvac вы уже наверное знаете, но тем не мение, уточню. У нас есть экран игры Screen - это объект Image, есть скелет карты - массив GameMapMas, нужно их совместить вот такой строкой: Код:
Screen.Canvas.Draw((j*MX)-GameMapMas[j,i].TGODispX, Это только одна сторона медали, также серьезно следует взяться за задний план карты - это поверхность, как ее нужно отображать, и что она из себя представляет? ...может это просто фон одного цвета, а может и мозаика из разных кусочков - тип грунта и пр. Прежде чем что-то рисовать канвой, следует вернуть назад участок заднего плана, как это будет происходит, зависит от вашего выбора. |
Цитата:
array of array of word + TImageList TImageList.Draw(canvas,x,y,map[mapx,mapy]); |
Цитата:
Для начала можно попробовать и просто картинку, ...только это будет графический редактор, или что-то в роде одноразовой аппликации. Все равно придется думать над хранением других данных, кроме картинки, и при том с как можно простым алгоритмом параллельного использования. Советую отказаться от использования объектов, если в них нет нужды, ...ведь нам нужен сам факт хранения картинок в ОЗУ, давайте делать это напрямую в массив, и выводить рисунок из памяти сразу в объект отображения без посредников. Обратите внимание на то, что в цикле прорисовки кадров в скором времени, когда игра будет совершенствоваться, появится множество процедур, ...тут идет борьба за каждую команду, за правильность выполнения последовательности, ...мы должны будем даже отказаться от привычного умножения (*) и деления (/), заменив их сдвигами. |
Цитата:
конечно, если не делать сдвиги ради самих сдвигов :) p.s. TImageList выводит графику довольно быстро, для учебных целей хватит с головой, а по своей сути он оболочка к системному имиджлисту. Свои объекты работают не намного быстрее стандартных, вообще ООП это тормоз, от него тоже нужно отказываться если нужна сверхскорость. |
Не буду спорить, ...начинающие выберут метод по легче, если он их устраивает. Давайте не будем ссылаться на две библиотеки :), ...и без них можно обходиться и довольно быстро все отрисовывать.
|
у меня все еще сохранилась проблема при нажатии на две кнопки одновременно... что делать?
|
Ответ прост использовать флаги в памяти. если нажата кнопка вверх один флаг становиться true, если нажата кнопка влево, проверяем все флаги и если верхний флаг true выполняем другое действие.
|
мне это уже обьясняли, но видемо, что-то не так делаю. Дайте готовый пример.
|
Пример мультиопроса клавиатуры
Вложений: 1
Лубышев, вот этот самый пример, как и ранее описанный. Мы меняем значения флагов (переменные типа Boolean), в зависимости от нажатия клавиш, это прописывается в OnKeyDown и OnKeyUp фомы. Флаги после этого можно использовать как угодно, я создал процедуру, где изменяю цвет букв нарисованных клавиш.
|
Я бы написал функцию которая проверяла нажата клавиша с номером key или нет:
Код:
function keypressed(key: byte): boolean; 37- right 40- down 38- up 13-enter 27-esc ... Например if keypressed(27) then form1.close; |
Делаем Пазл
Вложений: 1
Один из вариантов как можно сделать игру пазл.
Исходник с комментариями, читайте там. Версия 0.1 (работает еще не все) В следующей доделаю, а еще в следующей глянец наведу. |
А есть какая нить литература по созданию игр на Delphi?
|
Цитата:
Вопрос на засыпку: Где можно достать рецепт приготовления борща в эмалированной кастрюле? Может отличаться реализация графики: GDI, OpenGL, DirectX. Если использовать борландовскую VCL, то это будет GDI графика, но это не обязательлно может быть только Дельфи, C++ Билдер также использует VCL. Короче говоря проще найти отдельно литературу по игровым алгоритмам, нужному языку и графической библиотеке. |
Здравствуйте, у меня вопрос насчет 2D движков для делфи, кто нить что то подобное встречал? Еще интересно что именно должен содержать движок и в каком виде все это представлено? Предположим я знаю как создать систему боя, магазины и большинство основных элементов в игре, но делать из этого игру не хочется, т.к. например продолжение придется писать с нуля, легче написать движок подгрузив в него графику, сюжет...понимаю что это гараздо сложнее, но если понять принцип, возможно что то получится.
|
Цитата:
Цитата:
Цитата:
Дальше не совсем понял. Графический 2D движок это одно, а конструктор игр это другое. А свой собственный игровой движок-заготовка, в к-ром пол игры уже написано, это третье. |
Урок xxx
Самая главная ошибка первых Русских разработчик, это то что они не убирали за собой мусор, что приводило к понижению производительности игры и к ее зависанию. Не поленитесь очистить память от мусора. Память нужно чистить после завершения уровня, при переходе в другую локацию и при завершении программы. Простой пример Bitmap.free; Bitmap:=nil; |
А что разве когда програма закрывается то оно все само не уничтожается?
Все компоненты находятся на форме, нет формы, нет компонентов, зачем чистить. |
Вам рано или поздно придется работать с переменными, хранящими в себе большие области данных, например TBitmap, после завершения работы программа удалит переменную, но не данные в ОЗУ, на которые она ссылается.
|
А помоему Delphi за собой убирает. Это если самому память выделять, то тогда самому и чистить, а если средствами Delphi то она сама освободит. Освобождение памяти после себя это одно из достоинств Delphi (и некоторых других языков) и один из недостатков например C++.
Вобщем от языка зависит и от того как память выделяется. |
Цитата:
|
Когда я делал Аканоида, я не освобождал устройство и после запусков 15-20 игры, вся виндозовская GDI полетела: на рабочем столе иконки не отображались, в папках вместо иконок муть разная была, не отображались элементы пуска и т.д. А не освобождение поверхностей с картинками вызывало тормоза в игре и др. играх и решить эту проблему можно было только перезагрузкой компьютера.
Теперь освобождение ресурсов у меня на первом месте. |
Друзя помогите..........
:confused: :confused: :confused: Нужна помощ в созд прогр "Сквош"
дана задача : написать Игру: на игровом поле есть панель, что управляется мышей или клавиатурой. Шарик перемещается по полю отталк от стенок и панели. Задача игрока отбить шарик мах количество раз. Требования: Нужны функцииї: 1) подсчет баллов; 2) подсчет количества попыток; 3) сохранение результата таблица результатов; :confused: .... плизззззззззз.......... |
С такими просьбами во фриланс.
|
Подскажите,пожалуйста, как мне реализовать постоянное движение обьекта через Timer1. Допустим пользователь ввел с клавиатуры "up"
обьект непрерывно двигается вверх, соответственно "down" вниз и тд. |
Цитата:
|
Цитата:
|
anton14 может будут уточнения к вопросу? Если ищется алгоритм перемещения типа Пакмэна, то OnKeyUp уже применять не нужно, а OnKeyDown несколько модифицируется. Именно это прослеживается в вопросе.
|
я еще не делал игр с движением, поэтому не знаю: стоит ли выводить на канву формы? или сразу надо учить, например опенгль. при рисовании по канве возникает мерцание... В общем что перспективнее: простота канвы или красота более профессиональных библиотек. И подскажите если стоит чего - учить, то что.
|
Не путай библиотеки с умением делать игры. Библиотека это инструмент, как у художника кисть. Если ты в принципе можешь сделать игру, не важно в чем, ты сможешь сделать ее и в OpenGL, естественно после того как научишься с ней работать. Простой пример: в справке Дельфи описаны все функции канвы, ты видел там пример игры? Вот и в мануалах к OpenGL не увидишь.
Нужно кстати поднять общий уровень программирования, не только что касается игр. А то элементарно будут технические проблемы подключения, импортирования функций и т.д. Учить однозначно стоит, если в перспективе игры только под Windows, учи DirectX. Если больше интересует кроссплатформ, твой выбор - OpenGL. Не хочешь вникать в детали, есть движки, к-рые многое делают за тебя. Тут правда придется учить интерфейс движка, но он обычно намного легче и более высокоуровневый чем "родной" интерфейс библиотек. |
Canvas.Draw
Цитата:
Канва для игр перспективной вообще в принципе быть не может, ...это только некоторые экземпляры не требующие быстрого вывода и большого fps: типа первой Цивилизации или древней Симсити, карточных игр, простейших шахмат и пр. могут быть на ней реализованы в качестве макета, первого теста, учебного пособия, для себя от нечего делать, или как еще угодно. |
Шахматный интерфейс коня )))
Вложений: 1
Человек просил ход конем, выкладываю в уроках, может еще кому пригодится. Когда-то это должны были быть шашки, но теперь будут шахматы, конь уже есть )
|
А можно еще вопрос? Как сделать, чтоб картинка (допустим через 5 сек) появлялась в разных местах (то там, то здесь). Представление имею как делать, но решил все же уточнить, Спасибо!
|
например так
if GetTickCount mod 5000 = 0 then form1.Canvas.Draw(random(100),rando m(100),pic); Хотя правильнее было бы так Код:
var |
Идту туда куда смотрю!!!
Вложений: 1
Дума не только мне было интересно как реализовать ходьбу человека туда куда он смотрит. Возьмем тот же Crimsonland где человечек смотрит на мышь и идет туда по нажатию кнопки W. По этому алгоритму можно реализовать полет пули.
Вспомним тригонометрию, уравнение окружности выглядит следующим образом: x=cos(a); y=sin(a); Рассмотрим x и y не как точки, а как некий прирост по оси x и оси y. Допустим что a=pi/4, то sin(pi/4)=sqrt(2)/2 и cos(pi/4)=sqrt(2)/2, это значит, что нам нужно из начала координат (0,0) сдвинуться по оси x и y на sqrt(2)/2 и поставить там точку. А теперь задача с человечком. Допустим, что угол его взора равен a и нам необходимо изменить его координаты x и y так чтобы он пошел вперед. x:=x+cos(a); y:=y+sin(a); чтобы он пошол назад x:=x-cos(a); y:=y-sin(a); вот и все :) |
Цитата:
чем оно отличается от этого: Код:
//интервал таймера выставить в 5000 |
Цитата:
|
Цитата:
Или TickCount использовать или таймер, а то получается и то и другое и можно без хлеба. |
Цитата:
Код:
var |
И даже в этом случае TickCount юзать необязательно, достаточно переменной счетчика.
Конструкция с TickCount может заменить таймер (TTimer), когда вешается на Application.OnIdle. В остальных случаях есть таймер и его достаточно. А так получается двойная проверка, таймер тикнул, но мы ему не верим и проверим, а правильно ли он отсчитал? А кто проверит правильно ли TickCount отсчитал? |
Способов бывает много, причем один из равноценных не являются абсурдным. Если интервалы условий выбирать кратными интервалу таймера, то все работает как нужно, за исключением если вам конкретно нужно "полтора землекопа". Бреда здесь нет :)
|
Эй, народ! Напишите еще пару уроков. Я еще начинающий, но большая часть того, что сдесь пишется(в этой теме) либо очень непонятна(когда начинают о чем-то своем спорить профессионалы) или очень простым и неинтересным. Я могу наверное сделать чего-нибуть несложное типа простых шашек, или змейки, или пазлов например. Но дальше не идет. Напишите например какую-нибудь игру типа "герой прыгает по платформам через весь уровень убивая плохих и собирая юонусы". Напишите, как вы бы создавали эту игру сами, но максимально просто, желательно вообще через канву. Например сначала движение главного героя и его гравитацию(разные пружки и пр.), потом удару главного героя и вообще какую-нибудь анимацию, потом загрузка уровня, потом расположение объектов, потом... Особое внимание уделите пожалуйста графике. Я думай это будет многим интересно, надеюсь я не один такой тупой. выручайте, люди. я в тупике - то что я могу сделать не приведет к моему прогрессу, а для остального я совсем не готов. я даже не знаю что конкретно можно спросить. Поэтому напишите еще пару уроков по созданию ИГР для НОВИЧКОВ.
|
http://www.programmersforum.ru/attac...2&d=1211033214
Это анимация. Стрелками влево, вправо, планета катится, как шар из боулинга. Реализовать прыжки проще некуда. Заводите переменную sy, скорость по y и если под ногами у героя ничего нет, то прибавляем ускорение свободного падения к скорости, а по нажатию, прыжок, нужно просто sy присвоить какоенибудь отрицательное число, естественно если sy=0. Ходьбу по платформам это тоже достаточно легко реализовать. Нужно проверить 4 точки героя на столкновение со всеми видимыми платформами(чтобы не тормозило). Две верхние и две нижние. Если одна из нижних столкнулась(если гг падает), то его sy:=0;, а если он подлетает, то нужно проверить, две верхние точки и при столкновении sy:=0; и тут гравитация притянет его к земле. При ходьбе влево вправо, тоже советую завести переменную sx, скорость по x. И проделать тоже самое, только точки нужно проверять слева и справа. http://www.programmersforum.ru/showthread.php?t=20453, здесь описано как двигать экран. |
На канве...
Цитата:
Цитата:
Цитата:
Вот вы утвердились, будет главный герой, он передвигается по уровням, прыгает, стреляет из оружия, собирает предметы убивает противников, ...типичная аркада. Создавать игру нужно со "скелета" - модели уровня, модели объектов, системы хранения ресурсов и использования ресурсов. Я со своей стороны конечно предложу в качестве модели уровня - двумерный массив. Передвижение героя по "невидимым клеткам" со смещением для плавного перехода. Возможно реализация покажется сложной, ... что скажут остальные, какие еще есть предложения? |
Если графика на канве, то самое главное отойти от использования компонента TImage. Многие новички динамически создают массивы из TImage и помещают их на форму. Далеко не лучший способ. Единственная польза - научишься динамически создавать VCL объекты, если это кому нибудь надо )
Продолжение следует ... p/s Сегодня уже нет времени, завтра порассуждаю на эту тему ) |
Ладно, тогда начнем. Вы предлагаете в качестве модели уровня двумерный массив. А что он будет хранить(из приведенного ниже)? Как связать проходимость(т.е. физику), свойства объектов и вывод графики? Массив имеется в виду на сколько: вся карта или по размеру экрана, где будут меняться данные при продвижении?
|
Физика - это не проходимость, физика - это симуляция естественного поведения предметов - отскакивание, подпрыгивание, сила трения, инерция и т.д. путем расчетов с помощью законов и формул физики.
В аркадах физики обычно нет, в той о к-рой ты говорил точно нет. |
Модель аркадного уровня
Вложений: 1
Пожалуй начнем.
Данный метод построения модели "игрового пространства" может быть с успехом применен для любых игр, как 2D, так и 3D. Представте себе тетрадный лист в клеточку. Каждая клетка листа служит нам элементарной единицей пространства. Двумерный массив - математическая модель этого "тетрадного листа" (игрового пространства). Но в клетку массива обычно можно записать определенное значение некоторого типа. Для реализации множества параметров клетки (рисунок, проходимость, и пр.) потребуется "определить" эту клетку как собственный тип. Вот как это делается: Код:
// тип модели уровня Код:
Var Попробуем создать буфер кадра, в котором будет производиться построение, перед финальным выводом на экран, ... также загрузим картинки. Тут же построим игровой уровень, ...я покажу самый простой, статичный метод: Код:
procedure TForm1.FormCreate(Sender: TObject); Обновление кадра будет выполняться в таймере вот таким образом: Код:
// обновление кадра Код:
// процедура вывода изображения на форму Код:
// вывод изображения на экран Вот в принципе и все с моделью игрового пространства. Дальше будем разбирать модель персонажа, при условии, что знатоки помогут найти более простой способ, или просто что-то предложат :) |
Хочу сделать маленькое дополнение, в кач-ве заполнителя ячеек карты в простых играх можно применить обычный byte.
В программе эта карта будет иметь вид: map: array of array of byte; В файле карта будет иметь вид: 001012200... 003012200... 041015500... ... Тип byte позволяет иметь до 256-ти различных видов "заполнителя" карты, чего в аркаде хватает с головой, обычно хватает и десяти. Если все же их больше десяти, то в файле массив будет иметь несколько другой вид, нужен разделитель - пробел. 0 10 12 0 1 2 2 0 0... 0 15 3 0 1 22 2 0 0... 0 4 1 0 1 5 5 0 0... ... В заключение приведу реальный уровень из реальной игры Диггер (не оригинал, ремейк) Цитата:
Цитата:
|
Цитата:
p.s. А-а, все, увидел: MapMas[x,y].TGTexture:=brg; По сути тот же указатель. Битмап будет просто ссылаться на другой битмап (здесь на brg). Продолжение (про карту of byte) Как же загружать картинки при такой карте? Очень просто. Создаем массив битмапов, или же используем стандартный контрол TImageList. Загружаем в него картинки так, чтобы их нумерация совпала с элементами карты. Т.е. если у нас трава в карте это 0, то и картинка с травой тоже должна иметь индекс 0. |
Вложений: 1
L_M, заказывали пример, вот, получите и распишитесь. :) Небольшая игра по типу лабиринта, если усовершенствовать.
Управление: left,up,right,down. Цель: добраться до конца уровня к маленькому квадратику. Будет время, выложу пример аркады, в которой прыгать нужно, в этом же стиле. Как прикрутить картинки, тебе уже рассказали. :) |
Вложений: 1
Вот и второй пример поспел к раздаче. :) игра похож на предыдущую, только теперь она похожа на стандартную игру на Nokia, где мячик прыгает.
Управление: left,right,space. Цель: добраться до маленького квадратика. Офф-топ: я завтра уезжаю на две недели, не теряйте. =) |
Спасибо всем. А про TImageList объясните: что такое, зачем использовать(а не массив), как пользоваться. И почему модель уровня описана как объект, а не например просто запись?
|
TImageList это и есть массив, никаких особых преимуществ он не даст, просто один из способов. Польза есть в обоих случаях, в первом научишься использовать TImageList (он пригодится в прикладных программах), во втором научишься создавать динамические массивы, в частности из битмапов (тоже полезно =).
Как пользоваться написано в справке и в книгах по Дельфи. Не отходите от темы ) |
Цитата:
Не вижу смысла использовать ImageList, чтобы оставить его пустым, и при запуске заполнять эго картинками, ...или может загрузить картинки сразу и хранить в EXE? , побойтесь Бога. Вот такой вариант мной применялся до недавнего времени: Код:
Var Почему модель описана собственным типом? Конечно, то, что было показано - упрощенный вариант, ...а бывает, что можно не только проходить или нет, но и проходить с потерями, например если в клетке стоит огонь, или вода, ...в общем параметров может быть очень много (у меня 48). Цитата:
Так вот, при этой системе размер файла будет в разы меньшего объема, и плюс, нужно считывать подряд байт за байтом. Вот что может быть в файле: кЩxХС®AТ•Ф —dЌmҐEzA•˜№ UbJЃм•мп/¤ Л**@UMCtmЇ ...а теперь представьте как это выглядит с пробелами и по 2-3 байта на одну клетку карты. Никаких прочих алгоритмов писать не нужно, просто банальное read. Вот пример считывания карты с текстового файла: Код:
Var |
Ошибок нет, просто дополню до рабочего варианта
Код:
Var |
Отлично! Идем дальше, ...уровень построить можно, Kostia показал метод управления "персонажем", ...показываем методы выполнения анимации, конкретно система (как загружать картинки и куда выше было показано), смело несколько вариантов, чтобы видеть сходства и различия, причем помним, что анимация на прыжки и передвижения отдельная, там же и прочие типы.
|
Мне кажется тут все предельно просто и реализации отличаться будут лишь деталями.
Для начала как хранить спрайты? Я знаю три способа: прямоугольная карта, в один ряд и отдельными файлами. Я делал отдельными файлами, на то время с другими способами у меня были некоторые проблемы =) Грузил их в массив, и потом в таймере крутил, нужно скорость смены спрайта так расчитать чтобы было похоже что персонаж идет, а не семенит ногами на месте или чешет семимильными шагами. Для этого или подобрать интервал таймера, или же использовать счетчик. Код примерно такой: Код:
var http://avoreg.ru/pic_b/17bfe862ac900...c4d1f6aebd.gif |
Не совсем понял, GIF-анимация применяется?
|
Цитата:
|
Значит есть смысл пояснить, как работает система смены анимации, если на каждое состояние персонажа свой набор кадров. К примеру, у нас 10 кадров на каждое состояние (пусть будет качество :) ).
Анимация персонажа (файлы bmp): 1-10 - стоит; 11-20 - приседает; 21-30 - идет влево; 31-40 - идет вправо; 41-50 - прыгает влево; 51-60 - прыгает вправо; 61-70 - стреляет (бьет) влево; 71-80 - стреляет (бьет) вправо; Можете сделать меньше кадров, кому как нравится, или точнее, кому как ленится. Зеркальное отражение одного и того же действия я умышленно не применяю, и вам того же советую. Создайте в проекте новую папку, обзовите как-угодно и поместите туда все файлы. Подгружаются все кадры подряд через цикл, который уже был показан ранее. Теперь вызов нужной секции кадров из массива сводится к такому способу: BitBuf.Canvas.Draw(x, y, sprites[t+n]); где: t - задает тип анимации, а n - номер кадра. Теперь нужно будет только прописать назначение типа t на клавишах, какой тип нужно показывать. |
Ну с этим вроде понятно, хотя я сейчас на анимацию вообще плюнул и у меня, так же как и в примере, двигается шарик. Расскажите, как:
1.организовать бонусы, конкретно как они будут воздействовать на персонажа. 2.враги, как организовать их движение: сделать тупо чтобы ходили вперед-назад, или чтобы шли к игроку? 3.карта-ее основа двумерный массив, но как подобрать размер? И быть с динамичными объектами: бонусами, монстрами и пр. Записывать их в массив или проверять по координатам?(их будет не много) |
кстати, а как насчет цикличности анимации? типа пакмана-открывает и закрывает рот-надо рисовать каждый кадр или, например, менять n:=-1?
|
Между открытым и закрытым ртом хотя бы два промежуточных положения должно быть. Нужен счетчик в таймере, когда счетчик достиг числа спрайтов, обнуляй его. В случае с пакманом можно схитрить, закрывает рот он также как и открывает, так что можно для закрытия спрайты не делать, а использовать те же только в обратном порядке:
Код:
var n - номер спрайта i - счетчик (1 - 6) d - направление (0 - 3) n := d * 6 + i; |
Цитата:
Цитата:
Вперед-назад вообще элементарно, дошел до стены - развернулся, до развилки - повернул в случайную сторону. Цитата:
Monsters: array of TMonstr; А что с картой? В каком смысле подобрать размер? |
Думаю, имеется в виду, если карта больше экрана, как корректно сдвигать карту относительно него. Тут карты могут быть любого размера, главное помнить размеры, и держать персонажа по центру экрана.
|
нет, я имею в виду, что вот установлю я разрешение 800*600 и какими делать квадраты?(при полноэкр. режиме)
бонусы я не знаю как сделать. Например ускорение-если увеличивать сдвиг, будет получаться несоответствие с анимацией, сложности с проверкой столкновения и проч. еще вопрос: что делать при смерти перс.? Ну я имею ввиду как это делать. Отключать таймер и писать Game Over? А заново? И вообще как организовать меню? |
Цитата:
Цитата:
Цитата:
Меню игры (интерфейс) выполнить легче всего на панельках (Panel), которые могут содержать графику, кнопки, ...да все, что угодно. |
то есть когда надо показать меню делать панель с надписями видимой, а когда не надо просто скрывать? а как настройки сделать, например менять управление.
|
Вложений: 1
вот я попробовал написать игру и что получилось. теперь я думаю надо добавить разные детали уровня вместо простых кубиков, персонажей, анимировать, добавить звук, меню, бонусы, сделать редактор карт. Вроде все.
P.s. оцените что я сделал, только не дотрагивайтесь до врагов, потому что на прикосновение я поставил вывод сообщения, что бесконечно. стрелки-идти и прыгать, пробел-стрелять, врагов можно убить, 3 уровня |
В архиве недостаточно файлов для запуска. Скиньте весь проект.
|
Вложений: 1
извините, я забыл сами уровни. Также я сделал редактор, правда он рисует одно и то же, но работает правильно(таб-для ввода названия уровня, когда написал название нажать энтер, кликать мышкой, по умолчанию рисуется стена, после нажатия цифры 1 рисуется стена, 2- нач положение перс, 3- конец, 4-враг)
|
Привет всем :)
Вложений: 2
Меня небыло 2 недели, а тут почти ни каких продвижений в Gamedev'е.
L_M, пока плоховато. У меня после пары запусков, все иконки с рабочего пропали, это может быть вызвано, не правильной очисткой памяти или ее не очисткой. При выходе вылетает ошибка, пока еще не разбирал код, но мне кажется что ты чего не создал, а потом пытаешься его использовать или освободить его память. Пока с освобождение памяти можешь не мучаться, все за тебя delphi сделает. Меня затянул мой предыдущий пример и я захотел улучшить его, гляньте что получилось. Разрешение 320*240, fullscreen. Когда запустил игру в таком режиме, я снова вспомнил когда мне было 6 лет и денди к черно-белому телеку подключенный. Короче прикольная игрушка, от которой веет стариной, получилась. Управление: Left, Right, up или space. Цель: собрать зелененькие шарики и добраться до двери. Описание: вы играете маленьким шариком. Вам нужно пройти лабиринт с ловушками и собрать зеленые шарики и пройти на следующий уровень через дверь. В лабиринте вам встретятся разные ловушки: электрические ловушки, шипы и батуты которые не всегда будут вам помогать. |
У меня предложение. Эта тема начинает превращаться во свалку с неоднократно повторяющимися вопросами и ответами, все уроки разбросаны как попало, что приходится листать страничку за страничкой и в поисках полезной инфы, а вместо нее только каша информации.
Предлагаю создать две темы: Уроки по созданию игр для новичков... - здесь будут лежать исключительно уроки, без вопросов и объясните пожалуйста. Одним словом очистить это тему от лишнего. Мучающий меня вопрос... - здесь кто не попадя сможет задать вопросы, получать на них ответы, показывать свои наработки и обсуждать различные нюансы по созданию игр. И хорошие ответы из этой темы будут перетекать в тему выше. Думаю так будет логичнее всего поступить. |
Не так уж много страниц тут, за день прочитать можно, а игры то не за день делать учатся, так что постепенно можно прочесть. Для новичка тут все полезное, в том числе споры "более продвинутых товарищей". Это вообще эксклюзив, ни в одной книге не прочтешь )
Хотя в чем-то ты прав, тема не так начинала свою жизнь, но надо смотреть на это как на естественную эволюцию. |
Поддерживаю систематизацию уроков, но и "вариации на тему" в подавляющем большинстве своем - незаменимый урок начинающему, как правильно понять сее теоретическое и как применить правильно с нужной выгодой в тех или иных случаях.
|
Цитата:
|
просто уроков не слишком много. да и тогда весь этот раздел можно было уместить в двух-трех темах(кстати что правильно). а у меня такой вопрос: как обрабатывать и действоовать с объектом, если он никак не умещается в 1 клетку карты? например он должен в массиве занимать несколько клеток, а при считывании как определить с какой клетки начинать рисование? ну для рисования объект можно разделить, а как быть например с удалением этого объекта, т.е. правильно найти все его части и удалить, ведь рядом могут быть несколько одинаковых объектов?
|
У объекта должны быть координаты, то есть Left, Top (в клетках или в пикселях неважно). Ну и габариты. Вот и все. А клетки на поле занятые объектом маркируются соответсвующе.
Если он большой то и рисовать его целиком, делить незачем. |
Думаю пришло время изучить более простую но продвинутую конструкцию карт. Это карта путей. На подробное описание времени нет, но скажу что это 2D массив типа boolean(можно byte если будут плохо проходимые места, но принцип один) 0-проходимая клетка, 1-не проходимая и делать то что написал mutabor.
Например у нас есть дом 2*2 клетки и он стоит в x и y координате. Мы при загрузки карты считываем координаты дома и циклом заполняем соответствующие клетки карты путей единицами и просто рисуем там дом. Подробнее и с примером отпишусь чуть позже. |
На 11-й странице про проходимость рассказывалось, даже тип был создан для этого, чтобы в одном массиве хранить индексы и графики и карты проходимости.
|
Цитата:
Значит, благодаря смещению мы правильно отображаем объект, а благодаря размерам - правильно проверяем объекты на столкновения. Создайте свой тип на объект, где будут записи на ширину и высоту картинки, смещение по осям X и Y, и еще много чего вам будет полезно, например состояние персонажа, номер анимации, текущий кадр и пр. пр. пр. |
извините, но я не понимаю преимуществ карты путей. зачем делать тот же массив, еще и сложнее: добавлять разные свойства, рисунок и пр. массив чисел мне кажется проще-только для каждого числа свои действия. а ту же проходимость например можно сделать так:
if map[i,j]>n then Go; где до n непроходимые рисунки, а после - проходимые. |
не примите как возражение против карты путей, просто объясните, в чем преимущество?
|
Цитата:
|
А кто может сказать как загрузить на форму свою анимацию?
|
ORBIUS, а что вы подразумеваете под "загрузить на форму анимацию"? ...где хранить кадры или как их выводить на экран?
|
Цитата:
Вот странные люди программисты, толи делают вид, что непонимают, чего может непонимать спрашивающий, толь ленятся больше одного ответа давать. Интересует то весь процесс с максимальным количеством подробностей и с примером, если можно, а не совет, дави F1...:rolleyes: |
пишу танчики и просто застрял на одном месте!
как можно сделать, чтобы если, ты, например, развернут вниз, компонент image1 (снаряд) летел вниз, вправо-вправо и т.д. у меня все время он летит вверх, чтобы я не делал! я задал переменные: Код:
image3up,image3left,image3down,image3right:boolean; //image3-снаряд Код:
if image2up=true then в таймере пишу код: Код:
if image3up=false then помогите, плиз, так хочется по-скорей закончить, а тут это... :( |
Популярно...
ЛомиК, ярлыки вешать все мастера.
Обычно так и происходит на полное описание процесса потом идет нарекание типа "это я и без вас знаю, мне бы вот это...", ...так стоит ставить вопрос соответствующе, чтобы было понятно, что имеется в виду. Загрузить на форму - это одно, вывести на форму - это другое. А за примеры не боИтесь, без них не оставляем :cool: Все взято из тем "Как вы относитесь к созданию игр на Delphi?" и "Уроки по созданию игр для новичков". Вывод графики для VCL, загрузка, и структура хранения без ограничений для любых методов. Создание структуры хранения анимации (это было к примеру аркады, "Уроки по созданию игр для новичков", пост #115) Если на каждое состояние персонажа свой набор кадров. К примеру, у нас 10 кадров на каждое состояние (пусть будет качество). Анимация персонажа (файлы bmp): 1-10 - стоит; 11-20 - приседает; 21-30 - идет влево; 31-40 - идет вправо; 41-50 - прыгает влево; 51-60 - прыгает вправо; 61-70 - стреляет (бьет) влево; 71-80 - стреляет (бьет) вправо; Можете сделать меньше кадров, кому как нравится. Зеркальное отражение одного и того же действия я умышленно не применяю, и вам того же советую. Создайте в проекте новую папку, например Anim, и поместите туда все файлы. Загрузка анимации Практикуется загрузка анимации в ImageList. ("Уроки по созданию игр для новичков", из поста #109) Не вижу смысла использовать ImageList, чтобы оставить его пустым, и при запуске заполнять эго картинками, ...или может загрузить картинки сразу и хранить в EXE? , побойтесь Бога. Загружать анимацию будем в массив типа TBitmap. Вот такой вариант мной применялся до недавнего времени: (добавлю точности для частного случая) Код:
Var Подготовка кадра ("Уроки по созданию игр для новичков", из поста #85) Цитата:
(пост #102) Попробуем создать буфер кадра, в котором будет производиться построение, перед финальным выводом на экран: Код:
procedure TForm1.FormCreate(Sender: TObject); Код:
BitBuf.Canvas.Draw(x, y, TexMas[t+n]); Вывод анимации Тут следует уточнить, куда выводить анимацию, прямо на форму или же в PainBox, Image. Пусть в Image. Смотрим процесс отрисовки кадра и его вывод в Image в процедуре таймера: Код:
procedure TForm1.Timer1Timer(Sender: TObject); (читаем материал "Уроки по созданию игр для новичков", пост #102) Создаем свой тип для модели мира (уровня) и для персонажей, в таймере применяем цикл по числу персонажей. P.S. Если нужно, остановимся подробнее на модели персонажа. |
Titan123, для начала слегка поменяйте название переменных, ...человеческий зрительный аппарат так устроен, что привыкает к похожести начальных нескольких символов, и при беглом поиске просто считает имена одинаковыми, ...в итоге поиск ошибок затрудняется. Это из многолетней практики.
Предложу исправить вот так: Код:
PatronUp, PatronLeft, PatronDown, PatronRight: Boolean; //PatronImage-снаряд Также в таймере есть условие: if image3up=false then оно неверное, если вас интересует лишь истинность True. ...это наверное попытка хоть как-то повлиять на ситуацию? :) |
Titan123, раз он все время летит вверх, эначит этот код
Код:
if image3down=true then Чтобы не было таких запутанных условий, лучше сделать немного иначе: Код:
type Код:
var |
Titan123, а кто снаряд? -
как можно сделать, чтобы если, ты, например, развернут вниз, компонент image1 (снаряд) летел вниз, вправо-вправо и т.д. у меня все время он летит вверх, чтобы я не делал! я задал переменные: Код: view plaincopy to clipboardprint? image3up,image3left,image3down,imag e3right:boolean; //image3-снаряд ====== У Вас там путаницы с image нет? Правильно Вам посоветовали с именами переменных. Beermonza Извиняюсь, если задел, просто часто уж приходится слышать весьма лаконичные ответы, Вы мне открыли глаза, я и недумал что это может напрягать, хотя если человек совсем бестолков, тогда да, но я таким вообще не отвечаю, прошу прощенья. |
1.подскажите как лучше делать иск. интеллект? я вот пробовал для крестиков-ноликов описать процедуру постановки знака и вызывал ее с параметрами(чей ход и пр.) - т.е. как бы общая процедура для всех, а в процессе поиска лучшего решения я как бы моделировал ходы- комп проверял возможный ход на эффективность и проверял что будет. правилен ли такой подход или надо как - то иначе?
2. расскажите как сделать игру через интернет |
L_M, так понимаю, вам нужно написать искусственный интелект для некоторой игры: "расскажите как сделать игру через интернет", а первые попытки у вас были на игре "крестики-нолики"? ...или ваша игра "крестики-нолики" и вас не устраивает тот метод работы ИИ что вы уже применили?
Все зависит от типа игры и от поведения объекта, который вы собираетесь имитировать. Уточните, тогда можно будет вам помочь. |
ну конкретно я хочу сделать юнита, например в стратегии. вот вопросы:
1. как их все хранить? есть юнит, 1 штука, например объект. как хранить много юнитов(в массиве что ли)? 2. как создавать(динамически?). 3. как сделать прозрачные панели, например со зданиями? |
вот, забыл самое главное: нужно ли делать каждый юнит екземпляром объекта(класса, компонента,...) с процедурами, или описать глобальные процедуры, например движения и передавать туда параметры каждого юнита?
|
Цитата:
а вообще выше описанный мною способ с image3up и т.д. я нашел в одном исходнике. поэтому я даже не понимаю как это работает! может, надо как-то описать это... но как? для меня идеальный способ был бы сказать если image2.picture='вверх.bmp' то... но я узнал так сделать невозможно :( может вы подскажите мне вообще альтернативный вариант этого действия? был бы очень признателен |
все понял я.
как обычно, виноват я: запутался и допустил ошибки. всем спасибо. я, наверное, еще обращусь :) |
Про модель юнитов
Titan123, самый верный способ не допускать ошибки - это делать код как можно понятнее, даже для себя, писать комментарии, давать названия, из которых сразу видно что это и для чего. Даже если не это стало причиной неправильной работы программы в вашем случае, не соблюдение вышеуказанных правил вам еще о себе напомнит, когда вы будете писать проект не на десяток строк.
L_M, воу, воу, воу, не все сразу :) ...и ИИ, и модель юнитов, и графика, ...давайте по степени значимости. На первом месте всегда модели. Значит разбираем модель юнита (персонажа), полагаю модель мира вы уже понимаете как создается из прошлых уроков, даже готовую игрушку показали :) Для стратегии все аналогично, только текстурки тайлов будут изометрические или вид сверху. Модель персонажа Чтобы юнит был не один, нужно воспользоваться одномерным массивом, размер его нужно задать сразу, например (0-255) - это будет лимит "населения" в вашей стратегии. Массив создается сразу, а вот управлять его содержимым мы будем динамически. Юнит обладает рядом характеристик игровых, а так же множеством системных данных от указателей на анимацию до индексов действий. Главным остается правило: "все юниты в системе игры имеют один и тот же набор характеристик и системных данных". Для этого нам понадобится собственный тип массива: Код:
// тип "юнит" ----------------------------------------------------- Теперь достаточно назначить тип на наш массив и модель юнита готова: Код:
Var продолжение следует... |
Про модель юнитов (продолжение)
продолжение...
Вот секция управления перемещением юнитов: Код:
procedure TForm1.Timer1Timer(Sender: TObject); Что значит "прозрачные панели под здания" я не совсем понимаю, если мы рисуем в буфере, то достаточно иметь bmp-картинку здания, при загрузке указать прозрачность. Вот в принципе и все, с моделью. ИИ для стратегии Задача достаточно сложная, готового кода у меня к сожалению нет, еще предстоит разработать только для RPG, он много сложнее. Вам же нужен примитивный. Попробую объяснить на пальцах. Итак ИИ для стратегий. В него входит система поиска пути и система распознования целей. "Поиск пути" - достаточно распространенная тема, нас интересует самый простой частный случай - "дойти до точки назначения" (или до расстояния атаки), без особенностей, смотрим тут: http://www.delphikingdom.com/asp/vie...catalogid=1127 В системе распознования целей у нас есть цикл, он перебирает всех юнитов, берет их координаты UPosX, UPosY и прибавляет/отнимает, в соответствии, обзор UScan по всем направлениям, если на карте в этом радиусе (он не совсем радиус, скорее ромб) находится цель, то передаются координаты в систему поиска пути. В случае дальней атаки предварительно отнимается/прибавляется дистанция атаки URange. Казалось бы это одна система, но поиск пути нам не нужен пока нет цели или пока не дана команда перейти в указанное место (мышкой). Как интерпритировать координаты мышки в координаты карты? ...оч. просто: Код:
MapX:=Trunc((Mouse.CursorPos.X-Form1.Left-{поправка})/{половина длины тайла})+DispMapX; Тут одно за другое цепляется, куча нюансов. Ну что, аркаду можно сказать сделали, теперь стратегию? :) |
как я понял создается массив из юнитов, потом в цикле изменяются координаты каждого согласно направлению? почему используется тип packet record, а не например просто запись, или объект?
|
в основном меня интересует именно модель персонажа и как "приделать" к ней графику и ИИ. графику я думаю, что смогу сделать, об этом сказано достаточно, ИИ тоже несложно, но как собрать все вместе. вы уже начали объяснять как раз то, что нужно. получается надо для всего проверять весь массив(например столкновение друг с другом это цикл огромный получиться)? да и 255 это слишком мало для стратегии(если 16 рас, то по 16 юнитов получиться)-мне кажется это будет очень долго обрабатываться. я еще не знаю что делаю - рпг в стиле диабло(аллодов) или стратегию, но принцип то там будет один и тот же?
|
Продолжаем разбирать модель юнитов ...
Цитата:
Packet record я использую в целях экономии ресурсов, эти записи будут предварительно обработаны, и будут занимать столько памяти сколько для них требуется, в отличие от просто Record, правда чуть падает скорость, но на игре это не отразится. Применять Object вообще нет никакого смысла, никакого наследования у нас нет, строить дерево тоже не нужно, просто записи. Цитата:
ИИ непосредственно управляет записями массива юнитов, обрабатывая в цикле условия. Вспомните AOEII там лимит 200 юнитов для расы, ...у вас будет 16 массивов, причем движок будет работать только с теми, что участвуют в игре, ...как подтормаживает Империя на макс лимите все знают :) Так что вы пробуйте на малом, постепенно расширяйте. Разница между стратегией и RPG в плане движка невелика, они часто обе содержатся в одной и той же игре, например WarCraft. |
вот столкнулся с такими проблемами:
при закрытии неправильно работает. в таймере обрабатывается графика, ну как в примерах, и при нажатии Esc Close; а в собственной процедуре close работает для файлов, и я не знаю как правильно завершить программу. сразу такой вопрос где все-таки все обрабатывать? для таймера в примере был обработчик клавиатуры, а как быть с мышью? |
Друзья, понимаю что влез не в тему вообще, но у меня вопрос. Как создать физику мяча? Сделать так точнее чтобы он мог оттталкиваться от стен, скорость остаётся постоянной.
|
Цитата:
Не знаю как все, а если VCL, то проще обрабатывать OnKeyDown и иже с ними OnMouse для мыши на главной форме, ...тут у вас флаги меняют свои значения по нажатию с клавиатуры или мыши, а один ОБЩИЙ таймер обрабатывает флаги, задает такт ИИ и сам же им и является, готовит графику и опять так и дает команду процедуре вывода кадра на экран. Цитата:
|
Скорость - это вектор. Реверсируем координаты вектора в зависимости от стены, от которой отталкиваемся. От вертикальных - реверс Х, от горизонтальных - реверс Y.
|
у меня возникла такая проблема: как заставить юнита идти в нужную точку? ну с прямой это просто и понятно:
Код:
while (man.x<>click_x)and(man.y<>click_y) do begin |
Возвращаясь к напечатанному...
Возвращаемся к посту #155, еще раз разбираем код:
Код:
procedure TForm1.Timer1Timer(Sender: TObject); |
пожалуйста, напишите урок по создании крестиков-ноликов. хотя бы простейших 3*3
разбираю исходники, не понимаю кода! |
Titan123, а что именно непонятно? Давайте первый непонятный кусок кода.
|
Titan123, тебе нужно поучиться алгоритмы составлять. Не обязательно на играх, любые задачки подойдут. Есть книжки такие с задачками и с их алгоритмами, например "200 задач на С/С++", может для Дельфи такие есть, но язык не важен, также как и среда, хоть в КьюБейсике, главное - алгоритмы.
Иначе у тебя будут постоянно подобные вопросы. Возьми лист бумаги, ручку, подумай как бы ты сам делал ходы, поставь себя на место компьютера, и напиши алгоритм действий. Возможно твой алгоритм будет не самым красивым и удачным, но это будет твой алгоритм. А потом можно сравнить с другими, и я уверен ты начнешь в них кое-что понимать. Урок писать это долго, лучше приведи непонятный кусок кода (переменные не потеряй только). Хотя если на работе завтра нечем будет заняться, напишу крестики нолики 3х3 (никогда раньше не делал и код не видел, интересно что получится). |
Вложений: 1
Народ, помогите мне пожалуйста. У меня неправильно ищется маршрут - приходит в другое место перс. И еще просьба: напишите еще несколько уроков по играм, например про оптимизацию, хранение различных ресурсов.
Вот что у меня пока получается: |
L_M, уже обсуждали, причем привели несколько вариантов.
http://www.programmersforum.ru/showt...3612#post53612 |
Насчет оптимизации. Это очень обширная тема про которую можно не один том написать. Советую начать с изучения архитектуры компьютера. Когда знаешь как работает твое железо, то можно и оптимальную для него программу написать.
Хранение различных ресурсов - это уже не раз обсуждалось, поиск по форуму или Google. |
Вложений: 1
я писал крестики-нолики, составил несколько десятков комбинаций противника, кода получилось очень много, рассматривая другой исходник К-Н я понимал, что делаю неправильно.
у меня все банально: например, Код:
if (panel1.caption='0') and (panel5.Caption='0') and (panel9.Caption<>'x') then begin panel9.caption:='0'; end но это все неверно. выкладываю не мои К-Н, может, вы объясните мне о чем там говориться. |
To L_M
Мде, я немного затерялся в вашем коде. При разработке игры создайте дополнительно панельку (Panel), в которую поместите лэйблы (Label), напишите процедуру сбора данных, это вам поможет видеть текущие значения переменных и тем самым ошибки работы программы. Обязательно текущие координаты мыши, клетки карты, позиция персонажа, и дополнительные на тип действия или еще что. Я предложил простейший пример движения персонажа, мне кажется он самый простой в понимании и реализации, ...вот так он выглядит на практике: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Т 0 0 0 0 0 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 0 0 0 0 / 0 0 0 0 0 0 0 0 0 0 0 0 / 0 0 0 0 0 0 0 0 0 0 0 0 / 0 0 0 0 0 0 0 0 0 0 0 0 П 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 П - текущие координаты персонажа Т - точка, куда нужно переместиться Логика Зная координаты персонажа и новой точки нужно сравнивать поочереди X и Y. Код:
if UPointX>UPosX then UDispX:=1; Код:
if UPosX<>UPointX then Настоятельно рекомендую попробовать :cool: |
To Titan123, дам совет. Разделяй код логики и вывода на экран. То есть обработка геймплея не должна базироваться на панелях или на кнопках или на чем-то там еще. Делай универсальный (абстрактный, не зависимый от графики) код, к к-рому можно будет прикрутить любой вывод на экран. Читабельность кода намного вырастет, да и не всегда у тебя будут панели чтобы на них опираться.
Используй структуры, классы, просто переменные, массивы и т.д. Крестики нолики не делал, времени нет. Но подумал, как бы я их сделал. Сразу отбросил вариант 3х3, слишком маленькие, алгоритм даже потестировать негде, тесновато и не интересно. Я еще с первого класса помню какой нужно сделать первый ход чтобы выиграть. Я бы сделал поле 10х10, и по таким правилам, если пять подряд по горизонтали, вертикали или диагонали выстроил - победа. Не совсем крестики нолики но так интересней. Думал над алгоритмом. Сразу нужно отсеять рутинные операции типа вывода на экран, очистки поля, обработки мыши и т.п. В итоге я бы сделал функцию "СделатьХод" MakeMove(параметры): возвращаемый тип; Вобщем она должна сделать ход, параметры и возвращаемое значение можно сделать разные, но на вход она должна получить игрока за к-рого ходить, т.е. крестиком или ноликом, уровень мастерства, т.е. насколько умным должен быть ход (Random - самый тупой =), а вернуть позицию куда лепить тот же крестик или нолик. Матрицу - игровое поле можно передать в параметрах или обращаться к ней как к глобальной. С теорией пока все, сделать так чтоб работало не проблема, но все что приходило мне в голову какое-то громоздкое и слишком "человеко ориентированное". Тут наверное математика не помешала бы. |
Посмотрел те крестики нолики, ну и наворочено. Явно для примера не подходят, процедура где генерируется следующий ход - procedure putO(); в Unit1, вся суть в ней.
Игровое поле матрица 3х3 of integer; Как такового алгоритма нет, тупо проверяются различные комбинации, заточено под поле 3х3, если бы таким методом сделать проверку поля 10х10, код вырос бы до огромных размеров. Там где компьютер - дурачок, ход генерируется функцией Random. Там где поумней - 200 строк кода, сплошные проверки if. Наверное перебрана каждая комбинация к-рая может возникнуть на поле. |
mutabor, простого показательного кода не получить в любом случае. Тут как в шахматах, есть логические ходы, БД с комбинациями, проверка в ней на соответствие, это первое, ...а второе - перебор последовательности вероятного хода противника до оптимального варианта, в котором будет выигрыш за какое-то число ходов.
Так что, 3х3 хоть и не интересно, но показательно с точки зрения алгоритма. |
Простой пример основы РПГ
Вложений: 1
Вот, держите примерчик. Упрощено до минимума, на исходниках L_M.
Это может быть РПГ или стратегия. |
спасибо, то что нужно было...пока.
|
Урок Крестики-нолики на большом поле Часть1
Вложений: 1
В этом уроке я расскажу как сделать большие крестики-нолики на Дельфи. Скорее всего вы знаете эту игру, возможно под другим названием. Объясню вкратце: прямоугольное поле в клетку, кто раньше выстроил пять своих фишек (крестиков, ноликов, клякс и т.п.) подряд по горизонтали, вертикали или диагонали тот и выиграл.
Урок расчитан на новичков, если вы не новичек, для вас тоже может найтись интересное, почитайте P.S. Итак приступим. Часть первая — интерфейс. Для вывода графики будем использовать компонент TImage. Поле будет 10х10 клеток, но код будет универсальный и вы потом сможете без особого труда сделать изменяемые размеры. Поле реализовано как двумерный массив с элементом типа Shortint, вместо него можно было и Integer использовать, Shortint выбран т.к. занимает меньше памяти. Тип выбран с возможность присваивать отрицательные значения, -1 будет означать пусто, 0 — нолик, 1- крестик. Можно было создать свой перечисляемый тип для элемента, со значениями Krestik, Nolik, но простые числа более гибкие в коде, с ними удобнее, хотя не так наглядно. Рассмотрим секцию var Код:
var CPUMark, HumanMark — будет хранить кто чем играет, крестиком или ноликом. 0 — нолик, 1 — крестик. В дальнейшем я буду стараться чтобы 0 совпадал с ноликом при создании переменных. table — игровое поле. TableWidth, TableHeight — тут думаю понятно ширина и высота. Менять не советую, так как в процессе написания универсльность несколько потерялась. Константа одна - CELL_SIDE = 40; это размер клетки, а точнее длина ее стороны в пикселях. TImage соответственно будет иметь размеры 400 х 400. Настройки я засунул в главное меню, их там немного и вы сами я думаю разберетесь. Выбор противника не работает, но в коде все под него есть, алгоритмы заточены ходить за любого игрока. Так что доделать будет не так сложно, лучше выбор игроков сделать в двух комбобоксах, чтобы разные алгоритмы друг на друге тестировать можно было. Смотрим дальше главный юнит — Main. (Код во вложении.) Сначала идут обработчики пунктов меню, в них ничего интересного. Дальше идет сам игровой процесс. Он состоит из двух процедур — обработчик нажатия мыши в Image и обработчик пукта меню Новая игра. Вот и вся игра. Но это конечно не весь код, самое интересное скрыто в юните Game, о нем попозже. |
продолжение...
В обработчике пункта Новая игра всего одна строка - вызов функции NewGame;
В ней описаны все действия необходимые при старте новой игры. Какие в этот момент выбраны настройки в меню, с такими и начнется игра. В процедуре Image1MouseDown заключается высокоуровневый алгоритм игры, как видите он довольно простой, если не вникать в сами функции. Разберем по строкам. cx:=x div CELL_SIDE; cy:=y div CELL_SIDE; Переводим координаты клика из пикселей в координаты клетки на поле. if Empty(table[cx,cy]) then Функция Empty возвращает True если клетка пустая, т.е. в нее можно ходить HumanMove(cx,cy); Ходим. Application.ProcessMessages; Это нужно чтобы ваш ход сразу отобразился на экране. Иначе это произойдет только после завершения всей процедуры. if EndOfGame = 0 then Проверяем не выиграли ли мы. Или не последний ли это был возможный ход. Функция EndOfGame вернет 0 — если еще не конец игры, 1 - выиграли нолики, 2 — крестики. Sleep(500); Если управление дошло сюда, значит еще не конец игры. Делаем задержку в полсекунды, чтобы компьютер не отвечал мгновенно. CPUMove(CPUSkill,CPUMark); Ходит компьютер. Параметры — уровень мастерства и чем собственно ходить. if EndOfGame > 0 then ShowMessage('the end '+IntToStr(EndOfGame)); Если условие верно, значит наступил конец игры после хода компьютера. Результат игры возвращает та же функция, об этом написано выше. ShowMessage здесь просто как заглушка, к написанию второй части урока я это доделаю. else ShowMessage('the end '+IntToStr(EndOfGame)); То же самое, только конец игры наступил после хода человека. Пока это все. Разбор юнита Game будет во второй части урока. В текущей версии при выборе мастерства Новичек и Мастер, компьютер ходит всегда как новичек, вообще не думая, используется Random. Над более продвинутым алгоритмом я как раз сейчас думаю. P.S. Для кое-чего умеющих. Если вам интересно, можете написать свою версию алгоритма для хода компьютера - procedure CPUMove(skill: byte; mark: byte); На вход процедура получает уровень мастерства и чем ходить. Доступ к массиву как к глобальному. Массив 10 х 10 - table: array of array of shortint; //-1 — пусто, 0 — нолик, 1 — крестик Готовый ход делается в конце процедуры двумя строками table[x,y]:=mark; //сохранение хода в матрице PutMark(x,y,mark); //вывод хода на экран Для отладки можете использовать проект во вложении, он рабочий. |
mutabor спасибо, что откликнулись на мою просьбу, но компьютер играет довольно скудно.
я, конечно, буду разбираться в коде, но как можно увеличить его мастерство? |
Всем привет!Первый раз на этом форуме.Очень жалею, что только сейчас обнаружил этот форум. Давно занимаюсь изучением программирования и мне кажется ,что через создание игр, даже простейших, самый оптимальный способ обучения.Создал несколько игрушек, но есть вопросы.Вот только незнаю куда и как можно выложить коды,exe-шники,
чтобы потом давать на них ссылки.Подскажите, плз. |
Цитата:
|
Цитата:
|
Еще о движениях персонажей
Вложений: 1
Простенький пример передвижения для новичков в 2D.Принцип - покадрового вывода из файлов (можно из файла ресурсов или из Image
List, что предпочтительнее для .exe файлов) с последующим затиранием фоном и сдвигом вывода след. кадра.Винни скопирован здесь же на форуме (прошу прощения). Запустите программку и нажмите "стрелка влево"(можно держать непрерывно.Это только принцип движения. который можно видоизменять под свои нужды. |
Вложений: 1
mutabor я, в помощь, выложу не мои большие К-Н. я в коде ни чего не понял, но компьютер играет довольно хорошо. может, вам это поможет в написании алгоритма
|
Вложений: 2
Вот двое моих крестиков-ноликов. алгоритм хода компьютера очень прост: он считает для каждой клетки сколько будет рядом таких же, т.е. сколько рядом, если туда поставит компьютер минус сколько будет при ходе игрока.
|
Цитата:
Пока доработал программу, заточил под использование разных алгоритмов, в ней и сравню. Если конечно получится чужие алгоритмы под свои условия игры подогнать. Скриншот >>> |
Предотвращение ошибок
Частенько на форуме мы слышим "программа выдает ошибку...", ...свой собственный код, оказывается не под силу отладить самостоятельно, или же код не работает на сторонних ПК по непонятным причинам. Стандартное сообщение с ошибкой адреса абсолютно ни о чем не говорит пользователю.
Есть замечательная структура Try..Except..End. Неуверенный в своем коде программист может вплоть до каждой строки заключить в эту структуру и при том сторонние пользователи его труда будут знать где программа работает некорректно, и что нужно делать, разумеется если автор постарается с классификацией ошибок. Вот так может выглядеть часть кода: Код:
... |
Всем привет! Вот увидел темку и решил поучаствовать. Написал урок про то что меня волнует больше всего - скрипты в играх. Вобщем вот:
http://webfile.ru/2253596 |
Большая просьба, ...оформите пожалуйста в виде урока, разбейте на части, ...а в прикрепленном файле оставьте архив проекта.
|
Добрый вечер, решил делать следующую игру для телефона, но уже серьезную, аналог гта 2, только без машин, решил все делать хорошо и реалистично, например бег по траве ниже чем по асфальту, решио делать землю из квадратов содержащиеся в массиве, так и графику легче загружать, только такой вопрос, как например a[1]:=квадрат 10 на 10? я могу по 1 пикселю присвоить, но не больше...еще если там будет содержаться етот квадрат...а я хочу еще помечать что если a[1]=1 то ето вода =2 ето земля =3 песок =4 трава и.т.д...массив занят как тогда реализовать такое?
Так....далее, карту я планирую делать примерно в 30 дисплеев телефона, тобишь огромная территория, как мне устанавливать здания? так и писать координаты x=-1200 y=-300, x=3000, y=-1300? |
[Smarik], в посте #154 "Про модель юнитов" описан принцип хранения объектов, будь то строения, юниты (персонажи), или даже текстуры. У вас будет массив особого типа, в котором записи нужных типов, в которые вы запишете все нужные вам параметры, включая графику.
|
Разрешите влесть не в тему, в прошлый раз меня послали в 154 пост, но мне показалась, там не совсем то, чего я желаю, есть частица истины, но реализована не для моих целей.
Мне нужна земля, по типу шахматной доски, тоесть квадратами, чтобы если я укажу drawimage(image,5,12) он четко покажет картину в нужный квадрат, я додумался только до варианта: Код:
drawimage(image,x,y); |
[Smarik], т.е. у вас отображение участка карты идет как экран - локация? ...она статична, и не двигается, а в ней много объектов?
|
да статична, объектов пока что будет мало, трава, вода, огонь, каждой свою клетку, далее будут дома, заборы..ну много всего, вроде как сути не имеет, мне говорили что в героях примерно такой же алгоритм и что его возможно найти, но гугл мне не помог, использовал десятки запросов.
|
Про локации...
Именно по этому и отправил вас читать 154-й пост. Не имеет значения как вы позиционируетесь на карте, важно то, как вы представляете данные карты в памяти ПК, в вашем случае СТ (сотового телефона).
Представьте себе лист в клеточку - это локация, в каждой клетке у нас может быть записано множество разнотипных данных. А теперь представьте что к этому листу в клеточку, вы положите справа еще такой же лист, ...что будет? у вас будет еще одна локация, у первой номер 1, а у второй - 2. Теперь вам нужно создать массив числового типа с индексами этих локаций, каждая из которых - тоже массив нужного размера, но уже особого типа, для записи картинок и пр. данных для каждой ячейки. Чтобы отрисовать нужную локацию, вам нужно знать ее номер, а позиционирование в ней будет от ее верхнего левого угла, т.е. от X = 0, Y = 0. |
возможно я повторюсь, но как лучше игру создавать:
чтобы объекты TShape(как написано на 1-ой странице) и др. двигались по форме или одни картинки TBitmap(какие можно ещё?) по объекту TImage(посоветуйте какой объект в данном случае использовать удобнее) --- в моих играх на Delphi6 всё прорисововалось на объекте DXDraw модуля DelphiX. это что-то вроде канвы, но удобнее (до сих пор не разобрался во всех прелестях) |
Для начала, прочитай всю тему "Уроки по созданию игр для новичков", попытайся повторить предложенные алгоритмы, только не просто скопировать, а осмыслить что и зачем, можно поиграться с переменными, определить что за что отвечает в коде. Одним словом, прежде чем создавать игру нужно сносно знать Delphi, уметь оперировать командами, знать элементарные приемы программинга и тд. и тп. и третье и десятое.
|
Оформи для меня какую-то маленькую часть проекта в задачку для нескольких функций, сначала что-то попроще, что вводить и что нужно получить на выходе. Вышли на bees[]meta.ua. Заделаю на досуге, времени сейчас появилось море, хочу поучаствовать в твоем прожекте :)
|
Хочу создать что-то типа стратегии Heroes 3. На GDI я смог бы без проблем создать, но нужно DirectX.
Не понимаю, как использовать DirectX для отображения карты. Способ хранения будет матрицей. Мне непонятнj, как отрисовывать карту с помощью DirectX на поверхности. Вопрос здесь http://www.programmersforum.ru/showthread.php?t=34393 Нужно делать какое-то матричное преобразование? |
Ребята, тема действительно интересная и очень полезная! Но было бы действительно классно, если бы все велося как на 1 страничке, код, и коментарии к нему, как это делал автор Темы!а сейчас просто свободный флуб профессионалов, общающихся между собой, может где то на форуме есть что то подобное, как 1 страница! А не вышеуказаный флуД?! Вот я лично полный новичек, и вы вкладываете уже готовые игры, я не могу понять как и что! Тема же называеться "Уроки..."!
|
если ты новичок, то качай исходники и разбирайся с ними, а что не получиться - пиши, поможем... а с налету ничего не бывает ;-)
|
я за то, что бы детально обьяснялся материал, как на 1 странице!
|
А нет ли более удачного алгоритма проверки сталкивания предметов с персонажем чем этот.
Код:
var Player: TPoint; |
Если объектов 1000 одновременно, то так тому и быть, ...например игровой сервер ворочиет их всех вместе по порядку или в потоках, ...все равно нужно всех проверять.
|
Нахождение оптимального маршрута и обхождение препятствий
Допустим есть карта-двумерный массив из проходимых и не проходимых зон. Персонажу нужно попасть из точки А в В проходя только через проходимые ячейки. при чем этот маршрут должен быть самым коротким. Кто нибудь знает как быть? Нужен алгоритм или код на дельфи с объяснением. ну или хотя бы посоветуйте как быть
|
Читаем про так званый "алгоритм дейкстры" :)
http://www.google.ru/search?hl=ru&q=...80%D0%B8%D1%82 |
Лубышев, вот тут интересная статья с примером http://www.delphikingdom.com/asp/vie...catalogid=1127
|
Прива всем. Токо что сюда попал. Народ, подскажите, с помощью какой програмы можно делать игры, ну пока 2D естествено?
|
Делают игры с помошью движков готовых, а сей форум в основном посвящен среде программирования - Delphi, а тема эта для тех, кто будет писать код для своей игры на Delphi, и не знает с чего начать, или знает, но есть вопросы.
|
Цитата:
http://www.programmersforum.ru/showthread.php?t=10952#6 Я приводил исходник поиска оптимального пути в лабиринте. |
Ну все... персонажи бегают по карте и дерутся между собой в ближнем бою. теперь такой вопрос. как быть с дальнем боем? Кто нибудь знает где взять учебный материал для создания на канвасе таких эффектов как фаербол или летящая из одной точки в другую молния и т. п. ? Пытался с помощью примитивов нарисовать по формуле но что то не очень правдоподобно получается.
|
Лубышев, можно использовать что-то типа спрайтов. Делать игрушки на канве не совсем эффективно. Но если уж взялись, можно TImageList использовать.
|
Цитата:
|
То есть нужно чтобы эффекты были нарисованными? т. е. не нужно их рисовать программно? ну тогда вот например как сделать молнию бьющию из одной точки в другую если мы не знаем ни длинны ни направления изначально. это зависит от координат где находятся противники. Под это уже не нарисуешь картинку. это нужно вырисовывать программно
|
Цитата:
|
С размером понятно. А вот с направлением не очень. Нужны изображения во всех направлениях-? то есть иметь пачку картинок с молнией с отклонением как в веере на 15 допустим градусов-? А применять ту или иную картинку в зависимости от угла между осью и вектором удара-?
|
Обычно молния бъет с неба на землю, все остальное - уже не молния, это типа огненные/ледяные/иные болты, энергетические стрелы и пр. плазма. Есть еще способ, нужно сделать анимацию некоторого среза молнии, потом передвигать эту анимацию от точки до точки причем не стирая предыдущие наложения. Тут нужно видение этого среза, можно по началу с примитивом, освещение в Фотошопе.
|
Игра как пример
Вложений: 1
Урок XXX
Тема: Игра Описание: Маленькая игра, в которой вы бегаете от человечка. Правила просты - продержаться до 6 уровня. Предоставляется открытый исходный код. Игра как пример работы с Bitmap и не только. В-общем, новичкам, я думаю, будет полезно. |
Вложений: 1
Цитата:
А скажите если вас не затруднит как то же самое но под разрешение 1024 на 768, я пытался сделать следующее: Код:
function SetFullscreenMode:Boolean; Код:
//настроим параметры буфера Создал карту размером 64 на 48 я так понимаю умножив эти значения на 16 получим 1024 на 768. И еще пробижался по коду и заменил где было 320 на 1024 и 240 на 768 однако саму игру отображает мелким размером а все остальное пространство белое.. Получается собственно что то похожее на это: |
Мне кажется нужно изменить размеры спрайтов, и кроме того, изменить пропорции отображения, там где умножается на коэффициент 16, если не ошибаюсь, поиграйся с ними, а еще лучше в место числа впиши переменную, меняя ее в одном месте везде будет правильный сдвиг.
|
С помощю какой програмы всё это делать? И где её можно скачать?
скаиньте ответ мне в почтовый ящик пожалуйста. |
Всем привет, у меня такая проблемма-->
Надо реализовать задержку при выполнении части процедуры, но так чтоб она не мешала производить другие манипуляции в программе.. напримере: procedure Primer(A,B:TClass; Memo:TMemo); begin Memo.Lines.Add(ShowMes(A.n,1)); sleep(800); while ((A.i>0) or (B.i>0)) do begin Memo.Lines.Add(ShowMes(A.n,2)); sleep(800); Memo.Lines.Add(ShowMes(A.n,3)); sleep(800); end; end; листинг процедупры находится в отдельном unit'е и вызывается таким образом: procedure TForm1.Button1Click(); var At,Bt:TClass; begin Primer(At,Bt,Form1.Memo1); end; Вобщем вместо Sleep(800), что можно придумать, чтоб оно не мешало работе с программой? |
Можно попробовать втсавить Application.ProcessMessage в тело цикла, но это мало поможет.
|
Цитата:
|
Игра на Canwas. Если игровой мир очень большей, то это дело будет не реально как-то загрузить. На загрузку карты в несколько то экранов уйдет много ресурсов. вот я думаю можно ли как то грузить только то, что находится в ближайшей видимости?
И еще если персонажей очень очень много в мире, то нужно обробатывать их всех на взаимодействие. Как можно сделать, чтобы проверялись на взаимодействие только те, которые находятся не очень далеко? |
Цитата:
Цитата:
00000000 00011100 00012100 00011100 00000000 0 - не загруженый участок карты 1 - находится в памяти 2 - участок в котором находится гг. Можно сделать, чтобы куски грузились в отдельном потоке, тогда можно избежать тормозов при переходе. Хорош для игр от первого лица, если добавить туман, который не позволит увидеть дальше загруженой области. 0000 0100 0000 Если в памяти держать всего один кусок, то придется ждать, пока загрузится следующий кусок, хоть в отдельном потоке, хоть прямо в игре. Но потребление ресурсов снизится. И этот вариант хорошо должен подойти для игр с видом сверху. Еще можно применить частичную загрузку всей карты. Определить на каждом участки карты расстояние до гг. при котором должны грузиться объекты. Например расстояние 50 участков, грузить текстуру низкого качества и город, 20 кусков, грузить 2D деревья и пара крупных камне...(этот способ для вида от первого лица) |
Очевидно, Лубышев намекает на РПГ, от третьего лица, карта ползет плавно в противоположные стороны перемещению, а персонаж все время в центре экрана.
Если персонаж игрока все время в центре, то самый верный способ следить за радиусом обзора и подгружать ресурсы карты по мере их видимости. Подгрузка секторов карты уместна для 3D игр, где плавающая камера может перемещаться вплоть до режима от первого лица. Если игра однопользовательская, то следить за всеми юнитами не нужно, можно лишь делать иллюзию изменения их состояния, как только взор главного персонажа достигнет их. |
Плавное перемещение юнита в игровой матрице и разрешение конфликтной ситуации с иными обьектами.
Всем привет!... Решился написать простенькую стратежку. Начал писать алгоритм на бумаге и возникло пару вопросов. Ломал голову дня 2 ничего оптимального в голову непришло!... вот подумал спросить у профессионалов...
Имеется игровое поле реализованное в квадратной матрице. После реализации алгоритма для поиска пути возникает несколько вопросов по плавному передвижению юниотов. ПРи движениии обьекта из пункта А в пункт Б возникла проблема алгоритма (будем считать что путь перемещения найден и записан к примеру в динамический массив). Пусть свободные ячейки помечены нулём, занятые иными номерами. Наш юнит к примеру имеет номер занятости 2 (если смотреть игровое поле). При плавном передвижении юниота в очередную ячейку(по найденому свободному пути) нееобходима переместить его не за один игровой ход а к примеру за 10 что соответствует его скороси перемещения, те за 10 шагов мы должны переместиться в искомую клетку., казалось бы никаких проблем если бы не 1 но!... Что делать если юнит произвел 4 сдвига (из этих 10) и графически со смещением находиться ещё в начальной позиции матрицы но при этом и до конца не достиг следующей клетки(те следующей ячейки матрицы в его пути). Он как бы находиться и там и там. И происходит некое событие. К примеру если эта клетка ещё не помечена как занятая то на неё могут претендовать другие юниоты как для перемещения так и для иных действий(??? это так ???). Вопрос что делать если в такой ситуации. На эту же (2-ю клетку) претендует другой юнит то есть он тоже хочет проити через неё или он например частично находиться на ней а частично на другой при этом для упращения будем считать что размер обьекта соответствует размеру клетки матрицы... пожалуйста если кто знает как реализоватьь алгоритм или какую - нибудь идею по этому поводу напишите пожалуйста. ПРи этом хочеться отметить что желательно бы учесть тот факт что хочу чтобы это всё выглядело более реалестьично поэтому будем считать что на одной клетке не могут находиться более 1 юниота. Хотелось бы хотяб услышать идею по этой теме или что ещё лучше простенький пример по этому поводу или алгоритм! |
Допустим размер ячеек 50 х 50.Юнит находится в ячейке с координатами (Х=100,Y=100) и должен переместиться на на соседнюю ячейку
(150,100).По событию (нажатие клавиши вправо) делаете цикл и даете приращение по Х на 5 едениц.Получите плавное перемещение юнита. Примерно так : Код:
for i:= 1 to 10 do |
Maxadal, все очень просто. Физически матрица - модель карты, сектора, грубые для графики. Каждый переход на клетку сопровождается плавным смещением объекта на 1 пиксел по-X и/или по-Y в нужном направлении, причем, графически мы точно знаем размер одной клетки на экране, допустим это 50х50 (таил). Достаточно задать цикл смещения на пол размера тайла, ...считается если объект находится в некоторой клетке со смещением 0, то он будет в ней находиться, пока смещение в цикле не станет больше пол размера тайла, в этом случае будет считаться, что объект перешел на следующую клетку, но при этом получил отрицательное смещение, которое будет стремиться к нулю (центру клетки на экране). Как только смещение стало равным 0, объект останавливается, если это пункт назначения в модели. Посмотри вот этот пост http://programmersforum.ru/showpost....&postcount=164 ...далее после него в разделе есть и пример.
|
Вложений: 2
Предыдущие 2 ответа на мой вопрос тривиальны и не несут всебе необходимую информацию о сложившейся у меня проблеме ((( ... возможно я что-то не так обьяснил... теперь решил прикрепить 2 изабражения для полной оценки ситуации в ходе программы.. на первом рисунке изображена часть игрового поля (карты)... в ней я взял 3 елемента матрицы.. в верхней и нижней ячейках находиться по юниоту ... во 2-м изображении я показал ход их движения.. допустим юнит перемещаеться за 10 ходов в соседнюю клетку, это его скорость... допустим первым движение начал юниот1(или оба вместе)... так как запись его положения в пустую клетку произойдёт лишь когда он или они сделают по 5 перемещений из 10, то возникает вопрос как помечать и использовать такие клетки(в который он или они перемещаються)???... красный движеться к примеру сначала вниз а потом направо, а синиq только вверх или ещё как-нибудь, при этом нехотелось бы чтобы они находились в одной клетке вместе, как быть с отображением такого участка карты ведь клетка по центру сначала свободна и на неё движуться 2 или 3 юнита... а потом 1 из них перевым записался вэту клетку , что делать второму???... идти назад или как??? нехотелось бы также чтобы изображения этих юнитов накладывались друг на друга, или если юнит двидежеться к примеру со смещением влево на 5 шагов то он естественно будет "задевать" соседние элементы, что если на них переместиться некий обьект???
|
Все именно так как и описал выше, ...ситуация один в один. Позиция в массиве - это не самый главный показатель присутствия на карте объекта. Это привязка к модели, модель - штука не визуальная, а вот смещение - это основной показатель, где графически расположен объект. Разбираем рисунки. Оба объекта одновременно идут навстречу друг к другу. Как известно, обработка объектов производится в цикле по очереди. Первым ячейку замет тот объект, что в списке объектов записан первее, ...сразу он получит координаты этой ячейки, но отрицательное смещение равное половине размера реальной клетки карты. Визуально он будет на пол пути до центра клетки, но по списку в этот такт обрабатывается следующий объект. В момент, когда смещение позволяет выполнить переход на клетку выше, условие видит, что клетка уже занята. В этот момент нужно останавливать движение нижнего объекта. В результате, верхний объект займет пустую ячейку массива, а нижний в массиве останется на том же месте, но графически по смещениям они встретятся на середине и остановятся.
|
Beermonza, это теперь понятно... спасибо обьяснил на пальцах))... а если предположить что к примеру верхний обьект идёт слева или справа а нижний двигаеться так же... ведь когда они начнут двигаться в одну и ту же клетку то получиться что они будут "наезжать" друг на друга углами(графически)??? ... если это так то что делать в такой ситуации???
|
Maxadal, обрати внимание, ...я в предыдущем посте употребил фразу "...условие видит, что клетка уже занята." - это система "радиуса обзора". Т.е. обработка каждого объекта включает в себя проверку соседних клеток и смещений объектов, что в них находятся. Это часть системы поиска пути. Частный случай, когда "верхний объект идёт слева или справа, а нижний двигается так же", как ты предположил, первый должен остановиться, если графическое смещение второго уже не позволяет первому пройти. Если пройти еще можно, то первый будет идти, а второй "наткнувшись" на недопустимое смещение первого, остановится, будет ждать когда путь освободится, или начнет обходить, ...но это уже к полноценной системе "поиска пути" относится. StarCraft припоминаешь? ...как там танк может проехать между двумя строениями людей, наехав гусеницами на спрайт строения :) ...недочет небольшой, ...да кому это вообще интересно ковырять, игра-то хит!
А что за стратегия, вид сверху, или изометрия? |
Я ещё на "измене"... ))) ... охота конечно изметрию... но с другой с тороны стоит попробовать что полегче... первый раз игру пишу до этого с графикой мало работал... хочу курсовой себе на такую тему попробовать написать ... теперь вот сижу думаю, что использовать DirectX или обойтись стандартными возможностями... спасибо за помощь...
|
за что функция отвечает?
Учусь использовать canvas по урокам, которые предоставлены в этой теме. В посте № 105 приведен пример игры, в которой шарик плавно перемещается по карте из клеток, созданной из массива. Разбираю код. Всё ясно кроме назначения этой функции:
Код:
function keypressed(key: byte): boolean; |
128 и 129 - это код не клавиши, а что клавиша с кодом key нажата, 128 - клавиша нажата четный раз, 129 - нечетный раз, оба значения - "факт, клавиша нажата". Также для не нажатой клавиши значение 0 и 1.
|
Теперь всё стало ясно. Спасибо
|
Кто знает как можно вывести часть спрайта в DirectX без использования directdraw ???...
|
Maxadal, к сожалению никак. Но если сильно нужно, то можно программно разделить одну большую текстуру на несколько маленьких или заранее раздробить на несколько файлов.(если Direct3D имелся ввиду)
|
Да я имел ввиду Direct3D... просто я незнаю как мне сделать прокрутку игровай карты если использовать DirectX ... и чтобы можно было невыводить часть спрайта... я просто незнаю как тогда организовать интерфейс меню в игре??? и вывод карты с прокруткой...
|
Эх, надеюсь не забанят.
http://delphideveloper.narod.ru/ Сайт на фреймах поэтому прямой ссылки дать не могу. Pascal/Delphi -> Delphi,Direct3D,2D -> 1. Определение поддерживаемых режимов монитора... |
Боольшое спасибо попробую разобраться)
|
Maxadal, это ты миникарту в уголку реализуешь или что?
|
Цитата:
Банальное нежелание пользоваться поиском по форуму... |
Выводить 2D на экран посредством Direct3D - это просто кощунственно по отношению к нему, и для каких грандиозных целей он был создан :)
Вообще все просто. Нужно создать большой спрайт участка карты, чуть больше экрана, и банально грузить на него изменяющуюся текстуру поверхности, которая строится исходя из модели поверхности под ногами. Камера, надеюсь, не плавает? В моменты перехода на клетку (а карта смещается так же как и объект, по клетке матрицы, с плавным смещением) происходит сканирование определенного участка матрицы всей карты (модель с параметрами, которой не видим) и вывод на наш фрагмент - спрайт видимого участка. Сама текстура собирается по кусам. |
Collision Bitmap'ов на канве
Столкнулся с проблемой. Как проверить столкновение объектов Bitmap на канве. В теории я понимаю, что нужно проверять на столкновение углы прямоугольников. Но, если, у меня есть объект Bullet (Bitmap - пуля) с координатами BulletX,BulletY, который я отрисовываю в буффер так Buffer.canvas.Draw(BulletX,BulletY, bullet) и объект Enemy, с координатами Ex,Ey , как должен выглядеть код?
Я пробовал,к примеру, так (проверка только по оси Y) Код:
procedure Collision1(); |
Цитата:
Ты просто скобку где-нибудь пропустил... :) Дополнение Так... А что это за условие такое странное "((BulletX,BulletY)>=(Ex,Ey)) or ((BulletX+10,BulletY)>=(Ex+40,Ey))" ..? Может лучше так: Код:
If ((BulletX+60>Ex) And (Ex+60>BulletX)) And ((BulletY+60>Ey) And (Ey+60>BulletY)) Then |
Все нужно выполнять в модели, а отрисовка подчиняется изменению состояния модели. Т.е. мы работаем с цифрами, ...в клетке X,Y должна лететь пуля в таком-то направлении, ...создаем ее на карте под кодом, задаем направление, допустим по-Y вверх, в таймере обработки всех объектов, объект "пуля" с текущими координатами X,Y отнимает от Y ее скорость Speed, и постепенно "летит" по матрице карты, начисляя себе смещения и сменяя клетку, как только смещение упирается в конец. Таким образом, тот кто попадет в одну из клеток на пути перемещения пули будет поражен, это из условия (если в клетке есть объект, то травмировать его). Графика строится в конце цикла обработки объектов, ...перебираются клетки карты, и если там записаны объекты, то нарисовать их с их свойствами, где был, какое смещение, какая анимация, какой кадр и пр. пр. пр.
|
Цитата:
|
Извиняюсь перед всеми, кому задурил голову) И снова DomiNick был прав. Пока не начертил на бумаге эскиз с координатами, не понял сути. Мне нужна простая коллизия по оси Y. Поэтому код такой:
Код:
procedure collision(); |
А вообще запомните такую формулу:
Код:
if (x>=objx) and (y>=objy) and (x<=objx+objwidth) and (y<=objy+objheight) then А попадание точки в окружность определяется так: Код:
if sqrt(sqr(x-objx)+sqr(y-objy))<=r then |
Спасибо. Пригодится
|
У меня один вопрос. Игра-стрелялка. Мне нужро сделать чтобы пуль вылетало бесконечно много. Рисую на Canvas. У пули есть координаты x и y, и таймер её прорисовывает туда, куда показывает x или y. Но пуля тока одна, а мне нужно много. Как это осуществить? Ставить бесконечно много обработчиков событий для пуль??
|
Цитата:
Код:
MasBullet: array [1..255] of Tbullet; |
Цитата:
При выпускании пули она добавляется в конец списка, при попадании, она удаляется их списка. (т.е. функци-обработчик пуль работает не с каждой отдельной пулей, а со списком пуль). К стати, таким же способом можно сделать бесконечное число простивников. (хотя противников я бы делал классами, что бы каждому можно было сделаь индивидуальное поведение (ну что бы они не по прямой летели, а зигзагами, стреляли и т.п (впрочем если делатьк акие-то специфические патроны (типа самонаводящихся ракет или осколочных гранат), тот тут тоже классами делать нужно)).) |
А как это списками? Чо то я не вкупил.
|
А в какой программе это всё прописывать?
|
В данном разделе все делается на Делфи.
|
Вложений: 1
Цитата:
________ А это упрощенный TList: |
Универсальная проходимость карты
Никак не могу осилить. Как задать универсальную проходимость на карте? Изучил все примеры, которые находятся в этой теме. Неужели нужно делать ДВА массива карты? Один под проходимость, а другой под текстуру. Имееется ввиду карта с большим колличеством текстур и с разной проходимостью. Я понимаю как задать проходимость и текстуру на один индекс. То есть, если из файла считал индекс "1", то: ходить нельзя, текстура 1.bmp. В то же время прописывать под дополнительные обозначения свою проходимость мне кажется неправильным. К примеру, если карта имеет такой вид в текстовом файле:
11111111111111111 10000000000000001 10244300000000001 10000050000000001 10000005000000001 11111111111111111 Места под номерами 2,3,4,5 будут НЕ ПРОХОДИМЫМИ и все будут иметь разные тестуры. Как в таком случае будет выглядить код? Если создать тип карты: Код:
type Код:
var сответствовать индексу текстуры: Код:
//............................... Код:
if p=1 or if p=2 or if p=3..... then |
Цитата:
|
Цитата:
|
Про загрузку и использование текстур и проходимости...
Это пример с поста #102, если не ошибаюсь. Пример простейший. Задача стоит по-иному: если много текстур, как вместить проходимость?
Будем предельно точны, расширим представления о системе хранения текстур и проходимостей. У нас есть база текстур, в виде одномерного массива, в котором загружены все текстуры, что есть на карте, ...как? ...пробегаем по массиву карты, что был загружен с файла, смотрим каждую цифру, и записываем последовательно в массив Bitmap с файла текстуры. Дополнительно в коде каждой клетке зашифрована и проходимость, ...как? ...допустим мы берем 256 текстур - это много, половина из них проходимые, половина нет, или даже 3 степени проходимости: 0 - можно идти, 1 - нельзя ни при каких условиях, 2 - можно при определенных условиях. В итоге у нас: 0 - 99 - номера текстур, по которым можно ходить; 100 - 199 - номера текстур, по которым нельзя ходить; 200 - 255 - номера специальной проходимости. Вернемся к загрузке текстур. Проверяя очередную клетку выполняем условия: если число < 100, то ставим в запись проходимости 0; если число > 99 но < 200, то ставим в запись проходимости 1; если число > 199, то ставим в запись проходимости 2; Попутно с файла загружаются текстуры с именами, равными числам, таким образом тип банка текстур становится справедливым: Код:
type Код:
TexMas: array[0..255] of TTexBank; Код:
Type Код:
MapMas: array[1..20,1..15] of TGameMap; Код:
Buf.Canvas.Draw(x,y,TexMas[MapMas[i,j].Index].Tex); Как записать на карту числа уже весом в 3 байта? (0 - 9 весят 1 байт, 10 - 99 весят 2 байта, 100 - 255 весят 3 байта) ...ответ в вопросе, перейдем к хранению данных в байтах: Код:
MamFile: File of Byte; |
Огромное спасибо. Я думаю, этого достаточно. Осталось переварить информацию
|
Цитата:
001 002 003 055 066 077 111 112 113 114 115 116 117 118 119 120 121 122 а потом связывать текстовый файл с файлом байтов (MamFile: File of Byte;)? Код:
AssignFile(MamFile,'lvl.txt'); |
Цитата:
Если файл байтовый, значит он содержит байты, которые представляются в виде символов, каждый из которых может определять число от 0 до 255. Если открыть любой файл EXE в проводнике, то можно увидеть кучу "иероглифов" - это и есть представление чисел типа Byte. Цитата:
[hщык$4KЏЂуU¬«@c Заметно разницу в весе? ... 18 байт, ...у тебя 72 байта (переходы на строку тоже в счет), и при том, что карта мизерная совсем. Всегда следи за "весом" ресурсов, негоже раскидываться памятью, если в том нет надобности. Значит все байты идут подряд, без пробелов, ...мы же четко знаем, что один байт - одна клетка, ненужны пробелы, будем выполнять команду чтения одного байта Read. Записываем в цикле: Код:
for i:=1 to 20 do |
Уважаемый Beermonza, спасибо за разжевывание информации. С байтами я уяснил преимущества. Создал редактор карты и с его помощью записываю в одну строку байты в текстовый файл карты.
Цитата:
|
Подробно о заполнении банка текстур...
Сначала как всегда "на пальцах" немного теории. Цель - загрузить текстуры в банк, исходя из кода, считанного с файла, и не допустить дублирования, если в этом нет надобности. Логически все выглядит так. У нас есть некий файл карты, мы можем его "читать" по одному байту. У нас есть одномерный массив, в который мы будем записывать текстуры. Очевидно, что понадобится перебор банка текстур, с целью поиска уже существующей текстуры по коду карты. А если текстура так и не была найдена на переборе до ближайшей свободной ячейки банка, то значит нужно записать ее в эту первую свободную ячейку, после всех занятых. Чтобы долго не кувыркаться со стандартными командами, добавим в тип банка две записи Name и TexUses:
Код:
type Код:
for t := 0 to 255 do Код:
for i:=1 to 20 do С переходами GoTo работать просто, нужно только указать в процедуре, перед ее началом (begin) запись метки: Label M; |
Вложений: 3
са сейчас мучаюсь пока ничего невышло если выйдет напишу как смастерил, по последнему посту вообще неполучаеться хотя подход правельный я всё понимаю но реализовать немогу программа не та.
щас пользуюсь просто вот таким масивом Код:
map: array of array of byte; а в программе уже зависимость от проходимость про проверке след клетки да вот мой цикл считавания: Код:
Reset(f); вот что у мну получаеться КОРОЧЕ МЕНЯ ВСЕ уже достало дайте простой пример проги чтобы просто загружалась карта пусть даже с 2 обьектами, любое управление 1 обьект фон 2 ой непроходимый так будет понятнее |
Прозрачность спрайтовой анимации
Вложений: 1
Разбираюсь со способами вывода анимации на форму при помощи спрайтов, размещенных в едином Битмапе. У меня при выводе анимации каждый последующий кадр просто накладывается на предыдущий. Не могу понять как в таком случае затирать предыдущий кадр фоном? Код такой:
Код:
var |
Вложений: 1
щас выложу пример там всё расписано с этим у меня проблем нету а вот с мапой никак не разбирусь ппц(
вот код и пример: Код:
// "кидаем" в буфер кадра задний фон карты |
Спасибо. Пример Очень расширенный) На самом деле всё оказалось проще чем я думал. Нужно создать дополнительный буффер, в котором задается прозрачность и её цвет. В этот буффер отрисовывается кадр, а буффер рисуется в основной буффер программы.
|
это уже давным давно надо было использовать с сапого начало создать буфер и внём могое отрисовывать у можеш небольшой пример загрузки карты привести или сказать что в моём непрально? щас выложу
у меня или нерисуеться вообще или ошибка в самом приложении когда её закрываеш то она исчезает вот он по моему всё должно строиться: Код:
unit Unit1; |
Вложений: 1
Вот тебе пример построения карты. Взят из этой же темы из ранних постов. Карта представлена не байтами. Всё проще. Изучи.
Твоя ошибка в том, что ты взял усложненный готовый код программы и пытаешься его адаптировать под свою программу. |
Цитата:
Я СДЕЛАЛ грац меня:) короче говоря я просто напросто не считывал и всё:) нада было добавить цикл для считывания хотя в примерах его нету и как оно пашет я хз( |
IvaniuS, а зачем для построения карты нужен таймер?
Цитата:
Происходит так: 1) По кускам собирается задний фон, один раз для определенного участка карты, и хранится пока не будет произведено смещение по карте; 2) Фон перекидывается в буфер кадра каждый раз вначале цикла отрисовки каждого кадра. Он кладется поверх, затирая все что было в буфере; 3) В цикле накладываются спрайты объектов, с анимацией или без. Каждый спрайт, суть, Bitmap, ему можно задать прозрачность и ее цвет. 4) Через Canvas или BitBlt() буфер кадра выводится в форму. |
Цитата:
у меня после всего а у меня все получилось даже больше есть 2 вопроса: 1:проблема с размером бмп хочу использовать 64х64 рачество заметно возрастает весит мало под сжатием а он отображаеться как 16х16 всеравно, как в программе это изменить? 2:проблема с масивом типа байт если обьектов много больше 10 что делать? трехзначные использовать значения чтоли или двух? а уже к ним присваивать название? это же полный бред, как-то видел прогу "моя третя гра" там какойто формат карты очень хороший хочу типа такого прогу сделать ОТВЕЧАЮ НА 1 ВОПРОС СВОЙ: у каждой текстуры есть "программный размер" Tex.Width Tex.Height которые можно менять |
Цитата:
1. Простой вариант: при использовании на карте символов char (map: array [1..X,1..Y] of char; ) можно кроме цифры использовать латинские символы a,b,c,d...z 2. Вариант посложнее: отлистнуть страницу назад и изучить информацию с поста 267 |
Цитата:
|
Цитата:
1) Посмотри как ты использовал отрисовку: Код:
case map[x,y] of 2) Смотри посты #265 - #270 Послесловие: IvaniuS, пиши грамотно. |
к счастью я вчера ночью разобрался со всем косаюмщимся карты,
нашёл замену размеров и многое другое точ но нужно было, сейчас видел редактор он записывает в файл через пробел числа которые что-то означают согласитесь небольшая карта весит 25Мб + это непонятный набор цифр. ВОПРОС: нельзя использовать карты сторонних разработчиком например КС, ВАР-КРАФТ, ЕЕ1-3(Емперия), Диабло и т.д. можно до бесконечности перечислять и как их использовать т.е. это нужно искать исходник и разбираться или разбирать саму карту или сторонние компоненты? |
Всегда нужно разрабатывать свой способ, в зависимости от требований. Все прочие готовые варианты - это ресурс тех самых игр. Лично для меня их применение у себя - кощунство.
|
у меня нет времени и возможностей(не ресурсов заметте) чтобы создавать собственные модели, текстуры, и пр. поэтому ищу альтернативный вариант знаний в рисовании и моделировании достаточно свои модели персонажей и текстуры давно внедрил и с радость смотрю в Лайнейдж 2, поэтому горю желанием даже от тудова использовать персонажей и текстуры.
к завершению поста скажу что в графиге не ГДИ а именно ДИКС вообще ноль только неделю что-то разбираюсь поэтому хочу и мотор внедрить Анриловский Добвлю нашел заменю 3Д на гди т.к. у меня с геометрие й проблем нету вот пример системы координат для игры: Код:
/-------/ ВОПРОС: ЕСЛИ СОЗДАВАТЬ СВОЙ РЕДАКТОР С ОБЬЕКТАМИ БОЛЬШЕ ЧЕМ 10 ЧТО ДЕЛАТЬ ПЕРЕДХОДИТЬ к интегеру или стрингу хочу пейти к ини в нем записывать название обекта все координаты его создание и его размеры это можно сделать? |
Хорош флуд разводить :) ...тема не та, ...посмотри "Как вы относитесь к созданию игр на Delphi?", наша команда делает 2D в изометрии, выглядит тем же 3D, но камера не плавает. Этот пост не в тему последний.
|
Canvas тормозит или я?
Вложений: 1
Вроде бы ознакомился со всей информацией, что есть в нашем разделе. Но всё же решил переспросить. У меня в примере Tbitmap отрисовывается через буффер, но при быстром передвижении явно заметны мелькания изображения. Это означает, что я неправильно где-то отрисовываю или canvas даже через буффер так медленно работает?
Вот код отрисовки: Код:
procedure TForm1.Timer1Timer(Sender: TObject); |
А у меня ничего не тормозит.
|
Цитата:
|
Нет, не происходит.
|
Цитата:
|
Странно, я явно вижу рывки при перемещении. У меня железо нормальное. Atlon 5.2, Video Radeon 3650, 3 Gb оперативной
|
Алекс Ялта, у таймера какой интервал? ...извини, исходник не смотрел.
|
Таймер интервал в 1 мили секунду установлен
|
Цитата:
Давай вспомним сколько кадров достаточно для нормального восприятия движения объектов в 2D глазом человека. 24 кадра, но поставим умышленно 30 кадров. Поделим одну секунду на 30, получим приблизительно 33 мс (1000 мс / 30 кадров). ОС работает с графикой в форме сносно не быстрее чем 30 кадров в секунду, при больших изображениях, ...это проверено. Значит нужно ставить 33 мс интервал в таймере, а от лишних Canvas'ов нужно избавляться. |
Вложений: 1
Загрузку процессора через диспетчер задач установить мне не удалось. Выдает при работе приложения 0-1% (Может из-за того, что процессор не слабый). Файл подкачки увеличивается на 3Мб.
Я пытался избавиться от мелькания путем установки интервала таймера в 33 Мс. Мелькание действительно исчезает, но при этом, соответственно, падает скорость перемещения объекта. После, я выделил обработку перемещения объекта в отдельный таймер с интевалом в 1 Мс, а отрисовку оставил в первом таймере с интервалом в 33 Мс. Мелькания стали чуть менее заметны. Выходит, что проблема может скрываться в черезмерном использовании canvasa? Но я не могу понять каким образом можно избавиться в том коде от лишних canvas? И какой из них является лишним? Вот весь исходник |
У меня опять ничего не мелькает...
Я изменил вот это начальную строку в таймере Код:
procedure TForm1.Timer1Timer(Sender: TObject); |
Хочу сделать игру с использованием WinAPI. Но не знаю ничего про вывод графики, если писать всё с нуля. Может кто-нибудь написать урок про вывод графики, используя WinAPI?
Заранее спасибо |
Цитата:
Потом После этого выбираем в Object TreeView форму (Form1) Ну и это 4)В Object inspector на вкладке Events ищем свойство OnKeyDown и щёлкаем на него 2 раза. 5)В созданной процедуре пишем код (я рекомендую вам не просто копировать а понять как это работает!) расскажите что и куда кликать |
Падскажити плиз как сделать чтоб объект не только ездил при нажатии кнопок но и поворачивался на N угол если к примеру зажать стрелку влево
|
Цитата:
http://www.programmersforum.ru/searc...earchid=233664 |
Вложений: 1
Цитата:
Object TreeView находится по умолчанию в левом верхнем углу, под меню. Object inspector располагается по умолчанию сразу под окошком Object TreeView (в левом нижнем углу). Что и куда кликать уже рассказали, смотрите внимательно и кликайте) |
Вложений: 1
Алекс Ялта, посмотрел твой пример с космическим корабликом. Можно ускорить намного и сделать так, чтобы не было рывков при движении, ...но это уже тема не для новичков, там GDI и ассемблер.
Можно посоветовать хранить каждый кадр кораблика в отдельной ячейке массива типа TBitmap. Вот эта строчка будет ненужна: Код:
ShipBuf.Canvas.CopyRect(bounds(0,0,64,64),ShipSprite.Canvas,bounds(k*64,str*64,64,64)); Код:
Buffer.Canvas.Draw(px,py,ShipBuf); Код:
Buffer.Canvas.Draw(px,py,ShipAnimMas[{код направления},{номер кадра}].Tex); |
Цитата:
P.S. На данный момент изучаю основы работы с сетью на компонентах ClientSocket - ServerSocket по Вашим примерам (http://pblog.ru/?p=91). Кстати, полезнее и доступнее пока примеров в инете не нашел. Так что и за это тоже спасибо) |
Цитата:
|
Вот тут хороший исходник http://gigapeta.com/dl/196396ab01834. Показывает все основные методы программирования графики. И весит немного.
|
Не могу понять что за ошибка
Вложений: 1
Решил написать свою первую игру, ближе к сердцу аркада.
Взял за образец Игру от Kostia, пост № 106 (Огромное спасибо, надеюсь авторских прав не нарушил :d ) почитав здесь хорошенько, усложнил код: Не могу продолжить из-за того что : 1 когда нажимаешь пробел много раз 2 когда нажимаешь пробел и Юнит бьется головой о потолок Выходит ошибка: Цитата:
Код:
mapbmp.Canvas.draw(round(xp-20),round(yp-20),SpArr[UnitSplineN]); Код:
unit Unit1; P.S. Заранее спасибо. |
Брр! Я сейчас и в своем коде не разберусь. Вы лучше начните проект заново. Писать не много и пользы больше!
А еще лучше, если вы в тетради изложите свои мысли в словесно-математичеко-формульной форме. У вас наверняка возникнут вопросы и вот их спросите на форуме, а когда закончите с тетрадью, переводите словесную-математическую-формульную форму на язык программирования. |
Спасибо вам Kostia за совет, в тетради всё действительно понятней.
Я исправил ошибку Код:
//прыжок GetUnitState Параметр задавал тип анимации 3 (анимация прыжка) для юнита, но анимации этой я не сделал. Код:
case GetUnitState of Цитата:
Просто если я начну писать всё заново, то именно того что есть сейчас, я повторить не смогу. А на сегодня у меня в игре есть Редактор карт, два Бонуса (скорость, прыжок), и два ... не знаю как назвать вообщем Шипы и анимираванный Огонь. |
Цитата:
|
Вадим Буренков, в теме "Как Вы относитесь к созданию игр на Delphi?" с поста #46 читай подряд, найдешь создание буферов, отрисовку, перебрасывание подложки в кадр, и много интересного и поучительного.
Здесь описывать не буду, да и не имею право, ...тема не та, чтобы такие сложность показывать. |
Я там найду как выводить графику на Canvas без тормозов и ряби?А то мне не хочется убивать весь вечер на чтение 265 топиков и так ничего не добиться.
Проблема в том, что в Canvas меня устраивает все, кроме скорости вывода графики.Я использую два буфера и это дает результат, но не достаточный. |
Цитата:
В общем флуд тут не разводим (в данной теме это все флуд), все вопросы по этому поводу в соответствующей теме "Как вы относитесь к созданию игр на Delphi?", там опиши свою ситуацию, что отрисовываешь и как, постараюсь помочь. |
Года 2 назад изучал Delphi (Имею так сказать базовые знания (циклы процедуры и т.д )) .Случайно зашел на форум, прочитал тему от начала до конца и заинтересовался этим делом:) Скачал программу из поста №106.
Посидел пару-тройку часов(а могет и больше :p:p) поразбирался во всем этом( должен заметить где-то на 90% алгоритмы, функции , логика оказались не понятными).Сидел разбирался до тех пор пока не написал комментарий почти к каждой строке (спасибо Google за помощь).В итоге с n-ой попытки смог осознанно воспроизвести где то 95% кода. Решил что пожалуй можно чуть чуть потренироватся в расширении данной программы( так сказать для закрепления знаний). Увеличил размер карты, количество текстур( и тому подобная мелочь).Написал код все заработало но.... Но Написать заного то что уже видел раньше(хоть и осознанно) легче чем написать свое:) Сразуже неполучилось написать карту: -вопрос : Вроде как карта в обычном блокноте написана, задана числами(в примере) . Написал я такуюже с новыми размерами но возник вопрос как перейти на новую строку без того что бы в итоге в программе не было 2 пустых клеток? |
Выкладывай наработки, глянем что там "творится".
|
Вложений: 1
Вот .
Единственно я изменил размер клетки на 20. Может поэтому и такие проблемы( хотя картинки тоже сделал 20х20) Карта примитивная просто для проверки) |
Так и думал, а кто будет менять размеры самих массивов? А лучше сделать все это дело динамическим!
В общем блокнот кажет, что в нем размер карты 52*21, а массив: Код:
map: array[1..50,1..20] of char; |
В общем с этим вроде как разабрался( проблема была в самой карте(я ее 51х21 сделал) + я написал <=50 в процедуре loadlvl) что и привело к появлению 2 лишних клеток по Х.
p/s Пользоваться Tlist не хочу ибо в данной теме не нашел не 1 его применение(вроде читал внимательно) а без примеров сам многое не сделаю. Использование динамических массивов даже не представляю как тут реализовать))) ( все же я еще не достаточно силен в программировании, может как наберусь опыта буду использовать) Пока буду пользоваться таким методом(все таки были приложены усилия в его освоении, и теперь на что то переключится на другое обидно))) p/p/s Да и спасибо за быстрый и понятный ответ)) |
AvaMight, всегда в карте первыми байтами идет размер карты, при считывании с файла, размеры записываются в переменные, которые используются в циклах, ...никаких ошибок в кодах не будет, разумеется, если массив предусматривает все размеры карт, можно динамикой не пользоваться, но по-уму стоит пользовать динамический массив.
|
Проблема:
Решил добавить звуки в игру. (Ну например звук выстрела по нажатию) Пробовал стандартными средствами – не получается :( Хотел использовать PlaySound но звуки воспроизводятся не моментально и игра подвисает пака не пройдет звук. Хотел использовать поток для этого, опять не то. Какие есть решения? 1.Нужно чтобы звуки моментально воспроизводились 2.Нужно чтобы игра при этом не подвисала 3.Нужно чтобы звук воспроизводился неоднократно, т.е. если выстрелил и пока еще шел звук, если еще раз выстрелил еще раз воспроизвелся. 4.А вообще было бы шикарно, если бы одновременно с этим играла бы музыка и, если бы поразил выстрелом врага он бы тоже издал какой-нибудь звук. |
PlaySound('Sound.wav', 0, SND_ASYNC);
Так всё происходит синхронно с программой. Можно, наверное, использовать также FMOD(про него в теме: "Моя первая аркада на Delphi. Демка") |
Замечательно, хотя что то все же не так... немного притормаживает.Стандартные альтернативы есть?
А как сделать чтобы одновременно несколько звуков воспроизводилось? например все это происходит на фоне музыки? |
Я этого не знаю, но делаю по другому. Через mediaplayer играет фоновая музыка, а через PlaySound уже отдельные звуки.
|
Я тоже так же хотел сделать... Но если целый ряд звуков надо воспроизводить то не целый же ряд MP делать...
(Играет музыка, раздаются выстрелы, если попал то враг стонет, кричит и тому подобное..., раздаются прочие технические звуки) |
В DelphiX есть компонент, SoundList, кажется. Так вот с его помощью можно проигрывать несколько звуков сразу.
|
Да, в DelphiX есть два компонента, обертка для DirectX. Движок - DXSound, и архив DXWaveList. Можно использовать формат .dxw, ...что это я к сожалению не в курсе, а вот вавчики работают как надо.
|
Я предлагаю свой простой вариант проигрывания звуков одновременно и без тормозов:
(пост №20) |
С мгоей точки зрения лутше использовать GL scene
|
Проиграть два звука одновременно
Код:
uses |
спасибо за уроки!
|
воттакая вот цетата:
На самом деле всё оказалось проще чем я думал. Нужно создать дополнительный буффер, в котором задается прозрачность и её цвет. В этот буффер отрисовывается кадр, а буффер рисуется в основной буффер программы. если у когото есть время покажите пожалуйста как этот буфер с невидемостью сделать. |
Tank.Transparent:=true - где танк это твой игровой объект. Это делает вокруг танка фон прозрачным. У имиджа точно также, только вместо Tank - Image1. Буффер делаешь так:
Код:
Buffer:Tbitmap;//создаешь переменную Вот возникла проблема. У меня есть здание которое не умещается в одну клетку карты(100 на 100). Когда я прохожу перед ним то у меня персонаж рисуется на переднем плане а здание на втором. Но мне нужнно пройти за ним, и для этого нужно чтобы здание было на переднем плане а перс за ним рисовался и его скрывало зданием. Как это реализовать? |
Сначала рисуйте персонажа, а затем - здание.
|
На буфере последовательно рисуем фон, персонаж,здание и выводим этот бутерброд на форму.
Arigato быстрей оказался. |
Ну это то я знаю. Но вопрос в другом. Как сделать так чтобы в некоторых случаях персонаж скрывался зданием?
|
Цитата:
|
Цитата:
|
спасибо за буфер! очень поиогло!
|
Есть способ еще проще, ...следишь не за координатами объектов в массиве объектов, а проверяешь карту по ячейкам, от левой верхней, до правой нижней, т.е. за фрагментом карты, которая влезла в экран. Далее, значит перебирая ячейки карты смотришь запись "объект", там указан индекс на массив объектов в игре, по этому индексу отрисовываешь объект на карте, в текущей ячейке. Здания - если они крупнее, у них есть смещение спрайта, стоять они будут в конкретной ячейке карты но за счет смещения, их клетка будет в центре самого здания. Как движущийся объект не будет передвигаться, отображение всегда будет верным. Но нужно иметь в виду, что вокруг клетки здания нужно ввести "мертвую зону" в аккурат по периметру видимого силуэта (в изометрии по основанию).
|
Я нашол много хороших примеров движения перса за мышкой, но как можно научить его обходить преграды?
Есть идеи? |
Все азы и примеры в этой теме, ...тебе нужно конкретно? ...читай тему: http://programmersforum.ru/showthread.php?t=50504
|
Скинте пожалуйста кто то код простейшего редактора карт.( потихоньку пишу игру но карты надоело в блокноте рисовать :) )
|
|
Извеняюсь там только exe файл.Мне же нужен сам код если не сложно. Хотелось бы разобратся с самим механизмом создания редакторов.
|
Прошу помощи.Подскажите хороший движок для игры DelphiX GLScene и OpenGl не предлогать.Чуть незабыл 3д движок
|
|
У меня вопрос как пользоватся GLScriptLibrary можно статью какую небуть или код.
С уважением Alex2009 |
у меня при написании кода
for i1:=1 to 500 do for i2:=1 to 500 do begin map[i1,i2].pict:=Tbitmap.Create; map[i1,i2].pict.width:=35; map[i1,i2].pict.height:=35; map[i1,i2].pict.LoadFromFile('1.bmp'); form1.Canvas.Draw(i1*35-35,i2*35-35,map[i1,i2].pict); end; возникает ошыбка 'неверний деструктор' что это значит и как этого избежать |
Умножь 500 на 35, получишь недопустимый размер буфера канвы и по длине и по ширине. Отталкивайся от математики, дели разрешение экрана на твои 35 и получай истинный предел цикла по i1 и i2.
Не засоряем тему мелкими вопросами, создавайте отдельные темы, ...эта тема для разбора фундаментальных приемов построения игр. |
Думаю в этой теме не будет лишней книга по программированию стратегических игр с DX9
|
Alex2009, покопай в сторону DGLEngine.
|
Подскажите пожалуйста как можно вывести полосу жизней над персонажем,единственное что мне пришло в голову рисовать через канву , но это не очень удобно. Есть другие идеи?
|
Если элементарно совсем делать, то стоит просто один раз подрисовать полоску в кадры анимации над персонажем, и выводить как всегда без лишних действий иначе, постоянная прорисовка загрузит машину без надобности. Только когда нужно изменить количество жизни - выводить процедуру перерисовки полоски, также на все кадры один раз.
|
Игровое окно с изменяющимися размерами.
Вложений: 1
Понял интересную вещь. Даже в играх на канвасе можно сделать игровое окно с изменяющимися размерами (как в OpenGL), например как на скриншоте.
Вместо вывода подготовленного буффера на форму процедурой: Код:
MainForm.Canvas.Draw(0,0,Buffer); Код:
MainForm.Canvas.CopyRect(bounds(0,0,MainForm.ClientWidth,MainForm.ClientHeight),Buffer.Canvas,bounds(0,0,640,480)); Единственная проблема это потеря качества :( . |
Можно, но это немного не то. Там меняется разрешение экрана, если полноэкранный режим, а если в окне то я не встречал чтобы можно было растягивать. Кстати рисуя на канве тоже можно разрешение экрана менять, одно другого не касается.
p.s. Более красиво масштабирует StretchBlt из WinApi. Но это все более актуально для GUI прикладных программ, а не для игр. Для игр видеокарта есть, имхо. Хотя сам я на канве делал игры, но пригодились эти навыки именно в прикладных программах, с этими знаниями у вас развязаны руки в плане интерфейса. |
StretchBlt еще хорошо с SetStretchBltMode() использовать, в режиме HALFTONE, картинка будет сглаживаться при масштабировании.
|
Цитата:
|
Вадим Буренков
А сама игра на OpenGl или DirectX? |
Цитата:
|
как это потом перевести во swf и с помощью чего помогите пожалуйста.знаю что так делают но не знаю как это сделать
|
Вадим Буренков есть программа в интернете что бы улучшать картинки поищи .я если вспомню сайт то тебе скину
|
-=DeS=- у меня вопрос где находится обьект TShape
|
Вкладка Additional, 7-й по счету.
Вообще с подобными вопросами впредь в раздел "Общие вопросы Delphi". |
Народ,помогите плиз.На странице 9 этой темы был выложен исходник хода коня для шахмат.Начал разбирать его.Там есть такой код.
Код:
......... Код:
........... |
Почему это не может быть отрицательным?
|
ну насколько я помню диапазон чисел типа byte 0..255.Да и в учебнике так написано.
|
Ну про крайней мере будет перебор и ты получишь число 255 (256 + (-1)) помоему :) Возможно на это авторы и расчитывают.
|
А помоему там сказано что -255 - +255
|
нет,точно от 0 до 255.Это и у Сухарева и у Культина в учебниках
|
Числовые переменные типа Integer, Word или ShortInt и Byte можно приравнивать друг к другу, только вот если будет нарушен диапазон например Byte (0 - 255), то значения будут вырезаться относительно битов. Если приравнять числу типа Byte переменную типа ShortInt значение которой минус один (-1) то значение переменной типа Byte будет 255.
Так же все эти переменные переводятся в строковый тип одной и той же функцией IntToStr(); Смотреть нужно внимательно, и не допускать прохождения в код вычислений некорректных присвоений, ...только в условиях, как флаги, и то, спорный момент. |
Соблюдайте правила
Убедительная просьба ко всем создающим здесь сообщения, пожалуйста не задавайте мелкие вопросы общего характера "как нажать кнопку", "не могу запустить код", "как заставить панель двигаться по экрану", "как вывести в Image картинку из файла" и пр. Для этого есть раздел "Общие вопросы Delphi". Если ваше сообщение касается игр, и есть частный вопрос, создавайте новую тему. Здесь же задаются глобальные вопросы, вопросы по уже имеющимся урокам, размещаются статьи и уроки касающиеся создания игр простыми способами, или способами средней сложности.
|
Кто-нибудь может написать о создании сетевой игры небольшой урок(для Дельфи, не браузерную)? Какие компоненты использовать для содинения лучше(ведь их много, многие разделены на 2 части - клиент и сервер, как организовать перебор адресов/портов), как организовать ходы лучше(например нужно ли создавать объекты для других игроков или ограничиться изменением картинки и параметров), как будут соотноситься компьютерные противники(монстры) и персонажи(вероятно на сервере должны ходить монстры), как организовать сервер(например можно на простом хостинге создать демон-скрипт, который будет раздавать информацию клиентам, или в любом экземпляре программы лучше создавать сервер, к которому напрямую будут подключаться желающие, или есть постоянный хостинг(про хостинг я говорю как про бесплатную, хоть и ограниченную возможность создать игровой сервер) на который будут поступать запросы клинтов о подключении/создании экземпляра игры(карты), а он будет только рассылать информацию клинтам о друг друге(ип и порты), чтобы программа потом сама соединялась)? В общем какие-то основы расскажите. Уф-ф-ф. Вроде написал. Понимаю, что читать сложно, поэтому ввел начертание.
p.s. если что, за грамматику извините. Предупреждаю сразу)) |
L_M, разбор создания сетевых игр уже противоречит названию этой темы, т.е. не для новичка это дело.
|
L_M
Создавай новую тему в таком случае. |
Я хочу сделать игру типа "танчики", для двоих человек, перемещение танков я могу сделать...а вот как сделать стены комнаты...предположим они будут картинками, но стен много, а значит много и картинок, а проверять на столкновение каждую стену - это как-то муторно...
Подскажите пожалуйста.Заранее благодарен. P.S. И еще хотелось бы узнать, как сделать так чтобы картинка пули постоянно создавалась....т.е. существует 1 объект - пуля, а как сделать так, чтобы могла вылетать несколько пуль одновременно? |
Самый подходящий для этого случая вариант, это использовать перемещение танков не по пикселям, а по клеточкам. Читай выше, здесь это уже обсуждалось!
|
Цитата:
Цитата:
|
Цитата:
|
Как пример:
Код:
unit Unit1; |
Решил перевести систему координат в своём игровом проекте, и возникла куча вопросов. У каждого объекта есть координата (50*m; 50*n), где m и n - элементы массива. Массив динамический: matrix: array of array of smallint;
В-общем, не стоит говорить и спрашивать насчёт этой системы хранения карты, отрисовки на экран и создания "подложки" (Спасибо, Beermonza, метод всё-таки действительно помог). Поговорим о новом способе. Итак. Теперь карта (лучше говорить матрица) объектов представляет из себя такую структуру: Код:
type Код:
for i := 0 to LengthX do // Длина массива Если вы располагаете информацией насчёт этого, напишите пожалуйста в этой теме подробный ответ, буду очень благодарен. Спасибо. |
Все станет ясно, если вспомнить что карта - матрица. Что есть в матрице? ...ячейки. Что есть ячейка? ...элементарная запись некоторого кода, или индекс на банк ресурсов. Например карта - матрица типа Byte, на каждую клетку приходится 1 байт данный, или индекса, ...т.е. закодирован 1 из 256 возможных объектов. В матрице есть столбец и строка. Допустим, карта имеет размер 100х100 клеток. Здесь видно координаты объекта? ...видно, т.к. мы точно знаем какого размера элементарный тайл клетки карты. Нужно всего лишь умножить порядковые номера в столбце и в строке на высоту и ширину текстуры тайла карты. Что и применил Манжосов Денис
Цитата:
Цитата:
Это все сохраняется в формате File Of Byte. При считывании мы точно знаем, что первые два байта - это размеры карты, применим эти данные к циклу считывания как его границы. Так же просто в цикле считаем данные посредством команды Read, она не привязана к размерам матрицы и будет при каждом шаге цикла брать следующий байт в файле. Что получается. Карта есть, считывание есть, ...нужен банк текстур и система их правильного использования. Нет ничего проще. Создаем систему каталогов. Называем ее как нам нужно, один из каталогов - каталог текстур, в нем 256 файлов, которые так и носят имя в виде цифр. Вместе с ними идут допустим текстовые txt или ini файлы с данными, как правильно пользоваться текстурой, с тем же именем. Что происходит? ...при считывании карты с файла, и взяв индекс объекта, мы точно знаем как он называется, и где лежат его ресурсы. Код выдергивает с каталога все данные по имени файлов и загружает их в одномерный массив банка текстур, в первую свободную ячейку. Разумеется тип банка текстур нужно создать, чтобы в нем были все данные для обработки и отрисовки. Как только ресурс загружен, в массиве карты, вместо индекса объекта записывается номер ячейки в банке текстур. Зачем это делается? ...если в карте есть одинаковые объекты, то код найдет этот ресурс в банке и укажет просто номер ячейки, не загружая ресурсы снова. Т.е. идет ссылка на один и тот же объект в разных местах карты. Если есть вопросы с плавающей камерой относительно большой карты, или если объектов в игре более чем 256, задавайте вопросы, ...отвечу по мере поступления. |
Размер карты 100х100 пикселей вы имели ввиду? И каждый элемент массива (100х100) несёт в себе значение каждого пикселя? Или я не так понял. Дело в том, что столбов нет никаких, то есть объект можно поставить в абсолютно любую клетку (317; 526); (465; 777). Вот в чём проблема, и я не знаю как это реализовать. Надеюсь, мы поняли друг друга, Beermonza? Что именно вы имеете ввиду?
|
Цитата:
Цитата:
Как подвинуть камеру? - просто вычитаем из полученной координаты объекта координату камеры. |
(130.000; 0) - а что с такой координатой делать или даже если ещё больше значение будет? Использовать тип для координат LongInt просто? А если вообще не записывать объекты все подряд, а только те, которые есть на карте?
Ну, у меня сейчас вот так отрисовывается: Код:
begin Код:
procedure TMainForm.CreateBG; |
Цитата:
|
Так...Внимательно почитай мой пост первый, когда я только спросил как реализовать систему хранения файла отличную от моей в старой игре! Вот тип
Код:
type Код:
matrix: array of TMatrix; Блин, я от ответов только путаюсь сильней :) И как мне сделать игровую камеру, чтобы она рисовала объекты от начала экрана? |
Я же напечатал:
Цитата:
Карта не измеряется в экранных пикселях, ...клетка - это типичное название элементарной поверхности в игре. В математическом виде, клетка - одна ячейка матрицы, у которой есть координата i и j, номера i в матрице располагаются по столбцам, j - по строкам. Пример, вот карта игры 7х7: j,i 1 2 3 4 5 6 7 1 0 0 0 0 0 0 0 2 0 3 0 0 0 0 0 3 0 0 0 0 0 0 0 4 0 0 0 2 0 0 0 5 0 0 0 0 0 0 0 6 0 1 0 0 0 0 0 7 0 0 0 0 0 9 0 ...так выглядит математическая модель карты. А вот так она записана в файле, теоретически: 770000000030000000000000002000000000001000000000090 ...разумеется в файле в виде символов кодовой страницы. Если у вас размер тайла (одной элементарной клетки, ее текстуры) 50х50 пикселей на экране, то полная графическая поверхность будет 350х350 пикселей. Вот так хранить карту довольно рационально. Почему столько нулей и зачем их хранить? ...вспомним, что поверхность просто усеяна текстурами, и причем разными, ...записать пропуск проще, чем строить систему списка, к тому же она не сожмется потом, а последовательный массив сожмется, и довольно прилично. |
Beermonza, Вадим, вы мне говорите, о том, о чём я уже знаю. У меня всё это в игре реализовано. Вопрос был в другом, ну да ладно, буду сам находить ответ. Спасибо.
|
Цитата:
|
Цитата:
Код:
type |
Мы все говорим об одной и той же математической модели карты - матрице. Но, математическая матрица содержит в своих ячейках по определению числа - в данном случае индексы. Так намного проще обращаться к одним и тем же объектам, и записывать в файл только эти индексы, или по иному - код объекта, однобайтный или составной.
Размер файла уменьшается в разы, ...кроме того мы экономим ОЗУ, храня каждый объект в единственном экземпляре. Если потребуется изменить объект "на лету", то достаточно сменить его ресурс в банке, один раз, не бегая по карте и не меняя его во всех клетках карты, где он находится. |
В моём проекте есть массив двумерный x на y. Ячейка несёт в себе значение текстуры, которую нужно вывести на экран. Есть массив текстур:
Код:
TGameObject = record Beermonza, а как у Вас в игре хранится файл карты? Объекты можно ставить, где угодно или есть наименьший размер ячейки, к примеру 10? |
Цитата:
Так что, я думаю, то что предложено выше в полной мере позволяет реализовать любую 2D игру, и не только. Цитата:
Сохранение карты идет последовательно, клетка за клеткой, записывая код объекта, ...там где нет объектов идет пропусковый байт. После записи файл сжимается и записывается уже на винт. |
Цитата:
|
Вот почитал уроки. У меня все спрайты в отдельных файлах, решил их объединить в несколько, по темам. Возник вопрос: как загруженный битмап порезать? Может быть есть готовое решение?
|
Цитата:
|
Код:
TAnimation = object Код:
procedure TAnimation.CreateAnimation(FileName: string; Max: integer; XRes, YRes: integer); Код:
procedure TAnimation.DrawAnimation(XPos, YPos: integer); |
На самом деле здесь по-прежнему присутствует упомянутая некогда в топике проблема: если два объекта имеют одну и ту же анимацию, то они рисуются абсолютно синхронно, даже если по идее не должны (пример с поваленными деревьями).
Я недавно тоже столкнулся с этой проблемой и вначале измышлял совершенно дикие варианты вплоть до хранения в объекте текущего кадра анимации и количества кадров, и, соответственно проверкой на последний кадр вне функций самой анимации. Вскоре, однако, нашел довольно изящное решение. Анимация по-прежнему хранится отдельно, текущий кадр хранится в объекте карты (без этого никуда), процедура рисования анимации принимает текущий кадр в качестве аргумента (в итоге на карте могут быть несколько объектов с одной и той же анимацией на разных стадиях) и, что самое главное - номер кадра передается функции рисования анимации по ссылке (пишу на C++). Т.о. проверка на последний кадр происходит не выходя за пределы типа анимации, а объект карты должен хранить всего лишь номер текущего кадра и не заботиться о том, является ли он последним. Модификация кода по сравнению с вариантом, где текущий кадр хранился в типе анимации минимальна - удалил из типа переменную CurrFrame, вписав его вместо этого в качестве аргумента. Не знаю, есть ли в Delphi ссылки, но, думаю, если что, можно воспользоваться указателями. |
Гром, именно этот тип анимации я описывал в качестве урока, ...кадр текущий и их макс. число хранит в себе каждый объект, а анимация одна в банке на все кадры. Это очень правильно и рационально.
|
Beermonza, честно говоря, тему я почти не читал, т.к. дельфийский код читаю медленно на основе полузабытого паскаля и билдера... А вначале там и вовсе коды во вложенных файлах, их вообще лень читать...)
А как насчет хранения максимального номера кадра в типе анимации? По-моему, производить проверку номера кадров лучше всего прямо во время рисования кадра, т.е. в функции объекта типа анимация. Мне это кажется как-то более логично. К тому же, объект может иметь несколько различных видов анимации (например, дерево стоящее и дерево падающее). Если стоящее дерево имеет всего один кадр (или просто другое число кадров, нежели падающее), то как хранить число кадров? Отдельно для каждого типа анимации? Вообще прямо сейчас я имею на руках работающий код рисования анимации, реализованный по этому методу, а вот до использования этой самой анимации в объектах еще не дошел, так что пока не знаю наиболее рациональных приемов. |
Цитата:
|
Товарищи, не меряемся длинной портянки кода, ...тема обязывает давать понятия новичкам.
Гром, условие на переполнение кадра (счетчик) использует оба значения, текущий кадр и макс. кадр, и переводит текущий на начальный, посему оба значения нужно хранить вместе (условно): Код:
Inc(Obj[i,j].Frame); |
Beermonza, тоже логично...
С другой стороны, текущий кадр относится исключительно к конкретному объекту, а общее число кадров - ко всем объектам, использующим данную анимацию. Опять же и хранить идентичную информацию (число кадров) в каждом объекте - это, конечно, не так затратно, как своя собственная копия всей анимации для каждого объекта, но все же... А если все же объект использует разные виды анимации? Например, какой-нибудь персонаж идет вправо, влево, вверх, вниз, по диагонали, в каждом из направлений машет мечом да плюс еще пьет зелья и леший знает что еще... И таких на карте много... Информация множится со страшной скоростью, тем более что и хранить неудобно, разве что в безликом массиве, когда не всегда понятно, какой номер элемента за какую анимацию отвечает. |
Цитата:
|
Открою небольшой секрет, которого быть может новички не знают, или слышали мельком, ...дело в том, что на одной общей текстуре могут быть расположены несколько типов анимации, относящиеся к одному типу объекта. В этом случае, один из объектов игры может пользоваться своим куском анимации "от сих до сих", макс. кадр у объектов может быть разный. Вот условно пример сборной текстуры:
ПП1 ... ПП8 ПЛ1 ... ПЛ8 ПВ1 ... ПВ8 ПН1 ... ПН8 АП1 ... АП8 АЛ1 ... АЛ8 АВ1 ... АВ8 АН1 ... АН8 ГП1 ... ГП8 ГЛ1 ... ГЛ8 ГВ1 ... ГВ8 ГН1 ... ГН8 Поясню что это за запись. Это представление сборной текстуры в виде структуры кусочков, кадров, по типу анимации. Первая линия - подряд идущие кадры с 1 по 8 в разных, допустим 4-й направлениях. ПП - перемещение право, ПЛ - перемещение влево, ПВ - перемещение вверх, ПН - перемещение вниз. Вторая линейка - атака, также по направлениям, третья - гибель по направлениям. Все это в одном графическом файле, с именем типа анимации. Когда объект использует анимацию, у него есть движковые переменные направления анимации 1, 2, 3, 4, но в анимации для универсальности используется общий счет текстур (у дерева нет направлений), поэтому объект, в данном случае персонаж, берет с банка текстуру тем же способом, что и все объекты, но использует исходя и игрового типа свой участок. Один персонаж идет с 1-го по 8-й кадр сборной текстуры, а второй с 9-го по 16-й, у них разный макс. кадр, и кроме того и начало, ...в данном случае условие If Obj[i,j].Frame > Obj[i,j].MaxFrame then Obj[i,j].Frame := 0; уже будет некорректным, вместо Obj[i,j].Frame := 0; будет Obj[i,j].Frame := Obj[i,j].StartFrame; |
Beermonza, ну да, в принципе про хранение всей анимации в одном файле слышал. Вплоть до хранения всех картинок небольшой игры в одной картинке.
При таком раскладе, действительно, использование анимации становится специфичным для конкретного объекта... Структура хранения информации, правда, усложняется... |
Кроме того, все манипуляции с анимацией вы должны вложить в сопровождающем файле особого типа, где расписано: какого размера кадр, сколько кадров всего, сколько типов находятся в сборе, как пользоваться вырезкой, по типам, направлениям и пр. пр. пр. ...в этом случае вы уже не лезете в код движка, а создаете сборную текстуру и файл параметров, ...движок сам применит анимацию как положено, притом по одному и тому же алгоритму, читая сопроводительный файл один раз при загрузке ресурса в банк текстур и анимаций.
Еще один момент, ...знаете чем анимация отличается от статической текстуры в данной структуре хранения? ...ничем, просто в файле написано что кадр всего 1 и тип один. Для движка не составит никакого труда лишний раз просчитать условие на 1 кадр, это рациональнее записи условий на наличие анимации. |
Да, насчет статичной картинки в один кадр я не то в этой теме, не то в соседней уже прочитал и реализовал!:)
Информацию по числу и размерам кадров хранить и использовать несложно... А вот куда писать информацию по типам, направлениям и пр? К анимации или объектам? Может быть, отдельно хранить собственно картинки, а отдельно - информацию о расположении анимации данного типа на ней? А потом объект обращается к конкретной структуре информации... Как-то все-таки проще кажется хранить раздельно разные типы анимации (можно и для каждой анимации своя картинка), и уж потом обращаться к каждой из них в различных ситуациях... А уж разобрать хранящуюся на диске картинку хоть со всей анимацией игры на различные объекты анимации - не проблема...) P.S.Хотя может и не проще это... Мозги нынче уже плохо соображают, завтра на свежую голову еще подумаю!:) |
Хозяин - Барин, ...кому как удобно, тот так и делает. Но в основе всегда - рациональное использование пространства дисков, оперативное использование ресурсов без вмешательства в код движка, создание структуры кода и распределение ресурсов для быстрого доступа/обработки.
Как ни крути, кроме самого движка тянется еще цепочка спец-программ для создания ресурсов, кроме, собственно, еще и редактора карт. |
Цитата:
|
Как сделать так чтоб игра показывалась на весь экран ну как обычные игры?? Заранее спасибо
p.s. Посоветуйте литературу по написании игр в Delphi?? |
Цитата:
|
Цитата:
|
Цитата:
|
На русском матерном\схематичном.
Код:
Form1.FormStyle:=fsAlwaysOnTop; |
Как сделать так, чтобы камера следовала за персонажем? то есть если сама карта 100х100, а видно только 20х15?
Я уже пытался сделать с помощью полной перерисовки экрана, т.е. при нажатии кнопки все видимые элементы сдвигаются в противоположную сторону, что дает эффект хождения, но при этом способе комп жутко тормозит=(...да и косяки там у меня жесткие...=) Слушал, что можно сделать это с помощью регионов... Кому не сложно подскажите... |
Нужно вырезать и отображать только часть мира размером в экран, остальное опускать и не обрабатывать.
|
Ckomoroh, если у вас 100х100 весь уровень, а нужен кусочек, ...то при создании экранного фрагмента примените плавающий цикл. Создайте переменную StartX и StartY. Вот примерно так будет выглядеть выборка в общем массиве карты:
Код:
For Y := StartY to StartY + ScrHeight do ScrHeight и ScrWidth - размер экрана в клетках, который виден, т.е. диапазон по-X и по-Y от начала выборки до конца одного экрана. Нужно предусмотреть так же момент, когда персонаж у правого края карты, параметры StartX, StartY, ScrHeight и ScrWidth остаются статичными, только сам персонаж меняет смое положение. |
Щас делаю игру-аркаду, взял как пример исходник Beermonza, сделал проверку столкновений, управление и т.д. У меня все движение в одном таймере обрабатывается, ия не могу сделать прыжок. Нужно что бы по нажатию по W значению speedy придавалось значение 10, а потом пока снизу нет припятствия герой падал вниз. т.е sy постепенно уменьшалась, и становилась отрицательной пока герой не упадет на что нибудь )) Как это реализовать я знаю, но вот проблема если жать клавишу W и не отпускать, то SY всегда будет придаваться значение 10, т.е тело всегд будет лететь вверх :eek:. Управление реализовано с помощью флагов, тот же самый Beermonza, выкладывал реализацию.. :confused:
|
ну движение объекта вверх, а потом внизу можно реализовать таким образом:
Код:
if (getkeystate(ord('W') and 128)=128) or (Up<>0) then |
Если я правильно этот код понял, то он мне не подойдет, т.к я могу прыгнуть с одной высоты, и он должен будет падать до столкновения с непроходимой клеткой....Мне просто нужно при нажатии на кнопку W совершить прыжок, и до окончания прыжка обрабатывать нажата ли клавиши не надо.. Но дело в том что все обрабатывается в таймере, т.е он все равно каждый такт будет проверять нажата ли клавиша, и как я уже писал герой пока нажата клавиша будет лететь вверх, либо упираться в максимальную высоту прыжка и зависать там пока не отпушу клавишу.... Может есть еще какие то варианты?
|
А ты предыдущий пример пробовал, он подходит под все твои требования, в нем проверяется в каком состоянии сейчас персонаж и прыжок осуществляется только в том случаи если он не в прыжке.
|
Попробую обьяснить. Тебе достаточно ввести одну переменную в твой код, которая будет хранить информацию о состоянии игрока (0 - стоит на земле, 1 - летит вверх, 2 - летит вниз). И осуществлять новый прижок только если он стоит, т. е. переменная равна нулю. Если не понятно, приведи пример своего кода, в котором обрабатывается прижок. Помогу исправить
|
Пример аркады с прыжком
Вложений: 1
Вот пример с прыжками, в комментариях. Пример на двух пользователей, на WASD и стрелках. Размер текстуры - цветных квадратов, берется автоматически. Пример совсем сырой и довольно древний, кому нужно, тот переделает, ...но есть в нем механизмы уже "взрослой" аркады, т.е. собственные типы на карту и игрока, ...отрисовка силами Canvas и BitBlt.
|
Спасибо за примеры, щас буду пробывать их приделать для себя. Позже отпишу что вышло =)
|
Beermonza, Вобщем если я правильно понял ваш алгоритм, то там при нажатии на W прыжку присваивается true. Потом в таймере проверяется клетка "под ногами", если там 0 то скорость падения каждый такт увеличивается на g, а если 1 то скорость 0, и клетка после падения поднимается на указанную величину( вот этот момент немного не понял ). и проверяется значение Jump, если да то скорость падения уменьшили. Я ничего не упустил? =)
|
Да, ..в условии проверка на "пол под ногами", если оно ложное, т.е. под ногами пол, то скорость становится отрицательной, каждый такт уменьшаясь на гравитацию G. В какой-то момент условие это становится истинным, т.е. под ногами нет пола, и происходит дальнейшее уменьшение скорости, пока она не переползет за 0 и не отправит объект обратно к полу со скоростью, постоянно увеличивающуюся на гравитацию G. Как только пол достигнут, условие снова становится ложным, и проверяет флаг прыжка, если его нет, то скорость будет равна нулю, т.е. объект неподвижен, стоит на полу.
Есть еще проверка на "потолок". Это условие ищет столкновение сверху, если находит непроходимую клетку, то устанавливает скорость положительную, объект летит вниз. Через какое-то время условие становится ложным, а проверка на "пол под ногами" истинным, и объект падает вниз. |
А про смещения можешь поподробнее рассказать, потому как постоянно возникают такие ситуации когда объект проваливается..
|
Объект может провалиться только если встретится с другим, поскольку они оба меняют под себя проходимость, а проверки на их взаимодействие просто нет.
Вот этот код показывает, что происходит на карте, как меняются координаты объектов: Код:
// отрисовка точных координат в массиве карты (не обязательное и бессовестное) Чтобы избавиться от рывков, нужно ввести смещение по осям X и Y. Эти смещения отсчитываются до поры, пока не нужно будет перейти на соседнюю клетку. Большая текстура показывает плавность хода, благодаря смещениям. |
Вопрос: как лучше делать меню и интерфейс игры в целом?
То есть использовать для каждого окна свою форму, например для меню-форма №1, для главного окна игры - форма №2, для опций - форму №3 и т.д. или уничтожать и создавать кнопки на одной форме? |
Если в плане именно лучше, то на мой субъективный взгляд вообще меню, опции и подобные вещи кнопок содержать не должны (имеются в виду кнопки разряда TButton и им подобные). Лучше если все такие объекты будут нарисованы.
Вот как лично я реализовал в своей игре меню. Для обычного, собственно игрового, режима в игре есть свой буфер типа TBitmap, куда рисуется вся визуальная часть, ну а потом это дело копируется на канвас формы. Для меню также создается свой объект типа TBitmap, залитый каким-нибудь ядовитым цветом. На нем имеется несколько изображений неправильной формы, представляющие собой "кнопки" меню. Фон у них того же ядовитого цвета. Фон меню у меня рисовался в обычном буфере, игровом, выводился на форму, поверх него - с помощью функции Draw выводился битмап меню с установленным TransparentColor значением того самого ядовитого цвета. Как отлавливалось взаимодействие с меню: при вождении мышкой по форме считываются координаты курсора, по щелчку - проверяем цвет пикселя на битмапе меню с координатами последней позиции курсора. Если не цвет прозрачности - с помощью простых вычислений находим, какая это была кнопка. Впрочем, у меня еще было своеобразное подсвечивание каждой кнопки при наведении, что несколько усложняло весь алгоритм. Из альтернативных способов реализации подобного поведения меню - вместо битмапа меню используется форма, тоже прозрачная, синхронно двигающаяся с главной формой. При щелчке по прозрачной части второй формы клик должен прийтись по нижней форме. После попыток воплотить этот вариант я отказался от него по следующим причинам: во-первых, мой C++ Builder отказался считать щелчки по прозрачной части формы щелчками по нижней (главной) форме (в Delphi, однако, говорят, этот прием работает); во-вторых, вторая форма, в положении StayOnTop делается сама "активной", хоть и невидима со своими границами, а главная - соответственно подсвечивалась как "неактивная"; в-третьих, синхронное перемещение стало проблемой, т.к. происходило по таймеру, и даже при интервале 1мс вторая форма заметно запаздывала, получалось меню висящее вообще вне окна игры! Да и вообще, я спервоначалу намучался, когда выбирал правильный способ работы со второй формой, так что не захотел дальше с ней работать. Ну и еще из причин - зачем создавать лишнюю форму, когда можно ограничиться всего лишь битмапом, подумал я. И, собственно, еще один, более простой, но неплохо смотрящийся вариант. Опять же, меню рисуется каким-то фоновым рисунком, кнопки представляются красиво нарисованными правильными прямоугольниками и располагаются как вам надо. Все меню рисуется в одном (том же игровом) буфере, координаты точки, где произошел клик, однозначно сопоставляются с нужной кнопкой с помощью простейших расчетов. Вот такое мое видение способов рисования меню. Единственное, что я молчаливо здесь предполагаю - это что меню имеет свой собственный фон, т.е. не рисуется поверх игрового процесса (впрочем, с помощью способа, который выбрал себе я, и это можно, только и тут будут свои ограничения). |
Создание меню/интерфейса
В зависимости от степени погружения начинающего игростроителя в тонкости программирования различных процессов, можно выделить 4 типа построения меню/интерфейса, ...по уровню сложности (баллы):
1. На основе форм (TForm) Под каждую группу элементов интерфейса создается отдельная форма. В ней расположены элементы декора (Image) и элементы управления, всевозможные кнопки, переключатели, полоски состояния и пр. Если стандартные компоненты не устраивают, то все можно выполнить с помощью Image, помещая в них графические экземпляры кнопок не стандартной формы. В OnClick выполняется обработка нажатия на такую "нарисованную" кнопку. Кроме того, можно воспользоваться событиями Image - OnMouseDown и OnMouseUp, в первом событии можно смещать Image по Top и Left на 1 пиксел, во втором возвращать на место, ...при этом будет иллюзия притапливания рисованной кнопки в момент нажатия на клавишу мыши и возвращение при отпускании. Процедура с OnClick теперь переползет в OnMouseUp, и OnClick уже не нужно. В Image вас будет интересовать свойство Transparent. Гром, пожаловался на свой C++ Builder, но я вам говорю со 100-процентной гарантией, если часть прозрачная, то никакие клики мыши на ней в Delphi 7 не проходят по прозрачной форме, если за ней есть главная, ...т.е. работает только по видимой части рисованной кнопки на форме меню, прозрачные части графики считаются не активными, поскольку и форма и ее компоненты для ОС - суть, графика, и все состояния прозрачности компонентов подчиняются основным настройкам форм. Если не устраивает стандартный стиль окна, то он убирается совсем, по свойству BorderStyle = bsNone, НО! ...не забудьте про отдельную кнопку закрытия формы, иначе она так и будет маячить на экране. Синхронизация понадобится, если игра выполнена в окне, это делается по таймеру с интервалом 31 мс (даже есть некая иллюзия 3D). В таймере условие на проверку положения главной формы, со старым положением и новым, если есть отличие, узнаем на сколько и двигаем все формы интерфейса на столько же. 2. На основе панелей (TPanel) Вы точно знаете, что у вас квадратные не прозрачные элементы меню/интерфейса, с графическим задним фоном. В этом случае все меню создаются на панелях, на задний фон помещаются Image, на передний - стандартные компоненты, или рисованные, или те же Panel в виде кнопок, их цвет можно менять. Все элементы готовые располагаются в сторонке скрытыми "по-умолчанию" (Visible = False), выставляются на места после запуска программы, появляются и исчезают по созданной структуре меню и интерфейса. Вся графика загружается только после запуска программы. Этот метод сокращает размер исполнительного файла и загружает CPU значительно меньше. 3. На основе буферов TBitmap и "пустых" Image в качестве зон срабатывания Этот метод позволяет создавать меню любой графической сложности, и накладывать его поверх изображения главной формы. Несколько пустых Image с заданными размерами (несколько меньшими чем границы рисунка, ибо кнопка рисуется на единственной главной форме, ее прозрачные части тоже будут активными на клик). В соответствии со структурой меню/интерфейса на главную форму накладываются разные буфера TBitmap, и активные области Image "плавают" по форме как-угодно. 4. Полностью графический метод, без VCL В основе PNG-фрагменты форм, из которых с помощью конструктора собирается скелет любой формы, или готовые изображения форм хранятся в сжатом виде и подгружаются в буфера. Области срабатывания хранятся в движке интерфейса, который отслеживает положение курсора мыши на главной форме. Посредством флагов определяется нужно ли выполнять отслеживание нажатий или нет, на каждый конкретный объект меню/интерфейса. Здесь повсеместно вспомогательные файлы структуры меню, особого типа. Выбирайте. |
Цитата:
Код:
If (X>5) And (X<45) And (Y>5) And (Y<45) Then Image1.Canvas.Draw(5,5,LightButton) Else ... Вот мой пример (на форум не влезло) |
Alex Cones, это пункт 4:
Цитата:
Код:
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Кроме того, если есть движок, то проект серьезный, а ему не с руки сходить на Canvas и TBitmap. Ежели хочется именно так, то почему бы и нет, ...но с головой применять методы, иначе складывается ложно представление о силе Delphi в игростроении без библиотек и движков. |
Вопрос наверняка уже был раньше: как сделать перемещение вражеских существ с течением времени? Для этого необходимо в таймере написать приращение скорости для существа?
|
Цитата:
|
Я имею ввиду, что существо движется от одной точки к другой, например, только по оси абсцисс. Оно движется с определенной скоростью. Для него надо создавать отдельный таймер, писать в главном таймере или еще как-то по-другому?
|
Все игровые события происходят в главном таймере. В частности, вы перебираете всех существ, по каким-то алгоритмам находите, куда каждое из них будет двигаться в этом ходу (скорость) и что будет делать. Потом снова их всех перебираете и, грубо говоря, прибавляете к координатам каждого его вновь вычисленную скорость. Также можно еще проводить всякие проверки на столкновение, взаимодействие с другими объектами и много что еще.
|
Управление, прямо говоря, мобом осуществляется набором условий, по имеющемуся набору параметров в его типе, минимум таких как: текущие координаты, координаты перемещения, скорость движения, состояние.
Как ими пользоваться? ...разбираем. Вот стоит на карте моб. У него есть запись текущих координат, ...с позиционированием все понятно. Теперь его состояние, ...допустим он находится в ожидании на кого напасть, но вокруг никого нет (алгоритм поиска цели вокруг себя на некоторый радиус). Вот в один из тактов алгоритм бота под порядковым номером в списке "нащупал" на карте цель (допустим вас, ...определил по типу объекта), алгоритм поиска цели указывает координаты перемещения, т.е. куда должен топать моб, и задает скорость, в зависимости от типа моба. Проходя через общую для всех структуру перемещения, координатам моба начисляются смещения, равные скорости перемещения, и будут начисляться до той поры, пока эти текущие координаты не станут равны координатам перемещения, заданным в начале перемещения как точку на карте, ...в этот момент в алгоритме перемещения условия на смещения по осям становятся ложными, и начислений смещения больше не будет, ...следствие - моб стоит в заданной точке. Далее, "алгоритм действия" фиксирует близость цели и запускает процедуру выполнения атаки. Все просто. У вас будет порядок алгоритмов такой: 1) Алгоритм перемещения; 2) Алгоритм поиска цели; 3) Алгоритм действия; ...и так далее, с гибелью и пр. пр. пр. Все работает в цикле по списку объектов и с учетом типов объектов, ...куча условий, фильтрующих объекты. |
Вообще спасибо Вам огромное за такую тему!
|
очень полезная тема, правда длинная...
|
Обучение еще длиннее, это всего лишь маленькие уроки, советы.
|
Да, тема довольно интересная, правда, местами сложная для понимания.
Но, у меня возникло небольшое разногласие: простите, если я ошибаюсь, но мне кажется что Банк текстур не нужная трата ресурсов. Что бы избавиться от непониманий в дальнейшем, привожу код своего Банка: Код:
// В глобальных переменных задаю массивы карты и банка Скажите, неужели толк от Банка текстур настолько выше и значительней, чем простое создание 1-го битмапа, загрузки в него текстур и очистки этого битмапа, после окончания работы с ним??? P.S. Тему читал всю, но заметил лишь два пункта превосходства Банка текстур, хотелось бы больше. :rolleyes: :( |
Зачем же обязательно 256, когда можно использовать ровно столько, сколько надо? Используйте динамический массив строго необходимого размера, и будет вам оптимальное использование ресурсов. (Хотя уже в упор не помню, есть ли в Паскале динамические массивы, но в Delphi точно должно быть что-то подходящее!)
Можно, конечно, хранить все текстуры в виде одного сложного битмапа - это вопрос удобства, но все равно где-то должна храниться разнообразная информация о картинке (размеры, количество кадров в анимации, прозрачность и т.д. и т.п.) Или вы имеете в виду каждый раз грузить из файла одну текстуру, рисовать ее, выгружать из памяти, грузить следующую, рисовать, выгружать, и так далее множество раз в секунду? Вот тогда это уж настоящая пустая трата ресурсов!;) |
Уважаемый Гром, я не профессионал и все что пишу, основано на моих собственных умозаключениях и на том, что видел своими глазами. Вот вы в своем сообщение говорите, что происходит при использовании буфера:
Цитата:
Цитата:
|
Не отличающиеся внешне текстуры - это просто грубая ошибка художника/дизайнера. Тому, кто их делал - руки оторвать и пришить в более правильное место.
Так что, исходя из того, что разные текстуры выглядят достаточно отлично друг от друга, получаем, что либо текстур гораздо меньше, либо толк от них всех все равно есть. Потом, при работе с банком текстур есть однократная загрузка с диска, а потом идет работа с оперативной памятью, что гораздо быстрее! А каждый раз читать с диска одну маленькую картинку, потом читать с диска еще 399 маленьких картинок, и так, скажем, 25 раз в секунду... Очень снижается быстродействие. С банком текстур мы не имеем такой проблемы, расплачиваясь за существенное быстродействие сравнительно небольшим расходом оперативки, а если текстуры часто повторяются - то и совсем небольшим. В общем, при увеличении числа текстур в варианте с банком - объем использования оперативной памяти растет линейно, в варианте без него - линейно же падает быстродействие. Вот только коэффициенты пропорциональности не в пользу варианта без банка. |
Гром говорит умные вещи, стоит поверить на слово, ...если только код написан был автоматически по примерам, и нет желания все же разобраться самому.
Попробую более доступным языком выразить все, что было уже сказано и показано в примерах. Вот у нас некий шаблон карты. Он закодирован, и на каждую текстуру клетки карты приходится свой код. В структуре есть матрица индексов текстур (это слой карты), есть динамический массив банка текстур, например Array of TGBank. Идет загрузка данных, при этом натыкаясь на первый байт кода текстуры банку задается размер 1, в ячейку помещается текстура и все сопутствующие данные по типу (размеры, смещения и пр.) в матрицу слоя записывается по координатам (x,y) индекс ячейки банка. Далее, переход на следующий код клетки, ...массив банка проверяется на наличие уже загруженной такой текстуры от 1 до размера массива, если такой нет, то идет увеличение размера массива на 1 и заполнение последней ячейки текстурой и данными к ней, также в матрицу слоя идет индекс ячейки банка. На очередном шаге встречается очередной код карты, при проверке банка оказалось, что такая текстура уже загружена, ...загрузка пропускается, вместо нее в матрицу пойдет индекс найденного совпадения кода на карте и в проверяемой ячейке банка. И так далее, пока не будет считана вся карта. Банк текстур никогда не очищается, если эта карта, или ее участок является активным в игре. Если нужна другая карта, тогда банк освобождается и заполняется заново, но уже текстурами к новой карте. Алгоритм построения кадра игры всегда пользуется индексами матрицы карты и берет текстуры непосредственно из банка, ...никакого другого хранения текстур в игре, кроме как в банке, быть не должно. Что в итоге? ...если текстурщик все продумал и создал набор оптимальных текстур, с помощью которых можно построить поверхность любой нужной сложности, то в памяти никогда не будет количества текстур, равных количеству клеток на карте, ...в том и заключается оптимизация. Вот у нас слой поверхности: трава, земля, дорога. Если прикинуть, то по 5 вариантов достаточно для неоднообразности. В сочетании со случайным наполнением и точным расположением нужных типов текстур карты 20х20, благодаря банку в памяти будет всего 15 текстур, ...иначе 400 (!) ...а если текстуры 25х25, то в размерах соотносится как 27 Кбайт к 720 Кбайт (!) ...есть разница? То же самое касается и слоя объектов, где текстуры уже будут поболее (вплоть до 400х500 пкс), понятно, что нет смысла держать в памяти копии текстуры одного и того же типа дерева, здания, части горы, ...да чего еще угодно. Вот в этом суть банка текстур, при правильном его создании и использовании. Что касается редактора карт. В любой момент может понадобиться любая из имеющихся текстур, ...у вас есть выбор, сразу загрузить все, или делать это по мере обращения к новым типам текстур, причем не выгружая прежних (если использование таковых не предвидится, то и загружать не нужно). |
Цитата:
Цитата:
Пока что основные составляющие это: игрок и карта. Теперь сама реализация: Тип игрока: Код:
TPlayer = packed record Код:
// Банк текстур. Управление персонажем: при нажатии на кнопку W вначале происходит проверка на проходимость и не занятость каким-либо НПС клетки выше персонажа. Если эта клетка свободна, то y координата игрока уменьшается на одну единицу, дальше отрисовывается анимация перемещения модели игрока вверх. Я сейчас все это только начинаю реализовать, и кое-что пока не совсем понятно. Поэтому прошу объяснить с простыми примерами о том, как значения из FullMap перевести в ScreenMap в зависимости от координат игрока. И прошу, если у меня в коде или в рассуждениях есть ошибки или не рациональные подходы, пожалуйста, напиши об этом. |
Вот тут ошибка:
Код:
Bank: array[1..256] of TBitmap; Код:
Bank: array[0..255] of TBitmap; По идее ScreenMap не нужен в принципе. Достаточно иметь 4 переменные, которые хранят диапазон выборки клеток карты. Две отвечают за сдвиг от начата карты по-X и по-Y, остальные две размер области экрана, т.е. ширину и высоту в клетках (у вас обе по 20). Я так понимаю речь идет о классическом расположении персонажа в центре экрана? |
Цитата:
Цитата:
Цитата:
|
Очень просто.
Вот персонаж в начальной клетке K(0,0), если он центрируется на экране, то мы четко знаем сколько клеток карты нужно, чтобы положение персонажа было в центре. Экран 20х20 - уже ошибка, числа должны быть нечетными. Пусть 19х19, тогда диапазон выборки будет от 0 до (19-1)/2. Теперь для координаты X, ближе к коду. Если сдвиг это DispX, а количество клеток в экране ScreenW, то цикл выборки организуется так: Код:
For X := 0 to ((ScreenW-1) div 2)+DispX do Код:
For X := DispX to ScreenW+DispX do Код:
If DispX <= (ScreenW-1) div 2 then По поводу отображения. Оно теперь не привязано к координатам начала 0,0, а будет плавающим: Код:
Form1.Canvas.Draw((ScreenW-(X2-X1))*TexW, (ScreenH-(Y2-Y1))*TexH, Buf); |
Помогите с редактором
Вложений: 1
Объясню суть вкратце: есть редактор, на мой взгляд, с не совсем удобным интерфейсом, но лучше придумать не могу. Что меня смущает: если я хочу, чтобы выбранный объект создавался как препятствие, я щёлкаю на галочку "Препятствие". К примеру, добавляю квадрат как препятствие, второй квадрат как не препятствие(снимаю галочку), третий как препятствие и т.д. Хочется придумать для этой операции вариант получше. Далее...Далее нет смысла объяснять, это очень долго. Во вложении exe редактора. Мне важно ваше мнение, как сделать программу удобней.
Небольшая инструкция: - Чтобы добавить объект, нажмите на + рядом с пустым полем и выберите любое изображение на вашем компьютере - Чтобы прекратить расстановку объектов по карте, нажмите "Сброс" - Чтобы выделить объект, нажмите на него. Вы можете перемещать объект по карте, с помощью стрелок. Чтобы сбросить выделение, нажмите на пустую область карты или на "Сброс" - Чтобы удалить объект, выберите объект и нажмите Delete - Чтобы ставить объекты как препятствия, щёлкните на галочке "Препятствие" - Чтобы создать новую зону, нажмите + рядом с надписью "Зона" - Чтобы удалить текущую зону, нажмите - - Чтобы перемещаться по зонам, используйте << и >> Надеюсь, что вы поможете мне. Спасибо P.S. Просьба не пользоваться меню - оно не до конца сделано и могут возникнуть проблемы. |
есть вопрос:
вывожу карту из текстового файла с 0 и 1 (для начала) в буфер (в битмап). Затем копирую ее на канву TImage. Размер минимальной клетки карты 10 на 10. размер карты 70 на 70. Все работает нормально. Если выставить значение размера карты больше 70 по любой стороне (хотя бы 71), то вылетает ошибка о каком-то неверном дескрипторе. Пожалуйста подскажите как поступить. |
like_cloud, смотрите массив карты в Var, он наверное жестко прописан array[1..70, 1..70] of ...
Манжосов Денис :), exe запускать не хочется, может скринчик покажешь? Сделай условие на зажатую клавишу. Если например "w" не зажата, лепит без препятствия, если зажата, соответственно, будет препятствие. |
Цитата:
Нет там массив в 1000 элементов. Щас поэксперемнтировал: можно вывести карту суммарным размером клеток не более 141. Т.е. можно 70 и 71 , 69 и 72 и т.д. назависимо от стороны X и Y. Я "слегка" в недоумении |
Ответ
Вложений: 1
Спасибо, Beermonza, что откликнулись. Идея с зажатой клавишей неплохая, можно на Ctrl сделать.
А при запуске программы даже никакое окошко не вылетает? У меня запустилось всё нормально из вложения. Скриншот редактора прилагается like_cloud, выложите на форум проект, так будет легче разобраться в проблеме. |
Вложений: 1
вот держите. Там все пока что сумбурно, только начинаю разбираться с этими делами. Вывод "карты" на форму по нажатию кнопки.
Заодно вопрос: когда-нибудь карта станет большой и будет кушать много ресурсов. На канву чего быстрее всего вывести ее? |
Вложений: 1
Вот что могу сказать: для каждой клетки создаётся свой Bitmap, что очень не желательно, потому как может быть 1000 одинаковых клеток и каждой свой Bitmap, хотя картинка одна и та же. Я ещё удивился, почему так долго загружается =). Также почему нет Assign(Input, lvl); и Close(Input);? Присутствует только Reset(Input);
Код:
j*razfieldX-razfieldX, i*razfieldY-razfieldY Написал простой пример загрузки карты и вывода изображения карты на экран. |
Цитата:
Код:
MapX := 70; Значит буфер нужен 1000х700, такой должен работать по-любому, что там у вас происходит я не в курсе, если такой не тянет. Теперь, мы работаем "в цифре", загружаем карту любого размера в массив карты любого размера (предела). Когда нужно отрисовать экран, мы берем диапазон из массива и готовим подложку в буфер. Т.е. нужно начало выборки и размер на экран, делаем цикл и рисуем кусочки в буфер. |
Цитата:
|
Цитата:
|
Цитата:
.......... проверил карту, был лишний пробел в конце строки. Убрал,все равно ошибка. Сделал новую карту,проверил ее - все равно ошибка. И именно на если карта больше 70 на 71 клетки.. |
В ваших исходниках загружается файл lvl02.txt, в нем физически нет клеток по-X больше 70. В lvl01.txt вроде 200, может в этом ошибка?
...и пробелы ставить не обязательно, пусть подряд идут байты клеток. |
непонел почему пост исчез((повторю вопрос. у меня игра в которой кот бегает за мышью по форме, но мне нужно сделать на форме лабиринт, и чтоб они бегали по нему. как это осуществить?
|
CbITHO, читайте тему с начала, разбирайте примеры, ...прежде чем задавать вопрос воспользуйтесь поиском по форуму.
Ваш вопрос удален по причине - "глупый" ...можете обижаться, но в нем сокрыта сама сущность понимания вами процессов игростроения. Читайте тему и все вопросы отпадут. |
я начинал читать ина первых 4 страницах нужной информации не нашол. я б дочитал доконца да мне вот завтро надобы сдать. подскажите хотябы где примерно искать
|
В раздел "помощь студентам", найдете человека, сделает.
А тема начинается по существу после 5-6-й страницы. |
Игра файтинг. Основы уже написал, теперь пытаюсь все упростить. У меня такаой вопрос. В игре используется 5 таймеров: 2 на каждого игрока - 1 на нанесение ударов, 2-й - на получение, +1 таймер на отлов клавиш. Можно ли как-нибудь это упростить?
З.Ы. Игра на C++ Builder 6.0 |
M0rf, нужно! Использовать ровно один таймер!
Вкратце: отлов клавиш осуществляете в событиях OnKeyDown, OnKeyUp - при этом вы просто запоминаете в соответствующих флагах нажата ли каждая нужная клавиша. При срабатывании таймера смотрите по флагам, какие клавиши нажаты и делаете то, что нужно - у обоих игроков. Нанесение и получение ударов происходит одновременно. Если у вас еще есть какая-то анимация их, т.е. не мгновенное нанесение ударов, то просто в каждый момент нанесение удара будет на какой-то стадии. Если вдруг противник оказался в радиусе действия удара - тут-то ему и больно стало! Кстати, я уже однажды распинался насчет файтинга и таймеров вот в этой теме. |
Почитал. Попытался впихнуть все в один таймер. KeyDown и KeyUp у меня используются так как ты написал (пасиб кстати), а вот с таймером некоторые проблемки:
1) Таймер обрабатывает только одну функцию. Пусть и быстро (при выполнении действий с небольшим количеством кадров это незаметно), но при использовании действий с большим количеством кадров это ощутимо. 2) Выполняется только одна анимация в условии, даже если она не одна (нанесение удара и его получение обрабатываются в одном условии. В итоге я наношу удар одним персонажем с воспроизведением анимации удара, а второй персонаж получает урон, но анимации нет) |
Цитата:
Пихаете в функцию-обработчик события OnTimer вызовы всех функций, каких нужно и делается все хорошо. Код:
при использовании действий с большим количеством кадров это ощутимо. Цитата:
Вот такую схему могу вам предложить. |
По первому: таймер срабатывает раз в 40 млсек. и выполняет действие, которое удовлетворяет условию. Так вот, если действие состоит из 4-5 кадров - они выполняются довольно быстро, и когда таймер будет обрабатывать другое действие, нам кажется, что они происходят одновременно. А если действие, скажем в 30-40 кадров. Все остальные действия приостанавливаются и возобновляются после его окончания.
По второму: неплохая идея. Попробую обязательно. |
M0rf, внимательно читайте тему, ...несколько раз упоминался собственный тип массива юнитов. У юнита есть запись, отвечающая за состояние, т.е. тип анимации, которую он выполняет, ...есть запись, отвечающая за номер текущего кадра. Существует цикл по числу юнитов в игре, внутри цикла Case на состояние (тип анимации), в каждом пункте которого прописаны все состояния, и в каждом количество кадров, ...условия на конец анимации и переход на другое состояние.
В любой момент времени будут обрабатываться все юниты по одному и тому же таймеру, но каждый будет выполнять свои действия и анимацию, исходя из своих записей. Вот упрощенная модель: Код:
// цикл по числу юнитов |
Ура! Теперь у меня один таймер. Все неплохо работает, анимации корректно воспризводятся, но сложно регулировать скорость воспроизведения. при некоторых ударах получается, что анимация получения удара выполняется быстрее, чем нанесение. Пытался вручную менять интервалы у таймера, но это влияет на все скорости воспроизведения анимаций, что не решает проблемму. Возможно нужно использовать sleep() ?
З. Ы. Не подскажите ли мне аналог команды With на С++. Как я понял в данном примере, эта команда позволяет не писать каждый раз Units[i] при обращении к элементам. В helpe по С++ ее нет. |
Цитата:
Цитата:
Говоря кратко - нет такого аналога в C++, только в функциях-членах вы не пишете, к какому объекту обращаетесь. И еще добавлю, что при написании игры (и вообще любой нетривиальной программы) на C++ часто стоит активно использовать ООП. Если Pascal и Delphi несмотря на поддержку этой парадигмы часто оказываются склонны к функциональному программированию, что выражается хотя бы в разнице между записями и классами (отсутствие функций-членов и наследования в записях), то C++ является в противовес Си ориентированным именно на ООП и принципиальной разницы между структурами и классами там нет вообще никакой. Поэтому я советую использовать те средства, которые ближе выбранному вами языку (C++ в данном случае) - в частности, активно использовать функции-члены, например, таким образом: Код:
for (int i = 0; i < nUnits; i++) |
Цитата:
http://www.programmersforum.ru/showthread.php?t=70140 Почитай там мои посты, посмотри мою демку (правда она на Delphi, но как я понял ты его понимаешь). Смысл в том, что есть переменная, она каждый цикл таймера возрастает на 1. Как она становится равной, например 10 происходит ее сброс на 1 и выполняется код анимации. В итоге анимация работает в 10 раз медленнее таймера. Ту же систему можно использовать при других задержках чтобы не захламлять игру лишними таймерами. |
Цитата:
Код:
If FrameWait = 0 then Inc(Frame); // смена кадра |
Цитата:
Цитата:
|
Сессия закончилась, можно иделом заняться.
Решил переделать вывод графики через Canvas в один Image. нашел пару примеров (в С++ синтаксис не такой как в Delphi), но возникли трудности: TPicture *fon=new TPicture; - задаю указатель на фон игры fon->Bitmap->Width=1280; fon->Bitmap->Height=800; - указываю ширину и высоту fon->Bitmap->LoadFromFile("Арена1.bmp"); - загружаю Image1->Canvas->Draw(0,0,fon->Bitmap); - рисую. Выскакивает ошибка при запуске программы: "Stream read error". Все сделано в соответсвии с примером. Есть ли ошибка в коде, и как правильно сделать вывод? И еще, про классы. В начале планировалось использовать один класс - Fighter, который будет хранить все переменные, функции ударов, движения, получение урона. В общем все функции. Но один товарищ посоветовал мне писать несколько классов: описание бойца, описание анимаций и др. Никак не могу понять преимуществ такого способа. Как, на ваш взгляд, лучше писать классы? |
Не надо рисовать все в один Image. Рисуйте сразу на форму. В реализации разницы никакой - т.к. вывод происходит через канву, которая у Form и Image одна и та же, а результат уже ближе к идеалу.
Также вместо TPicture советую TBitmap (уже хотя бы потому, что TBitmap является членом TPicture и это именно через него вы работаете). Ошибка, возможно, из-за использования русских букв (вообще у Билдера с русскими символами и взаимодействием их с внешним миром все очень плохо). Цитата:
Вообще - почитайте Страуструпа, он много про ООП писал. |
Блин, столько времени и все зря. Уже по-всякому перепробывал. Или я что-то недопонял или чего-то не хватает Builder'у. Смотрим сами:
Graphics::TBitmap *tmpBitmap = new Graphics::TBitmap(); //создаем битмап tmpBitmap->LoadFromFile("1.bmp");// загружаем изоьражение (специально переименовал, чтобы русских букв не было) Form1->Canvas->Draw(0,0,tmpBitmap);//отображаем рисунок на форме, начиная с координаты (0,0) По идее, все должно отображаться. Но при запуске вылетает ошибка Stram read error. При загрузке этой же картинки в Image (Image1->Picture->LoadFromFile("1.bmp")) все грузится нормально. Может быть кто-нибудь выложит пример (самый простой), чтобы я мог проверить - будет ли он у меня работать или нет? |
С проблемами в коде в свою созданную тему, здесь только фундаментальное, на словах или в коде.
|
Здравствуйте 49 страниц не осилил! :)
У меня карта собирается из текстур 32х32 герой 64х32 ну и деревья и прочие здания разных размеров. Мне интересно как правильно отрисовывать героя и за деревьями и перед... Я не могу передвинуть героя на основания дерева (ствол) но под крону что находиться в ячейки выше могу и тут нужно что бы герой был под кроной дерева и на оборот если герой стоит на 1 ячейку ниже основания дерева(ствола) то мне нужно рисовать героя не переднем плане а дерево на заднем. Вопрос в следующем как это правильно делать? Я кончено могу рисовать героя в цикле отрисовки карты и смотреть в какой он ячейки и что вокруг него если он выше дерева то его первым рисовать дерево вторым и на оборот. На сколько это правильно? |
Вот, столкнулся с проблемой ИИ в игре РПГ. Подскажите (может у кого и пример кода есть), как сделать врагов более умными, то есть чтобы не видели ГГ сквозь стены, кидались на ГГ, если у них полно здоровья и убегали, если мало и т.п.
|
Цитата:
Цитата:
__________________ |
BASSON_XVI, если правильно организовано построение скелета карты и распределение в нем объектов, то все работает автоматически.
Дерево растет с корня, поэтому картинка смещается вверх на высоту текстуры минус пол клетки карты. Аналогично смещается персонаж. Как только персонаж находится по-Y выше дерева, хоть на 1 клетку, он будет позади него, ...почему? ...цикл обработает сначала персонажа, у него Y меньше, а следом дерево. Строения смещаются в зависимости от основания. Если они занимают 1 клетку, то как в случае с деревом, если 3х3 клетки, то в центре будет смещение, все клетки основания здания должны быть непроходимыми, тогда персонаж пройдет вокруг и его появление снаружи и за зданиями будет по всем правилам. Крупные здания нужно разбивать на части, работать как с пристройками. apromix, в каждом такте обработки моба запускается процедура. В ней куча условий. Самое первое - цикл обзора, т.е. моб сканирует вокруг себя карту на определенный радиус. Условие: если на карте обнаружился объект, проверить количество жизни. Если количество жизни больше чем у моба, то с вероятностью 80% выбрать произвольно точку отступления. Если жизни меньше или равно, то с вероятностью 90% взять координаты цели, отправить в процедуру перемещения, ...моб будет топать до цели. Он все время, каждый такт, будет выполнять все описанное ранее, и будет реагировать на перемещение цели, ...всегда будет идти к ней, как бы она не убегала. Цель может потеряться, если она уйдет каким-то образом за радиус обзора, тогда моб остановится и удалит у себя цель. Последняя проверка на дистанцию атаки. Если дистанция для нападения достаточная, то остановиться и перейти в режим атаки. Если по какой-то случайности или закономерности жизней у моба станет меньше чем у цели, он свалит. Или можно создать очередное условие на проверку режима. Если моб в режиме атаки, то не выполнять некоторые пункты выше, например, проверку на количество жизней, чтобы моб бился до конца. Тут же могут быть условия как пользоваться восстановлением жизни, лечиться или нет, когда и что делать, какими средствами. |
Не рандомистый рандом!
Довольна странная функция random(); она постоянно выбирает одни и те же цифры, то есть от запуска к запуску пробной демки моб ходит одинаково и постоянно уходит куда то вниз выделенного ему квадрата для ходьбы!
Выбор направления 0-3 то есть random(3); И насколько я вижу чаще всего выпадает именно 0. Как с этим бороться? Ниже кусок кода ходьбы мобов: Код:
if Mobs[i].CH <= 0 then |
Не помню точно, как в паскале, но по идее нужно сначала вызывать функцию randomize, чтобы ряды случайных значений каждый раз были разными.
|
Цитата:
|
люди кто нибудь можете пожалуиста создать текстовый фаил, содержащии страницы данной темы ато у меня инет тормознутый (оооооооооочень) за 3 день только 10 страниц прочитал (сидел где - то по часу в день)
|
Хм... Сейчас сделаю... :) Чуть позже в это же сообщение добавлю... :)
|
То есть перед каждым random(); вызывать randomize; ???
|
BASSON_XVI вызывать randomize надо в начале главных циклов например вначале процедур типа:
Procedure blabla(bla); begin randomize; blablabl:=random(10); blablaba:=random(10); blablala:=random(10); end; |