Anatoliy, думали об этом, но решили не делать, потому что уже получается довольно хардкорный игровой процесс.
Добавлено (07 октября 2015, 21:23) --------------------------------------------- К сожалению, не успели сделать всё, что хотели, поэтому снимаем заявку с конкурса. Институт и окружение съели всё время, которое хотелось посвятить разработке.
Если кому интересно, то вот скрины последних версий. Многое было переработано и оптимизировано.
Сюжет: Вы – рядовой исследователь новых миров, ваша задача – изучить новый мир, взять необходимые образцы, оценить возможность заселения людьми, после чего спокойно вернуться домой. Новый мир выглядит обычным, неопасным, однако что-то есть в нем особенное. Работа могла бы быть выполнена, если бы не некоторые обстоятельства...
Начало сюжета (спойлер):
Находя странный предмет, вы решаете отнести его в капсулу для изучения. Однако на пути к капсуле, в которой вы прибыли, оказывается, что дорогу вам преграждает пропасть. Но ваше внимание привлекает случайный факт, что найденный ранее предмет идеально подходит в отверстие таинственного камня, находящегося на краю пропасти. Вставив предмет в камень, вы активируете его, вследствие чего пропасть исчезает. Однако исчезновение преграды не сильно радует вас - капсула исчезает также, а на её месте вы видите необычное для данных мест существо, у которого, прежде чем оно убежит, успеваете заметить ключ от капсулы. Выхода не остается кроме как отправиться на поиски этого существа и капсулы, поскольку без нее домой вы попасть никак не сможете. На пути главному герою встретится множество преград и опасные сущности данного мира. Что это за странный мир, почему он именно такой и как попасть домой - главные вопросы, на которые так хочется найти ответы.
Особенности: Карта мира каждый раз генерируется заново, как и сам мир. Мир динамически изменяется в ходе игры.
Что уже сделано:
По состоянию на 4.09.15:
базовые текстуры
базовые анимации персонажа,
базовая генерация мира,
построение пути прохождения,
алгоритмы наполнения мира,
главное меню и настройки
Скриншоты и гифки:
Маленькая гифка:
Сообщение отредактировал Huntlier - Четверг, 08 Октября 2015, 01:10
Прошу помочь с выбором между GLUT, GLFW, GLEW и freeglut. Буду благодарен, если сможете пояснить в чём разница между ними, что лучше использовать и почему?
Кто может нормально объяснить как это работает? technique for the shader-based dynamic 2D shadows, а ещё лучше на этом примере объяснить Pixel perfect 2D shadow (похож на предыдущий, но доработанный)... Я вообще не могу разобраться в шейдерах, просто не понимаю, весь код в комментах, но всё равно сложно понять, особенно когда не работал с этим. Очень застрял на этом, если можете - распишите что да как работает, сижу уже неделю.
Понятно, видимо способа всё же нет...как раз таки мне и нужно менять переменную, чтобы не вызывать 2 раза SpriteBatch.Begin(), но по видимому этого никак не сделать, хотя я думаю это всё же возможно, только не на уровне SpriteBatch и на более низком
Сообщение отредактировал Huntlier - Четверг, 28 Марта 2013, 16:08
Pocifik, я конечно проверю, но это было бы очень странно, создать внешнюю переменную, передать её методу, а потом изменить, spriteBatch то это не поймёт, ему же мы потом ничего не передаём.
Добавлено (19.03.2013, 00:26) --------------------------------------------- Конечно же не сработало, глупо было даже проверять.
А после требуется изменить BlendState с AlphaBlend на Additive. Но не вызывая End(), а потом заново Begin() уже с другими параметрами... Изменять переменную напрямую не получилось, может есть какой нибудь метод? Или всё же придётся вызывать два раза?
noname, уже реализовал секторы, сделал проще некуда, а именно в самом начале загружаю все секторы и все спрайты в них, НО спрайт это лишь два прямоугольника 1) в котором рисуется текстура 2) указывающий координаты текстуры в атласе. Во время прорисовки все объекты рисуются из нескольких атласов, таким образом оптимизировал и отрисовку. Мир большой, но вот подгружать секторы не стану, не хочу лишний раз лезть в файл за данными. Проверку коллизий и отрисовку делаю лишь 9ти секторов, каждый сектор будет размером около 1500х1500 пикселей, в идеале 2048Х2048 (если считать в координатах, тобешь столько и пикселей условно), таким образом всё получилось довольно просто. Единственное, используя атласы, мне пришлось отказаться от попиксельной коллизии.
Цитата (noname)
как ты будешь создавать карту огромного мира?
Планирую в ближайшее время создать приступить к редактору мира (mapeditor), но сначала нужно управление персонажем изменить, а то он не падает, наворотил уж очень, всё таки первый раз тяжеловато делать)
Сообщение отредактировал Huntlier - Воскресенье, 17 Марта 2013, 01:07
Спасибо за ответы, ещё такой вопрос, если динамический объект ( допустим персонаж ) находится на стыке двух секторов? Как самый правильный вариант - это считать коллизию для обоих секторов, но не прибавится ли от этого существенный лагов на переходах из сектора в сектор?
P.S. проверить в действии ещё не могу...
Добавлено (13.02.2013, 19:57) --------------------------------------------- Наконец руку дошли до реализации всей системы, сейчас возник один вопрос, как лучше реализовать загрузку\выгрузку секторов, а точнее спрайтов (я под словом спрайт имею ввиду текстуру и её координаты)... Пока пришёл только к нескольким вариантам: 1) Загрузить сразу все сектора, ничего не выгружать и не загружать в процессе игры, а лишь рисовать или не рисовать сектор. 2) Загрузить сразу все спрайты, но без текстур (то есть только координаты расположения текстур), а в процессе игры загружать (именно загружать, а не копировать загруженные) текстуры приписанные каждому сектору по ID который будет хранится в каждом спрайте, при выгрузке просто высвобождать память под текстуру. 3) Загрузить сразу все текстуры и отдельно от текстур все сектора с их спрайтами (содержащими только координаты), а далее при активации сектора копировать уже загруженные текстуры в спрайты сектора, а когда сектор не нужен - выгружать текстуры из спрайтов сектора.
Ещё был 4 вариант: Все текстуры держать в одном большой файле, а спрайт содержал бы только два прямоугольника (1ый куда будет рисовать, то есть с координатами, 2ой что будет рисовать, то есть координаты текстуры в главном файле), тогда, всё сводилось бы только к загрузке и выгрузки 8 целочисленных переменных...НО тогда я не знаю как сделать попиксельную коллизию, ибо в моём случае она проверяется как раз таки сравнением каждого пикселя текстуры, а текстур то в спрайтах нет, есть только их прямоугольники, то есть обычное столкновение прямоугольников... По этому 4 вариант я отбросил. Хотя может есть какой то вариант попиксельной коллизии при условии что все текстуры в одном файле?
Собственно интересует мнение, какой из этих способов будет более быстрым и качественным в плане скорости и памяти... Делаю движок для игры, по этому сам проверить что быстрее не могу, а потом перебирать код как то не хочется.
Если есть другие варианты буду признателен если поделитесь )
XNA - это набор инструментов, в который уже встроена работа с DirectX и ещё куча всего для написания игр, а OpenGL - это API для работы с графикой, графическая библиотека, их нельзя сравнивать.
vasua99, а почему бы просто не начать делать какую нибудь игру? Там вы всё и сможете применить, сразу поймёте что вам очень нужно, а что не особо. По сабжу задачников не встречал нигде, по Си только знаю один, но там вы точно не сможете применить то, что есть в C#, так что ИМХО лучше сразу начинать, пробовать, учится сразу на деле.
Единственный вопрос, как определять принадлежность динамических объектов к сектору? Каждый раз проверять в "активных" (которые близко к персонажу) секторах координаты всех динамических объектов и определять принадлежность или же у каждого динамического объекта сверять координаты с координатами всех секторов и так определять принадлежность?
Собственно, делаю 2D rpg (этим мало кого удивишь тут), мой первый опыт так скажем, но если не будет проблем с художником, то игра будет очень не плохой, в плане механики куча идей, да и сюжет возможно не плох, но до этого ещё далеко...возник вопрос как же сделать коллизии и как вообще их считать в большом мире (единый мир, практически без отдельных локаций), про коллизии знаю много, но вот код популярнейших примеров понять до конца так и не смог, кто может пожалуйста объясните до мелочей (а лучше комментариями к каждой строке кода)?
На примере этого
Code
public static bool IntersectPixels(Rectangle rectangleA, Color[] dataA, Rectangle rectangleB, Color[] dataB) { // Find the bounds of the rectangle intersection int top = Math.Max(rectangleA.Top, rectangleB.Top); int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom); int left = Math.Max(rectangleA.Left, rectangleB.Left); int right = Math.Min(rectangleA.Right, rectangleB.Right);
// Check every point within the intersection bounds for (int y = top; y < bottom; y++) { for (int x = left; x < right; x++) { // Get the color of both pixels at this point Color colorA = dataA[(x - rectangleA.Left) + (y - rectangleA.Top) * rectangleA.Width]; Color colorB = dataB[(x - rectangleB.Left) + (y - rectangleB.Top) * rectangleB.Width];
// If both pixels are not completely transparent, if (colorA.A != 0 && colorB.A != 0) { // then an intersection has been found return true; } } }
public bool CollidesWith(Sprite other, bool calcPerPixel) { // Get dimensions of texture int widthOther = other.Texture.Width; int heightOther = other.Texture.Height; int widthMe = Texture.Width; int heightMe = Texture.Height;
if ( calcPerPixel && // if we need per pixel (( Math.Min(widthOther, heightOther) > 100) || // at least avoid doing it ( Math.Min(widthMe, heightMe) > 100))) // for small sizes (nobody will notice :P) { return Bounds.Intersects(other.Bounds) // If simple intersection fails, don't even bother with per-pixel && PerPixelCollision(this, other); }
return Bounds.Intersects(other.Bounds); }
static bool PerPixelCollision(Sprite a, Sprite b) { // Get Color data of each Texture Color[] bitsA = new Color[a.Texture.Width * a.Texture.Height]; a.Texture.GetData(bitsA); Color[] bitsB = new Color[b.Texture.Width * b.Texture.Height]; b.Texture.GetData(bitsB);
// Calculate the intersecting rectangle int x1 = Math.Max(a.Bounds.X, b.Bounds.X); int x2 = Math.Min(a.Bounds.X + a.Bounds.Width, b.Bounds.X + b.Bounds.Width);
int y1 = Math.Max(a.Bounds.Y, b.Bounds.Y); int y2 = Math.Min(a.Bounds.Y + a.Bounds.Height, b.Bounds.Y + b.Bounds.Height);
// For each single pixel in the intersecting rectangle for (int y = y1; y < y2; ++y) { for (int x = x1; x < x2; ++x) { // Get the color from each texture Color a = bitsA[(x - a.Bounds.X) + (y - a.Bounds.Y)*a.Texture.Width]; Color b = bitsB[(x - b.Bounds.X) + (y - b.Bounds.Y)*b.Texture.Width];
if (a.A != 0 && b.A != 0) // If both colors are not transparent (the alpha channel is not 0), then there is a collision { return true; } } } // If no collision occurred by now, we're clear. return false; }
private Rectangle bounds = Rectangle.Empty; public virtual Rectangle Bounds { get { return new Rectangle( (int)Position.X - Texture.Width, (int)Position.Y - Texture.Height, Texture.Width, Texture.Height); }
}
Коллизии можно ещё понять, но если учитывать, что мир огромен, не считать же коллизии на каждом шаге относительно всех объектов, да и считать ближайшие объекты, а относительно них коллизии тоже не особо радует, собственно появилась идея сделать следующим образом, весь мир разделить на сетку из большого количества секторов, в каждом секторе будет список динамических (куда будет входить персонаж, противники, снаряды, другими словами всё что там находится в данный момент времени) и статических объектов (ну это понятно, окружающий мир), таким образом можно решить проблему с огромным количеством просчётов коллизий, каждый Update сектор в котором есть активные динамические объекты (персонаж например), будет просчитывать коллизию каждого динамического объекта относительно окружающих объектов, на самом деле так как мне кажется решается ещё и проблема отрисовки большого количества объектов, одновременно будут рисоваться только ближайшие к персонажу сектора, единственное, каждый Update, нужно будет определять принадлежность динамических объектов определённому сектору (понятное дело не всех в мире, а только тех которые находятся в ближайших секторах), как считаете так будет нормально работать или есть алгоритмы по проще?
P.S. сейчас реализовать секторы до конца не могу, из за того что тупо не дошёл до списков объектов в C#, встречался с ними, но сам не использовал. В плане знания ЯП: С++ доучиваю, C# в процессе изучения.
Заранее спасибо.
Добавлено (24.11.2012, 19:58) --------------------------------------------- Хах, только сейчас понял, что весь код уже с комментариями Ладно, с коллизиями вопрос закрыт, а как на счёт разбиения на секторы? Есть у кого мысли по этому поводу?)