Страница 2 из 6

Хранение данных в игре

Добавлено: 23 ноя 2011, 21:50
Vasaka
krupennikov писал(а): 23 ноя 2011, 20:51Если речь идет об однопользовательской игре, то вопрос такой: где легче изменить данные - в ОЗУ или на жестком диске? В любом случае, при большом желании можно сделать и то и другое, но не вижу смысла для игрока, для него самого пропадет интерес к игре. Если речь идет о многопользовательской игре, то для этого в любом случае будет писаться отдельный код и использоваться реальная БД с сервера. Как по мне, так удобнее использовать вместо List именно DataTable, и делать выборку данных с реальной БД также удобнее с помощью DataTable (DataSet).

В мануале к Юнити написано, что один и тот же код используется для однопользовательской и многопользовательской игры.

Я сейчас попробую поискать где это было написано.

Хранение данных в игре

Добавлено: 23 ноя 2011, 21:54
AndreyKl
Vasaka писал(а): 23 ноя 2011, 21:50В мануале к Юнити написано, что один и тот же код используется для однопользовательской и многопользовательской игры.
Это не от Unity зависит, но для всех игроков действительно будет использоваться один и тот же код помимо хоста/арбитра или когонить со спецификой доступа - он единственный будет иметь доступ к открытию нового хода. во всяких FPS код может был бы один (хотя и там часто можно сервер выделить).
Конечно можно реализовать и общий код для всех, просто разделить права доступа. но по мне проще сделать формочку с строчкой для пароля и кнопочкой ран хосту.

Так же для пошаговых стратегий для мультика придется переделывать всю систему, дабы предотвратить сейв/лоад (пока само правильное решение в серии Space empires) - но графический движек всеравно останется тот же.

Хранение данных в игре

Добавлено: 23 ноя 2011, 23:54
Vasaka

Хранение данных в игре

Добавлено: 24 ноя 2011, 18:38
AndreyKl
Networked Multiplayer
Реализация сети в реальном времени — сложная задача, но мы сделали её максимально простой. В этом параграфе будут рассмотрены основные сетевые концепции и специфичные для Unity детали. Настоятельно рекомендуем внимательно прочитать эту главу всем пользователям, которые ранее не создавали сетевых игр.
Ключевым аспектом здесь является реальное время, которого у нас нет в помине. Для пошаговых игр мультиплеер вообще можно без сети делать - хоть на флешке файлы переноси (или подключайся к удаленной БД стандартными средствами если сейвы будут на основе БД).

Хранение данных в игре

Добавлено: 24 ноя 2011, 20:05
Vasaka
AndreyKl писал(а): 24 ноя 2011, 18:38Ключевым аспектом здесь является реальное время, которого у нас нет в помине. Для пошаговых игр мультиплеер вообще можно без сети делать - хоть на флешке файлы переноси (или подключайся к удаленной БД стандартными средствами если сейвы будут на основе БД).

Ясно.

Ты уже пробовал поработать с БД на Юнити?
4 гига, это ограничение на размер БД?

Хранение данных в игре

Добавлено: 25 ноя 2011, 11:04
krupennikov
AndreyKl писал(а): 23 ноя 2011, 21:49вот тут уж поверьте наслово, дататейбл по сравнению с ентити нервно курит в сторонке - через ентити по всем элементам базы можно пробегаться не прибегая к помощи linq, даже выборки делать, визуально никакого отличия от List нет помимо немного переименованных Add, наличия команд save/refresh и ивент обновления(кстати про рефрешь узнал только когда обнаружил, что программа оперирует с элементами удаленными из БД 2-3 часа назад).


С ентити я ни разу не работал, поэтому спорить с этим не буду. Возможно это действительно так. И если это так, то готов отказаться от DataSet и в своих проектах. Андрей, если есть возмножность, выложи пример недожидаясь меня. У меня завал в работе. Я уже начал писать пример, но пишу перерывами... Даже выкладывал на ХэшКоде вопрос какую БД можно использовать так , чтобы не требовалась дополнительная установка платного ПО, и в тоже время можно было программно в шарпе создавать и изменять таблицы с нуля, а не лезть в сторонний редактор. SQL server мне не понравился. Если ентити то что я искал, то буду очень рад и надеяться на содействие в помощи его изучения с твоей стороны (надеюсь можно и на ТЫ, не люблю ВЫкать)

Хранение данных в игре

Добавлено: 25 ноя 2011, 11:23
krupennikov
вот что сделал на скорую руку в два подхода по 15-20 мин. Но тут совсем малость и как говорится тема не раскрыта. Делал в C# Express 2010

Хранение данных в игре

Добавлено: 26 ноя 2011, 02:46
AndreyKl
Вот самый плешивенький пример на одну таблицу. Писать чтолибо сложнее пока не охота. Но приведу пример по связям на словах.
Если есть елемент car таблицы CarsSet (содержащая поле марок Marks_Id), и таблица MarksSet (содержашея имена марок), то чтобы узнать имя марки выбранной машины достаточно написать car.MarksSet.Name. Определить эффективность этого дества вызванного вне запросов Linq я не смог - по непонятной мне причине запросы к БД не всегда приходили даже при единичных вызовах поля Name (либо всё жутко оптимизировано и идет работа с ОЗУ, либо мелкософт жульничает и ввела обходной путь доступа к БД помимо SQL), для построения таблиц linq вытягивала эту информацию сразу.
Должен заметить, что уже вышел Ентити 4.1, я его как раз изучаю. Но и старый очень не плох, до тех пор, пока не нужно его напрямую привязывать к WPF binding (много мороки с отслеживанием обновления элементов как из-за самого биндинг так и необходимости refresh БД).
Базу (.sdf) ложить на диск C.

P.S. Регенерить базу не советую, для быстроты ввел кастомный код прямо в её класс - затреться при регенерации.
Все файлы в папке model были сгенерированны автоматически, никакого участия помимо добавленных 2 строк не принимал (просто лень было писать генерацию Id, так как в взятом шаблоне БД не проставил автоинкремент).
Изменение местоположения базы здесь через app.config, но при необходимости строку подключения можно передавать параметром.
P.P.S. У меня так же есть масштабный проэкт на базе Linq и Entity, где уже задействованы связи и т п. Могу скинуть его для ознакомления.

Хранение данных в игре

Добавлено: 27 ноя 2011, 15:18
krupennikov
Андрей, твой файл скачал, но еще не смотрел.
Выкладываю немного дописанный файл DataTableSample.

Вот некоторые вырезки из кода:

Код: Выделить всё



#region Описание
/*
* Для добавления новой таблицы добавьте новый класс в проект BaseLibrary.
* Для добавления нового столбца добавьте новый параметр в необходимый
* класс проекта BaseLibrary, при этом уже имеющиеся данные останутся.
*/
#endregion

#region Метод запроса по определенному столбцу
/*
* Заполнение таблицы результата на запрос tableResult
* необходимо для вывода результата в форме поиска
* исключительно для наглядности. При отсутствии необходимости
* вывода результата для наглядности в виде таблицы, достаточно
* оставить только одну строку запроса такого формата:
* DataRow[] rows = table.Select("имя_столбца='значение'");
* либо, например, для вывода строк столбца 'Сила' со значением больше 10:
* DataRow[] rows = table.Select("Сила>10");
*/
public static DataTable Search(DataTable table, string parametr, string columnName)
{
//формируем запрос
string filter = string.Format("{0}='{1}'", columnName, parametr);
//объявляем новую таблицу для результата запроса
DataTable tableResult = new DataTable();
try
{
//выполняем запрос
var rows = table.Select(filter);

//заполняем таблицу результата столбцами
foreach (var column in rows[0].Table.Columns)
tableResult.Columns.Add(((DataColumn)column).ColumnName);

//заполняем таблицу результата строками
foreach (var row in rows)
{
DataRow r = tableResult.NewRow();
r.ItemArray = row.ItemArray;
tableResult.Rows.Add(r);
}

//возвращаем результат запроса в виде таблицы
return tableResult;
}
catch { return null; }
}

#endregion

#region Метод запроса по всем столбцам таблицы

public static DataTable Search(DataTable table, string parametr)
{
//создаем новую таблицу для результата запроса
DataTable tableResult = new DataTable();

//ЗАПОЛНЯЕМ СТОЛБЦЫ

//Выберите вариант заполнения

/*
// Вариант 1
// Заполнение с помощью List
List<DataColumn> columns = new List<DataColumn>();
columns.AddRange(table.Columns.Cast<DataColumn>());
tableResult.Columns.AddRange(columns.ToArray());
*/

/*
// Вариант 2
// Заполнение с помощью еще одного метода
var cols = (DataColumn[])table.Columns.Cast<DataColumn>().ToArray().Clone();
tableResult.Columns.AddRange(cols);
*/

// Вариант 3
// Заполнение с помощью цикла
foreach (var column in table.Columns)
tableResult.Columns.Add(((DataColumn)column).ColumnName);

//выполняем запрос по всем столбцам таблицы
foreach (var column in table.Columns)
{
try
{
var rows = (Search(table, parametr, ((DataColumn)column).ColumnName)).Rows;
for (int i =0;i<rows.Count;i++)
tableResult.Rows.Add(rows[I].ItemArray);
}
catch { continue; }
}

//возвращаем результат запроса в виде таблицы
return tableResult;
}

Как видно, для поиска значения в DataTable существует удобный метод Select, который возвращает массив строк DataRow[]. Теперь для изменения нужного нам параметра, достаточно написать:
rows[index]["параметр"] = значение;

Например, в таблице Planets нам надо изменить диаметр Земли, присвоив значение 1000. Скажем эта таблица принадлежит переменной table:

DataRow[] rows = table.Select("Имя='Земля'");
rows[0]["Диаметр"] = 1000;

А вот если, например, в таблице Planets нам надо изменить диаметр Земли, увеличив на 10, то число строк увеличится:

DataRow[] rows = table.Select("Имя='Земля'");
var value = (double)rows[0]["Диаметр"];
value += 10;
rows[0]["Диаметр"] = value;

Вот и все. А по поводу выборки из нескольких таблиц, напишу позже. Пора бежать...

Хранение данных в игре

Добавлено: 27 ноя 2011, 21:23
krupennikov
Андрей, если не сложно, выложи что нибудь по изучению Entity. Либо ссылки на нормальное описание. На русском естесно

Добавлено через 58 минут 16 секунд
Выдержка из книги Троелсона:


Несмотря на удобство интерфейса LINQ to DataSet, следует помнить, что целью запроса LINQ являются данные, возвращенные из базы данных, а не сам механизм базы данных. В идеале хотелось бы строить запрос LINQ, который отправлялся бы на обработку непосредственно базе данных, и возвращал строго типизированные данные (именно это и позволяет достичь ADO.NET Entity Framework).
При использовании подключенного и автономного уровней ADO.NET всегда приходится помнить о физической структуре лежащей в основе базы данных. Необходимо знать схему каждой таблицы данных, писать сложные SQL-запросы для взаимодействия с данными таблиц и т.д. Это вынуждает писать довольно громоздкий код С#, поскольку С# существенно отличается от языка самой базы данных.
Вдобавок способ конструирования физической базы данных (администратором баз данных) полностью сосредоточен на таких конструкциях базы, как внешние ключи, представления и хранимые процедуры. Сложность баз данных, спроектированных администратором, может еще более возрастать, если администратор при этом заботится о безопасности и масштабируемости. Это также усложняет код С#, который приходится писать для взаимодействия с хранилищем данных. Платформа ADO.NET Entity Framework (EF) — это программная модель, которая пытается заполнить пробел между конструкциями базы данных и объектно-ориентированными конструкциями. Используя EF, можно взаимодействовать с реляционными базами данных, не имея дело с кодом SQL (при желании). Исполняющая среда EF генерирует подходящее операторы SQL, когда вы применяете запросы LINQ к строго типизированным классам.
На заметку! LINQ to Entities — это термин, описывающий применение запросов LINQ к сущностным объектам ADO.NET.
Другой возможный подход состоит в том, чтобы вместо обновления базы данных посредством нахождения строки, обновления строки и отправки строки обратно на обработку в пакете запросов SQL, просто изменять свойства объекта и сохранять его состояние. И в этом случае исполняющая среда EF обновляет базу данных автоматически.
В Microsoft считают ADO.NET Entity Framework новым членом семейства технологий доступа к данным, и не намерены заменять им подключенный и автономный уровни. Однако после недолгого использования EF часто отдается предпочтение этой развитой объектной модели перед относительно примитивным миром SQL-запросов и коллекций строк/столбцов.
Тем не менее, иногда в проектах .NET используются все три подхода, поскольку одна только модель EF чрезмерно усложняет код. Например, при построении внутреннего приложения, которому нужно взаимодействовать с единственной таблицей базы данных, подключенный уровень может применяться для запуска пакета хранимых процедур. Существенно выиграть от использования EF могут более крупные приложения, особенно если команда разработчиков уверено работает с LINQ. Как с любой новой технологией, следует знать, как (и когда) имеет смысл применять ADO.NET EF.
На заметку! Вспомните, что в .NET 3.5 появился API-интерфейс программирования баз данных под названием LINQ to SQL. Он был построен на основе концепции, близкой (даже очень близкой в смысле конструкций программирования) к ADO.NET ЕЕ Хотя LINQ to SQL формально еще существует, официальное мнение в Microsoft состоит в том, что теперь следует обращать внимание на EF, а не на LINQ to SQL.


Согласно этой выдержки, соглашусь с Андреем, что для использования масштабного проекта лучше использовать Entity для работы с Базой данных. Для менее масштабного проекта DataSet (DataTable) все таки имеет больше преимуществ перед Entity. Хотя мой проект, над которым я в данный момент работаю, менее масштабный (содержит 1 большую таблицу - основную, и несколько маленьких) буду переделывать под Entity, только ради полного и глубокого изучения Entity FrameWork.