ria pc game
fle game engine - движок для создания игр
fle game engine - движок для создания игр


Balls and holes PC game / Balls and Holes PC игра
Вакансии
Игродельня
Сегодня
18 февраля 2019 5:03
Вход Регистрация Забыли пароль ?

megainformatic - Мои Музыкальные Миры
        Мои Музыкальные Миры - готовая музыка mp3 Уроки Fruity Loops Studio (FL Studio) хорошая, позитивная электронная mp3 музыка для вашего компьютера, ноутбука, нетбука
подробнее...

Теги создание сайтов, создание игр, дизайн, игры, информатика, уроки photshop, php, c++, музыка, delphi, cms, робосайт
Статьи сайта
megainformatic - Мастер-класс: Создание модели и текстуры Коммандного Центра (как в StarCraft 2) Часть 2

megainformatic - Мастер-класс: Создание модели и текстуры Коммандного Центра (как в StarCraft 2) Часть 3

megainformatic - Мастер-класс: Создание модели и текстуры Коммандного Центра (как в StarCraft 2) Часть 4

megainformatic - Мастер-класс: Создание модели и текстуры Коммандного Центра (как в StarCraft 2) Часть 5

megainformatic - Мастер-класс: Создание модели и текстуры Коммандного Центра (как в StarCraft 2) Часть 6

Система управления сайтом - megainformatic cms e-shop

Система управления сайтом - megainformatic cms e-shop

Система управления сайтом - megainformatic cms e-shop

megainformatic - Уроки 3ds max - Введение в 3ds max

megainformatic - ГАЛЕРЕЯ 3D-моделей

megainformatic - СОЗДАНИЕ МАКЕТА ПОМЕЩЕНИЯ

megainformatic - Создание макета помещения - этап 2

megainformatic - МОДЕЛИРОВАНИЕ НА УРОВНЕ МНОГОУГОЛЬНИКОВ

megainformatic - СОЗДАНИЕ ПРЕДМЕТОВ ОБСТАНОВКИ ПОМЕЩЕНИЯ

megainformatic - Моделирование обстановки помещения

megainformatic - Создание модели автомобиля

megainformatic - Создание текстурной развертки для модели автомобиля

megainformatic - Создание анимации вращающихся колес автомобиля

megainformatic - игра Нечто: Необъяснимое и в плену желаний

megainformatic - Основы 3D-анимации, экспорт скелетной анимации

megainformatic - Подготовка модели к использованию скелетной анимации

megainformatic - Продолжаем Создание скелета для данной модели

megainformatic - Построение ирерархических связей между объектами и основы 3d анимирования

megainformatic - Особенности экспорта моделей и анимации экспортером kWXPort080719 из 3ds max 2009 

megainformatic - Создание модели броневика (Хэд)

megainformatic cms e-mailer

megainformatic cms e-mailer

megainformatic cms e-mailer

Бесплатная Система Управления Вашим Сайтом - megainformatic cms free

megainformatic - Путешествие в мир 3d

megainformatic - Путешествие в мир 3d - страница 2

megainformatic - Путешествие в мир 3d - страница 3

megainformatic - Путешествие в мир 3d - страница 4

megainformatic - Путешествие в мир 3d - страница 5

megainformatic - Путешествие в мир 3d - страница 6

megainformatic - Создание модели броневика (Хэд) - Анимация вращения колес

megainformatic cms express files

megainformatic cms express files

megainformatic cms express files

megainformatic - Уроки Photoshop - Чудеса

megainformatic cms express files - Развертывание сайта на Вашем хостинге

megainformatic - Настольная игра "Веселый Буквоежка"

megainformatic - Уроки delphi directx 8.1

megainformatic - Уроки delphi directx 8.1 - Урок 1 - Введение в Delphi DirectX 8.1. Создание шаблона стартового приложения.

megainformatic - Уроки delphi directx 8.1 - Урок 1 - Введение в Delphi DirectX 8.1. Создание шаблона стартового приложения. Страница 2

megainformatic - Урок 2 Создаем и обрабатываем команды меню.

megainformatic - Урок 2 Создаем и обрабатываем команды меню. Страница 2

megainformatic - Урок 3 Оконный и полноэкранный режимы работы D3D-приложения. Управление игрой средствами DirectInput8

megainformatic - Урок 3 Оконный и полноэкранный режимы работы D3D-приложения. Управление игрой средствами DirectInput8 - Страница 2

megainformatic - Урок 3 Оконный и полноэкранный режимы работы D3D-приложения. Управление игрой средствами DirectInput8 - Страница 3

megainformatic - Урок 4 Построение класса приложения

megainformatic - Урок 4 Построение класса приложения - Страница 2

megainformatic - Урок 5 Построение классов игровых объектов и других необходимых классов

megainformatic - Урок 5 Построение классов игровых объектов и других необходимых классов - Страница 2

megainformatic - Урок 6 Игровая логика

megainformatic - Заметки по joomla - JFolder::create: Path not in open_basedir paths. Что это?

подробнее

 

Что нужно знать для создания DirectX-приложений на C++ в среде
Microsoft Visual Studio 2008

 
     
  Урок 4 Создание Win32-приложений. Стандартные диалоги. Изучение
сопутствующих конструкций языка. Консольные Win32-приложения.
Указатели. Ссылочный тип. Массивы.
 
     
 

Данный урок является введением в программирование на C++ в MSVS 2008

Вам нужно иметь установленную среду Microsoft Visual Studio 2005 или 2008 (можно триал),

и DirectX SDK 9 версии, или лучше самой последней - DirectX SDK August 2008.

 
     
  [назад] [далее] [к содержанию]  
     
  Мы рассматриваем основы программирования на C++ в среде программирования MSVS 2008  
     
 

25/11/2008, 27/11/2008

Общие окна диалога для открытия и сохранения файла при использовании обработки пунктов

меню Save и Load

Работа с общими диалогами в Win32-приложениях описана в разделе

MSVS 2008 > Help > Contents > Win32 and COM Development > User Interface >

Windows User Experience >

Windows Management > Windows User Interface > User Input > Common Dialog Box Library

 
     
 

//++ Учебное задание: использование общего диалога для выбора цвета

Работа с общим диалогом выбора цвета описана в разделе

MSVS 2008 > Help > Contents > Win32 and COM Development > User Interface >

Windows User Experience >

Windows Management > Windows User Interface > User Input > Common Dialog Box Library >

Common Dialog Box Library Overviews > Color Dialog Box

Сопутствующие необходимые знания

chcol.lpCustColors - использование массивов

Требуется указатель на массив из 16-ти элементов типа COLORREF (статичный или локальный)

Работа с массивами в приложениях Win32 (Native Development) описана в разделе справки -

MSVS 2008 > Help > Contents > Development Tools and Languages > Visual Studio >

Visual C++ > Reference >

C/C++ Languages > Declarators > Arrays

 
     
 

Работа с примерами кода в консольных приложениях для лучшего уяснения отдельных

элементов Visual C++

Работа с консольными приложениями позволит Вам освоить наиболее общие конструкции

языка

Visual C++ не вдаваясь в детали создания интерфейса пользователя.

Для создания консольного приложения Win32 нужно закрыть текущий солюшн (Close solution)

с которым Вы

работали и выбрать File > New > Project > Win32 > Win32 Console Application, указать имя и папку

для создаваемого проекта.

Добавить в файл с исходным кодом необходимый код, выполнить сборку Build, а

для просмотра результатов

работы такого приложения выполнять запуск из командной строки Пуск > Все программы >

Стандартные > Командная строка

 
     
 

Например Ваш скомпилированный файл находится в папке

H:\Andrew\work\gamecre\DXSDK_Aug2008\MyWorks\NuPogodiFull\NuPogodiFull_vs2008\

training\LearnPointers\Debug

 
     
 

Тогда, в окне Коммандной строки набираем

H:

и нажимаем Enter. Тем самым переходим на диск H.

копируем нужный путь прямо из проводника.

в коммандной строке набираем

cd

и правой клавишей мыши вызываем контекстное меню и вставляем скопированный путь

получается

cd H:\Andrew\work\gamecre\DXSDK_Aug2008\MyWorks\NuPogodiFull\NuPogodiFull_vs2008\

training\LearnPointers\Debug

нажимаем Enter.

Теперь мы находимся в этой папке.

Можете применить команду dir и вы увидите содержимое этого каталога.

Для очистки экрана консоли удобно использовать команду очистки экрана cls

Теперь Вам остается только набрать имя нужного exe-файла любыми буквами

(хоть большими, хоть маленькими, хоть вразнобой - никакой разницы, т.к. консоль

запускает файлы по именам

без учета регистра (заглавные/строчные)

Далее нажать Enter и увидеть результат работы Вашего консольного приложения.

 
     
 

Далее остается только экспериментировать - изменять код, выполнять новую сборку и

запускать созданное

из консоли наблюдая и анализируя полученные результаты.

 
     
 

Пример кода для понимания указателей (Pointers) - пример взят из MSVS Documentation

Для проверки и экспериментов с кодом используйте консольное приложение Win32

 
     
  // pointer.cpp
// compile with: /EHsc
#include <iostream>
int main() {
int i = 1, j = 2; // локальные переменные, размещаются в стеке
int *p; // указатель на целое (int)

// a pointer may be assigned to "point to" the value of
// another variable using the & (address of) operator

// указателю может быть присвоен адрес переменной
// содержащей значение посредством оператора &

p = & j;

// since j was on the stack, this address will be somewhere
// on the stack. Pointers are printed in hex format using
// %p and conventionally marked with 0x.

// поскольку j размещено в стеке, адрес будет представлять
// какой-то из адресов стека. Указатели распечатываются в шестнадцатиричном формате

с использованием
// %p в функции printf_s и по соглашению помечаются 0x.

printf_s("0x%p\n", p);

// The * (indirection operator) can be read as "the value
// pointed to by".
// Since p is pointing to j, this should print "2"

// Оператор * (оператор разыменования) может быть читаем как "указатель на значение"
// Поскольку p указывает на j, будет выведено "2"

printf_s("0x%p %d\n", p, *p);

// changing j will change the result of the indirection
// operator on p.

// изменение j изменит результат применения оператора разыменования
// к p.

j = 7;
printf_s("0x%p %d\n", p, *p );

// The value of j can also be changed through the pointer
// by making an assignment to the dereferenced pointer

// значение j может быть также изменено посредством указателя
// выполнением присвоения к разыменованному указателю

*p = 10;
printf_s("j is %d\n", j); // j теперь равно 10

// allocate memory on the heap for an integer,
// initialize to 5

// выделение памяти на куче (heap) для целого и,
// инициализация значением 5

p = new int(5);

// print the pointer and the object pointed to
// the address will be somewhere on the heap

// печать указателя и объекта на который указывает адрес
// где-то на куче (heap)

printf_s("0x%p %d\n", p, *p);

// free the memory pointed to by p

// освобождение памяти на которую указывает p
delete p;

// At this point, dereferencing p with *p would trigger
// a runtime access violation.

// с этого места разыменование p как *p будет давать
// ошибку нарушения прав доступа к памяти во время выполнения программы

// Pointer arithmetic may be done with an array declared
// on the stack or allocated on the heap with new.
// The increment operator takes into account the size
// of the objects pointed to.

// Вычисления с указателями могут выполняться для массива объявленного
// на стеке или выделенного на куче с помощью new.
// Оператор инкремента использует размер
// объектов на которые указывает указатель

p = new int[5];
for (i = 0; i < 5; i++, p++) {
*p = i * 10;
printf_s("0x%p %d\n", p, *p);
}

// A common expression seen is dereferencing in combination
// with increment or decrement operators, as shown here.
// The indirection operator * takes precedence over the
// increment operator ++.
// These are particularly useful in manipulating char arrays.

// Часто встречаемое выражение разыменования в комбинации
// с операторами инкремента или декремента выглядит так, как показано ниже.
// Оператор разыменования * выполняется перед оператором инкремента ++
// Это эффективно при манипуляциях с символьными массивами

char s1[4] = "cat";
char s2[4] = "dog";
char* p1 = s1;
char* p2 = s2;

// the following is a string copy operation

// операция копирования строки выглядит так -
while (*p1++ = *p2++);

// s2 was copied into s1, so now they are both equal to "dog"

// s2 копируется в s1, так что теперь обе строки содержат слово "dog"
printf_s("%s %s", s1, s2);
}

 
     
 

А вот пример демонстрирующий использование указателей в структурах данных, в данном случае

это связанный список. Пример также взят из MSVS Documentation

 
     
  // pointer_linkedlist.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;

struct NewNode {
NewNode() : node(0){}
int i;
NewNode * node;
};

void WalkList(NewNode * ptr) {
if (ptr != 0) {
int i = 1;
while (ptr->node != 0 ) {
cout << "node " << i++ << " = " << ptr->i << endl;
ptr = ptr->node;
}
cout << "node " << i++ << " = " << ptr->i << endl;
}
}

void AddNode(NewNode ** ptr) {
NewNode * walker = 0;
NewNode * MyNewNode = new NewNode;
cout << "enter a number: " << endl;
cin >> MyNewNode->i;

if (*ptr == 0)
*ptr = MyNewNode;
else {
walker = *ptr;
while (walker->node != 0)
walker = walker->node;

walker->node = MyNewNode;
}
}

int main() {
char ans = ' ';
NewNode * ptr = 0;
do {
cout << "a (add node) d (display list) q (quit)" << endl;
cin >> ans;
switch (ans) {
case 'a':
AddNode(&ptr);
break;
case 'd':
WalkList(ptr);
break;
}
} while (ans != 'q');
}

 
     
 

примеры ссылочных (reference) типов -

int &i;
int &i, &j;

 
     
 

читается как ссылка (адрес) на объект i. Синтаксически работа со ссылками полностью аналогична

работе с объектами -

// references.cpp
#include <stdio.h>
struct S {
//структура S содержащая поле i с типом short
short i;
};

int main() {
S s; // Declare the object.
объявляем объект
S& SRef = s; // Declare the reference.
объявляем ссылку
s.i = 3;

printf_s("%d\n", s.i);
printf_s("%d\n", SRef.i);

SRef.i = 4;
printf_s("%d\n", s.i);
printf_s("%d\n", SRef.i);
}

 
     
 

Определение массивов, работа с массивами

объявление массива и работа с массивом времени выполнения -

// arrays.cpp
// compile with: /EHsc
#include <iostream>

int main() {
using namespace std;
int size = 3, i = 0;
//определяем размер массива и индекс

int* myarr = new int[size]; //объявляем массив из size элементов с типом int и выделяем ему

память на куче (heap)

for (i = 0 ; i < size ; i++)
myarr[i] = 10;
//заносим значения в элементы массива

for (i = 0 ; i < size ; i++)
printf_s("myarr[%d] = %d\n", i, myarr[i]);
//печатаем значения элементов массива

delete [] myarr; //освобождаем память
}

 
     
 

После получения необходимой информации из документации и экспериментов с учебными

примерами кода возвращаемся к нашей задаче -

//++ Учебное задание: использование общего диалога для выбора цвета

Работа с общим диалогом выбора цвета описана в разделе

MSVS 2008 > Help > Contents > Win32 and COM Development > User Interface >

Windows User Experience >

Windows Management > Windows User Interface > User Input > Common Dialog Box Library >

Common Dialog Box Library Overviews > Color Dialog Box

Сопутствующие необходимые знания

chcol.lpCustColors - использование массивов

Требуется указатель на массив из 16-ти элементов типа COLORREF (статичный или локальный)

Реализация данной задачи - вывод диалога выбора цвета например при нажатии пункта меню

Save будет выглядеть так (код нужно добавить в функцию WndProc) - показана в следующем уроке

 
     
 

в следующем уроке показана реализация выбора цвета из окна диалога цвета (Color Dialog) и

смена фона окна приложения в соответствии с выбранным цветом

 
     
     
     
     
     
     
     
     
     
  [назад] [далее] [к содержанию]  
подробнее

     
  [Назад] [Все уроки] [Далее]  
     
 

12/06/2008 Воспроизведение файлов в форматах *.it, *.xm, *.s3m, *.mod

продолжение...

 
[назад]
 

Теперь рассмотрим код, который должен осуществляться при уничтожении приложения - во время закрытия окна формы в данном примере -

procedure TfrmMain.FormClose

 
FMUSIC_StopAllSongs(); //останавливаем все играющие звуковые файлы
for Index := 0 to MAX_SONGS - 1 do
begin
if FSongs[Index].Module <> nil then
begin
FMUSIC_FreeSong(FSongs[Index].Module);
//освобождаем ресурсы памяти от трекерских файлов и
end
else if FSongs[Index].Stream <> nil then
begin
FSOUND_Stream_Stop(FSongs[Index].Stream);
//файлов-потоков (таких как wav, mp2, mp3, ogg и подобных)
FSOUND_Stream_Close(FSongs[Index].Stream);
end;
end;
FSpectrum.Free;
//удаляем объект спектрального анализатора

FMOD_Unload; //и выгружаем библиотеку fmod.dll из памяти

 

Мы выяснили что должно происходить во время старта и уничтожения приложения.

Рассмотрим как осуществить загрузку, выгрузку, проигрывание, останов, регулировку позиции текущего паттерна, громкости, организацию одновременного воспроизведения нескольких файлов и прочие особенности.

 

загрузка - procedure TfrmMain.btnLoadClick

Проверяем сколько файлов уже есть в списке и выводим предупреждение об ошибке если их больше допустимого

SongCount := lbxFiles.Items.Count;

if SongCount = MAX_SONGS then
begin
Application.MessageBox(PChar(Format('Limit of %d songs reached', [MAX_SONGS])), 'Load error', MB_OK or MB_ICONHAND);
Exit;
end;

 

Для очередного элемента открытых файлов -

Пробуем открыть файл как трек, а затем как поток

Stream := nil;
Module := FMUSIC_LoadSong(PChar(dlgOpen.Files[Index]));
if Module = nil then
begin
Stream := FSOUND_Stream_Open(PChar(dlgOpen.Files[Index]), FSOUND_NORMAL or FSOUND_LOOP_NORMAL, 0, 0);
end;

Если никак не удалось - снова предупреждение

if (Module = nil) and (Stream = nil) then
begin
Application.MessageBox(FMOD_ErrorString(FSOUND_GetError), 'Load error', MB_OK or MB_ICONHAND);
Continue;
end;

 

Если трек загрузился, то установить громкость для данного трека на максимум, а шаг панорамы на 15%

if Module <> nil then
begin
FMUSIC_SetMasterVolume(Module, 255);
if (FMUSIC_GetType(Module) = FMUSIC_TYPE_MOD) or (FMUSIC_GetType(Module) = FMUSIC_TYPE_S3M) then
FMUSIC_SetPanSeperation(Module, 0.15); // 15% crossover
end;

 

Присваиваем полученные обработчики трека и потока данному элементу массива воспроизводимых файлов, индикатор проигрывания сброшен

FSongs[SongCount].Module := Module;
FSongs[SongCount].Stream := Stream;
FSongs[SongCount].Playing := False;

lbxFiles.Items.Add(ExtractFileName(dlgOpen.Files[Index])); //эта особенность актуальна лишь для примера testbed.dpr
lbxFiles.ItemIndex := SongCount;
//имя файла добавляется в список и текущим в списке становится данный файл

 

После этого вызывается псевдо-щелчок по файлу. Это приводит к считыванию текущих параметров из модуля (потока) данного файла, но это уже более актуально для примера testbed.dpr, хотя что-то может пригодиться и в игровом приложении

{...}

lbxFilesClick(nil);

 

выгрузка мелодии из памяти -

procedure TfrmMain.btnDeleteClick

определяем текущий элемент списка и останавливаем,

Index := lbxFiles.ItemIndex;
if Index < 0 then
Exit;

btnStopClick(nil);

 

а затем удаляем его -

lbxFiles.Items.Delete(Index);
// сдвигаем нижележащие элементы на освободившуюся позицию
if lbxFiles.Items.Count > 0 then
begin
if Index < lbxFiles.Items.Count - 1 then
begin
for Index2 := Index to lbxFiles.Items.Count - 2 do
FSongs[Index2] := FSongs[Index2 + 1];
end;
if Index < lbxFiles.Items.Count then
lbxFiles.ItemIndex := Index
else
lbxFiles.ItemIndex := lbxFiles.Items.Count - 1;
end;
lbxFilesClick(nil); //оcвежаем параметры для нового текущего файла

 

Воспроизведение мелодии -

procedure TfrmMain.btnPlayClick

Выбранная мелодия останавливается, если она уже играла

Index := lbxFiles.ItemIndex;

if Index < 0 then
Exit;

if FSongs[Index].Playing then
btnStopClick(Sender);

Включаем воспроизведение текущей мелодии списка

if FSongs[Index].Module <> nil then
begin
FSongs[Index].Playing := FMUSIC_PlaySong(FSongs[Index].Module);
if not FSongs[Index].Playing then
Application.MessageBox(FMOD_ErrorString(FSOUND_GetError), 'Play song', MB_OK or MB_ICONHAND);
end

 

или потока, если это поток

else if FSongs[Index].Stream <> nil then
begin
FSongs[Index].Channel := FSOUND_Stream_Play(FSOUND_FREE, FSongs[Index].Stream);
FSongs[Index].Playing := FSongs[Index].Channel >= 0;
if not FSongs[Index].Playing then
begin
Application.MessageBox(FMOD_ErrorString(FSOUND_GetError), 'Play stream', MB_OK or MB_ICONHAND);
end

 

если звуковой поток уже играет, то включить воспроизведение стерео, громкость на максимум

else
begin
FSOUND_SetPan(FSongs[Index].Channel, FSOUND_STEREOPAN);
FSOUND_SetVolume(FSongs[Index].Channel, 255);
end;

 

Остановка воспроизведения -

procedure TfrmMain.btnStopClick

Определяем текущую мелодию

Index := lbxFiles.ItemIndex;

if Index < 0 then
Exit;

Если это трекерский модуль - применяем команду остановки для него

if FSongs[Index].Module <> nil then
FMUSIC_StopSong(FSongs[Index].Module)

если это потоковое аудио - применяем другую команду остановки
else if FSongs[Index].Stream <> nil then
FSOUND_Stream_Stop(FSongs[Index].Stream);

Текущий канал потока - неопределен, индикатор проигрывания сброшен
FSongs[Index].Channel := -1;
FSongs[Index].Playing := False;

 

Регулировка громкости текущей мелодии -

Если не установка регулятора глобальной громкости

if not FSettingMasterVolume then
begin

Определяем текущую композицию
Index := lbxFiles.ItemIndex;
if Index > -1 then
begin

для модуля применяем свою команду
if FSongs[Index].Module <> nil then
begin
FMUSIC_SetMasterVolume(FSongs[Index].Module, trkMasterVolume.Position);
lblSongMasterVolume.Caption := Format('%3.3d', [trkMasterVolume.Position]);
//это актуально для элемента управления

//регулятором
end
else if FSongs[Index].Stream <> nil then

для потока - свою
begin
FSOUND_SetVolume(FSongs[Index].Channel, trkMasterVolume.Position);
lblSongMasterVolume.Caption := Format('%3.3d', [trkMasterVolume.Position]);
//это актуально для элемента управления

//регулятором
end;
end;
end;

 

Регулировка текущего воспроизводимого паттерна в трекерском модуле -

переход к предыдущему паттерну порядка воспроизведения -

procedure TfrmMain.btnPrevOrderClick(Sender: TObject);
var
Index: Integer;
Order: DWORD;
begin

считываем текущий модуль
Index := lbxFiles.ItemIndex;
if Index < 0 then
Exit;

если это трекерский модуль - считываем текущий индекс элемента порядка воспроизведения и уменьшаем его на 1
if FSongs[Index].Module = nil then
Exit;
Order := FMUSIC_GetOrder(FSongs[Index].Module);
if Order > 0 then
FMUSIC_SetOrder(FSongs[Index].Module, Order - 1);
end;

 

для переключения на следующий паттерн всё аналогично кроме строк -

т.е. приращаем индекс на +1

if Order < FMUSIC_GetNumOrders(FSongs[Index].Module) then
FMUSIC_SetOrder(FSongs[Index].Module, Order + 1);

 

внутри метода периодической работы таймера представлены ряд интересных команд -

procedure TfrmMain.tmrMainTimer(Sender: TObject);
var
Index: Integer;
begin

для игрового проекта это по большому счету не особо нужная информация, но все-таки полезна
lblCPU.Caption := Format('%.1f%%', [FSOUND_GetCPUUsage]);
//например можно определять загруженность процессора
lblChannels.Caption := Format('%3.3d', [FSOUND_GetChannelsPlaying]);
//музыкой и количество занятых звуковых каналов

//это полезно, т.к. для музыки не существует такого понятия как FPS, зато вышеуказанные параметры могут служить в какой-то мере для целей оценки быстродействия работающего проекта
Index := lbxFiles.ItemIndex;
if Index > -1 then
begin
ShowSpectrum;
ShowDynamicSongInfo(Index);
//данный метод будет полезен с точки зрения наблюдения за текущей позицией воспроизведения
if FMUSIC_IsFinished(FSongs[Index].Module) and chkPlaylist.Checked then
//если мелодия кончилась и установлен индикатор работы в режиме плей-листа - т.е. списка воспроизведения, то переход к следующей мелодии
begin
btnStopClick(nil);
Inc(Index);
if Index >= lbxFiles.Items.Count then
Index := 0;
lbxFiles.ItemIndex := Index;
lbxFilesClick(nil);
btnPlayClick(nil);
end;
end;
{ ... }

end;

 

Конфигурирование - выбор драйвера и параметров фильтрации -

Настройки конфигурирования происходят в модуле формы TfrmConfig -

С точки зрения наших задач заслуживает внимания метод модуля config.pas -

Считываются параметры установленные в окне формы конфигуратора и применяются к объекту FSOUND.

procedure TfrmConfig.btnOkClick(Sender: TObject);
var
Flags: Cardinal;
begin
FSOUND_SetOutput(OutputTypes[cbxOutputType.ItemIndex]);
FSOUND_SetDriver(cbxOutputDevice.ItemIndex);
FSOUND_SetMixer(TFSoundMixerTypes(cbxMixerType.ItemIndex));
Flags := 0;
if chkSoftwareMIDI.Checked then
Flags := Flags or FSOUND_INIT_USEDEFAULTMIDISYNTH;
if chkGlobalFocus.Checked then
Flags := Flags or FSOUND_INIT_GLOBALFOCUS;
FSOUND_Init(OutputRates[cbxOutputRate.ItemIndex], 128, Flags);
end;

 
Оставшиеся нерассмотренными здесь методы, я думаю, Вы разберете самостоятельно.
 
Теперь переходим к практическим упражнениям - реализации использования FMOD 3.75 для воспроизведения музыки и звуков в трекерских и потоковых форматах.
 

Файл fmod.dll размещаем в папке проекта, в настройках проекта указываем ссылку на интерфейсы в delphi-исходниках - fmod375;

В секции interface

uses

добавляем ссылку на fmodtypes

В секции implementation

uses

добавляем ссылки на fmod, fmoderrors

 

Внутри класса приложения объявляем 2 метода -

//music functions
procedure InitMusicLib;
procedure FreeMusicLib;

 

Пишем реализацию данных методов -

procedure TD3DGameApp.InitMusicLib;
var
Index: Integer;
begin
FMOD_Load(nil);

{ Check version numbers }
if FMOD_VERSION > FSOUND_GetVersion then
begin
MessageBox(g_d3dApp.m_hWnd, PChar(Format('API version %3.2f is newer than DLL version %3.2f', [FMOD_VERSION, FSOUND_GetVersion])), 'Version mismatch', MB_OK or MB_ICONERROR);
Halt;
end;

{ Initialize FSOUND }
try
if not FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND) then
raise Exception.Create('FSOUND_SetOutput failed');
if not FSOUND_SetDriver(0) then
raise Exception.Create('FSOUND_SetDriver failed');
if not FSOUND_SetMixer(FSOUND_MIXER_QUALITY_AUTODETECT) then
raise Exception.Create('FSOUND_SetMixer failed');
if not FSOUND_SetHWND(g_d3dApp.m_hWnd) then
raise Exception.Create('FSOUND_SetHWND failed');
except
MessageBox(g_d3dApp.m_hWnd, FMOD_ErrorString(FSOUND_GetError), 'Initialization', MB_OK or MB_ICONHAND);
raise;
end;

if not FSOUND_Init(22050, 128, 0) then
begin
MessageBox(g_d3dApp.m_hWnd, FMOD_ErrorString(FSOUND_GetError), 'FSOUND_Init', MB_OK or MB_ICONHAND);
Halt;
end;

{ Initialize song list to empty }
for Index := 0 to MAX_SONGS - 1 do
begin
FSongs[Index].Module := nil;
FSongs[Index].Stream := nil;
FSongs[Index].Channel := -1;
end;

FTrackNumber := 0;
FNumTracks := 0;

LoadPlaylist(DefaultThemes); //данный метод будет реализован далее (см. ниже)

end;

 

procedure TD3DGameApp.FreeMusicLib;
var
Index: Integer;
begin
FMUSIC_StopAllSongs;
for Index := 0 to MAX_SONGS - 1 do
begin
if FSongs[Index].Module <> nil then
begin
FMUSIC_FreeSong(FSongs[Index].Module);
end
else if FSongs[Index].Stream <> nil then
begin
FSOUND_Stream_Stop(FSongs[Index].Stream);
FSOUND_Stream_Close(FSongs[Index].Stream);
end;
end;

FreePlayList; //данный метод будет реализован далее (см. ниже)

FMOD_Unload;
end;

 
Как видим нам почти ничего даже переделывать не пришлось, только опустили кое-какой код и изменили вызовы MessageBox.
 

Я организую вызов данных методов внутри TD3DGameApp.CreateSoundObjects и TD3DGameApp.DestroySoundObjects.

Где будете делать это Вы - решать Вам. Можете поступить аналогично. Следует иметь в виду, что метод InitMusicLib должен вызываться только после того, как окно приложения будет создано и обработчик окна - m_hWnd в нашем случае обретет своё действительное значение - в противном случае будут только ошибки... ошибки... и ошибки...

 

 
Теперь реализуем загрузку нужных мелодий в список. Для удобства и наименьших изменений кода можно сделать это организовав загрузку требуемого списка мелодий из обычного текстового файла, где бы каждая строка соответствовала полному имени файла внутри дистрибутива игры. Таким способом и Вы и Ваши пользователи будут вольны не только слушать в игре то что было предопределено ее дистрибутивом, но и любые другие файлы мелодий поддерживаемых форматов.
 
Единственным ограничением списка воспроизведения является количество файлов в нем - не более 512, но это ограничение легко обойти использовав столько плей-листов сколько нужно. Конечно же в каждый момент времени работа будет осуществляться только с выбранным списком.
 

Загрузка списка мелодий из текстового файла const DefaultThemes = 'Media\Music\muzon_themes.txt'; -

Код уже должен быть Вам знаком по предыдущему повествованию, особо нового ничего нет

procedure TD3DGameApp.LoadPlaylist(PlayList: string);
var
Index: Integer;
Module: PFMusicModule;
Stream: PFSoundStream;
SongCount: Integer;
begin

создаем список строк будущего плей-листа и загружаем
FTMSPlayList := TStringList.Create;
try
FTMSPlayList.LoadFromFile(PlayList);
except
MessageBox(g_d3dApp.m_hWnd, PChar('Playlist '+PlayList+' not found!'),
'Playlist load Error', MB_OK or MB_ICONHAND);
end;

SongCount := FTMSPlayList.Count;

предупредить, если мелодий в списке больше допустимого!

if SongCount = MAX_SONGS then
begin
MessageBox(g_d3dApp.m_hWnd, PChar(Format('Limit of %d songs reached',
[MAX_SONGS])), 'Load error', MB_OK or MB_ICONHAND);
Exit;
end;

загружаем файлы списка в массив FSongs

for Index := 0 to SongCount - 1 do begin
Stream := nil;
Module := FMUSIC_LoadSong(PChar(FTMSPlayList[Index]));
if Module = nil then
begin
Stream := FSOUND_Stream_Open(PChar(FTMSPlayList[Index]),
FSOUND_NORMAL or FSOUND_LOOP_NORMAL, 0, 0);
end;

if (Module = nil) and (Stream = nil) then
begin
MessageBox(g_d3dApp.m_hWnd, FMOD_ErrorString(FSOUND_GetError),
'Load error', MB_OK or MB_ICONHAND);
Continue;
end;

if Module <> nil then
begin
FMUSIC_SetMasterVolume(Module, 255);
if (FMUSIC_GetType(Module) = FMUSIC_TYPE_MOD)
or (FMUSIC_GetType(Module) = FMUSIC_TYPE_S3M) then
FMUSIC_SetPanSeperation(Module, 0.15); // 15% crossover
end;

FSongs[Index].Module := Module;
FSongs[Index].Stream := Stream;
FSongs[Index].Playing := False;
end;
end;

 

Метод FreePlaylist выглядит совсем просто -

procedure TD3DGameApp.FreePlaylist;
begin
FreeAndNil(FTMSPlayList);
end;

 

Воспроизводим и останавливаем нужный трэк или поток по его номеру в массиве FSongs -

procedure TD3DGameApp.PlayItem(Index: Integer);
begin
if (Index < 0) or (Index > FTMSPlayList.Count-1) then
Exit;


if FSongs[Index].Playing then
StopItem(Index);

if FSongs[Index].Module <> nil then
begin
FSongs[Index].Playing := FMUSIC_PlaySong(FSongs[Index].Module);
if not FSongs[Index].Playing then
MessageBox(g_d3dApp.m_hWnd, FMOD_ErrorString(FSOUND_GetError),
'Play song', MB_OK or MB_ICONHAND);
end
else if FSongs[Index].Stream <> nil then
begin
FSongs[Index].Channel := FSOUND_Stream_Play(FSOUND_FREE,
FSongs[Index].Stream);
FSongs[Index].Playing := FSongs[Index].Channel >= 0;
if not FSongs[Index].Playing then
begin
MessageBox(g_d3dApp.m_hWnd, FMOD_ErrorString(FSOUND_GetError),
'Play stream', MB_OK or MB_ICONHAND);
end
else
begin
FSOUND_SetPan(FSongs[Index].Channel, FSOUND_STEREOPAN);
FSOUND_SetVolume(FSongs[Index].Channel, 255);
end;
end;
end;

procedure TD3DGameApp.StopItem(Index: Integer);
begin
if (Index < 0) or (Index > FTMSPlayList.Count-1) then
Exit;

if FSongs[Index].Module <> nil then
FMUSIC_StopSong(FSongs[Index].Module)
else if FSongs[Index].Stream <> nil then
FSOUND_Stream_Stop(FSongs[Index].Stream);
FSongs[Index].Channel := -1;
FSongs[Index].Playing := False;
end;

 

Для того, чтобы не выгружать весь плей-лист ради одной лишь песни реализуем методы удаления и добавления отдельных композиций списка.

Сначала реализуем удаление -

 
procedure TD3DGameApp.DeleteSong(Index: Integer);
var
Index2: Integer;
begin
if (Index < 0) or (Index > FTMSPlayList.Count-1) then
Exit;

StopItem(Index);
FTMSPlayList.Delete(Index);
// Move all following items up one position
if FTMSPlayList.Count > 0 then
begin
if Index < FTMSPlayList.Count - 1 then
begin
for Index2 := Index to FTMSPlayList.Count - 2 do
FSongs[Index2] := FSongs[Index2 + 1];
end;
end;
end;

 

Теперь добавление -

function TD3DGameApp.AddSong(Filename: string): Integer;
var
Module: PFMusicModule;
Stream: PFSoundStream;
SongCount: Integer;
begin
SongCount := FTMSPlayList.Count;

if SongCount = MAX_SONGS then
begin
MessageBox(g_d3dApp.m_hWnd, PChar(Format('Limit of %d songs reached',
[MAX_SONGS])), 'Load error', MB_OK or MB_ICONHAND);
result := -1;
Exit;
end;


Stream := nil;
Module := FMUSIC_LoadSong(PChar(Filename));
if Module = nil then
begin
Stream := FSOUND_Stream_Open(PChar(Filename),
FSOUND_NORMAL or FSOUND_LOOP_NORMAL, 0, 0);
end;

if (Module = nil) and (Stream = nil) then
begin
MessageBox(g_d3dApp.m_hWnd, FMOD_ErrorString(FSOUND_GetError),
'Load error', MB_OK or MB_ICONHAND);
result := -1;
Exit;
end;

if Module <> nil then
begin
FMUSIC_SetMasterVolume(Module, 255);
if (FMUSIC_GetType(Module) = FMUSIC_TYPE_MOD)
or (FMUSIC_GetType(Module) = FMUSIC_TYPE_S3M) then
FMUSIC_SetPanSeperation(Module, 0.15); // 15% crossover
end;

result := FTMSPlayList.Add(Filename);

FSongs[result].Module := Module;
FSongs[result].Stream := Stream;
FSongs[result].Playing := False;

end;

 

Регулируем громкость - значения громкости 0 - тишина, 255 - максимум

procedure TD3DGameApp.Volume(SongIndex: Integer; Value: Byte);
begin
if (SongIndex < 0) or (SongIndex > FTMSPlayList.Count-1) then
Exit;

if FSongs[SongIndex].Module <> nil then
FMUSIC_SetMasterVolume(FSongs[SongIndex].Module, Value)
else if FSongs[SongIndex].Stream <> nil then
FSOUND_SetVolume(FSongs[SongIndex].Channel, Value);

end;

 

Регулировка позиции воспроизведения модуля по паттернам - переход к следующему/предыдущему паттерну -

function TD3DGameApp.Go2NextPattern(SongIndex: Integer): Integer;
begin
result := -1;

if (SongIndex < 0) or (SongIndex > FTMSPlayList.Count-1) then
Exit;

if FSongs[SongIndex].Module = nil then
Exit;
result := FMUSIC_GetOrder(FSongs[SongIndex].Module);
if result < FMUSIC_GetNumOrders(FSongs[SongIndex].Module) then begin
result := result + 1;
FMUSIC_SetOrder(FSongs[SongIndex].Module, result);
end;
end;

function TD3DGameApp.Go2PrevPattern(SongIndex: Integer): Integer;
begin
result := -1;

if (SongIndex < 0) or (SongIndex > FTMSPlayList.Count-1) then
Exit;

if FSongs[SongIndex].Module = nil then
Exit;
result := FMUSIC_GetOrder(FSongs[SongIndex].Module);
if result < FMUSIC_GetNumOrders(FSongs[SongIndex].Module) then begin
result := result - 1;
FMUSIC_SetOrder(FSongs[SongIndex].Module, result);
end;
end;

 

Для целей отладки будет полезно получать параметры производительности системы FMOD -

var
Index: Integer;
begin
SS_CPUUsage := Format('%.1f%%', [FSOUND_GetCPUUsage]);
SS_Channels := Format('%3.3d', [FSOUND_GetChannelsPlaying]);

if CurrentSongIndex > -1 then
begin
if FMUSIC_IsFinished(FSongs[CurrentSongIndex].Module) and PlaylistMode then
begin
StopItem(CurrentSongIndex);
Index := CurrentSongIndex;
Inc(Index);
if Index >= FTMSPlayList.Count then
Index := 0;
CurrentSongIndex := Index;
PlayItem(Index);
end
else if FMUSIC_IsFinished(FSongs[CurrentSongIndex].Module) and
not PlaylistMode then begin
PlayItem(CurrentSongIndex);
end;
end;

данный метод должен вызываться периодически (аналогично FrameMove). Здесь также проверяется режим плей-листа. Если он установлен, то будет проигрываться следующий файл списка, в противном случае будет бесконечно воспроизводиться композиция с индексом CurrentSongIndex.

 
Если Ваш игровой проект будет поддерживать в опции настроек установку каких-либо аудио-параметров - выбор драйвера, параметры фильтрации и т.п., то можете реализовать их установку по аналогии с тем, как это выполнено в рассмотренном нами выше примере.
 

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

Сделать чтобы несколько файлов играли одновременно и бесконечно - это Вы, я думаю сможете самостоятельно, но на первых порах это вряд ли Вам понадобится.

 
     
  [Назад] [Все уроки] [Далее]  
     
подробнее

Начало работы с fle game engine. Создание стартового шаблона приложения - будущей игры на c++ directx 9



Итак, Вы решили создать собственную игру и выбрали для этого движок с полностью открытым
кодом - fle game engine

fle game engine Редактор сцен

В отличие от популярных движков таких как unity 3d или unreal engine, данный движок
позволит Вам создать игру на c++ под directx 9, не накладывая никаких ограничений
на функциональные возможности. Они будут ограничиваться только вашими способностями
к их созданию и использованию.

То есть вы неограниченно сможете расширять как свой проект, так и возможности самого
движка.

Весь исходный код полностью открыт и доступен для использования, в отличие от
вышеупомянутых, в которых открытость заключается лишь в использовании среды разработки и интерфейсов.

Расширить движок созданный под unity 3d или unreal engine Вы сможете только
сделав крупные капиталовложения, но и в этом случае никто вам не даст
доступ к открытому коду самого движка.

Почему мне ближе fle game engine ?

Я его создавал с нуля и развивал на протяжении ряда лет, но создание
движка не является для меня самоцелью (в отличие от тех же unity 3d или unreal engine), потому что судя по этим движкам складывается мнение как раз обратное -

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

С fle game engine у вас нет такой зависимости. Потому что Вы
получаете весь его исходный код и примеры целиком и полностью без
каких-либо на то ограничений.

Скачать fle game engine (полный исходный код).


Включает исходный код, полезные материалы и инструменты. Вы можете поддержать проект оформив платную подписку.
Размер: 482 Mb Подробнее Что включает дистрибутив ? - Редактор сцен Scene Editor; - пример игры simple game с полным исходным кодом; - пошаговое описание создания примера игры simple_game - представляет набор html файлов пригодных для открытия и чтения из любого браузера; - Coords 2D - утилиту отладки анимаций и подбора экранных координат содержит богатую библиотеку готовых примеров игровых спрайтов; - полный исходный код fle game engine - позволит вам создать свою собственную игру, а также расширить движок необходимыми возможностями в дальнейшем, никаких ограничений на расширение нет; - fgg_setup.exe Fly snow 3d - визуальные эффекты падающего снега/дождя и др. красивые эффекты с частицами в 2d/3d;
fle game engine изначально развивается не с целью создать коммерческий
движок для продаж. Он воплощен, чтобы разрабатывать собственные игровые проекты,
а значит его главная цель - это создание конкретной игры, а не развитие
движка. Поэтому движок развивается в контексте конкретных игровых
проектов, а не в контексте любых игровых проектов в расчете на универсальность.

Универсальность оборачивается функциональными излишествами и громоздкостью.
В случае же fle game engine Вы можете убрать весь ненужный вам
функционал, и дописать тот, который действительно нужен.

Единственным ограничением является то, что Вы должны упоминать
на каком движке Вы сделали игру и естественно не пытаться выдать
мои наработки за свои. Думаю это вполне разумное условие на
бесплатное и открытое использование.

По моему личному убеждению движок должен учитывать особенности
создаваемой игры, а значит никаких ограничений на его расширение
быть не должно изначально !

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

Конечно Вы можете разочароваться и в движке с открытым исходным кодом,
если у вас не хватит терпения и старания на то, чтобы дополнить
его недостающими возможностями, но в случае с коммерческими движками
такую возможность Вы даже не сможете получить (если только ваш проект
не станет коммерчески успешным, но поскольку вы еще не сделали
свою игру, то вероятность этого равна 0 - ведь сначала надо сделать
игру).

Сложно спорить о том, какой движок лучше. Любой движок имеет какие-то
плюсы, но в то же время и минусы.

Используя unity 3d или unreal engine или какой-то еще движок,
в котором ядро движка представляет закрытый от изменений код, Вы рискуете
тем, что нарветесь именно на такую необходимость - дописать функционал,
который изначально дописать или исправить нельзя. Потому что он уже жестко
закодирован и вам недоступен.

Движок с открытым исходным кодом - позволяет это исправить. И это является
несомненным плюсом.

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

Знания и навыки, а особенно необходимые именно Вам прямо здесь и сейчас -
очень трудно купить и они не даются Вам по щелчку пальцев.

Однако в отличие от платных движков или условно-бесплатных, но с частично закрытым
кодом, в любом случае Вам нужны будут знания, и fle game engine несомненно
имеет огромный плюс в том, что он бесплатно предоставляет вам неограниченные
возможности для изучения и экспериментов. Чего на данный момент не может
дать ни один из упомянутых движков.

Как те кто уже много работал с такими движками, как unity 3d или unreal engine,
так и те кто только начинает - единодушно склоняются к мнению: движок не должен
иметь ограничений. В противном случае невозможно сделать именно такую
игру, которую Вы хотите.

Поэтому напоследок добавлю - скорее всего Вам нужно попробовать все варианты
и в конечном итоге Вы придете к тому, что нужно писать свой собственный движок.

Однако в случае с unity 3d или unreal engine Вам это вряд ли
по силам. Только представьте сколько нужно времени, средств и человеко-ресурсов.
Нужно ли это Вам ?

То есть наиболее правильным и умным решением было бы попробовать создать игру, скажем
на unity 3d, а затем осознав все недостатки и достоинства, попробовать
сделать то же самое, но уже на движке с полностью открытым исходным кодом.

Несомненно, что и там и там, Вас ждут определенные трудности, но в то же время,
Вы обязательно получите и необходимый Вам опыт. И это тоже будет огромным плюсом.

Ну что ж, давайте продолжим.

Итак, Вы скачали и распаковали архив с fle game engine, у Вас уже есть установленные
Microsoft Visual Studio 2005 и DirectX SDK Aug 2008.

Хочу сразу предупредить, что в случае использования других версий MSVS и DX SDK вам
потребуется внести в код изменения. Поэтому если начальный уровень этих знаний у вас
близок к нулю, лучше использовать именно указанные версии MSVS и DX SDK.

Откроем папку движка и попробуем разобраться с тем, как нам создать свой первый
шаблон приложения.

Первым делом прочитаем файл readme.txt и увидим, что в папке есть уже готовый пример
игры simple game, а на сайте есть серия уроков подробно описывающая процесс её создания
пошагово.

fge\samples\simple_game\

Вам обязательно нужно будет ознакомиться с этими уроками и попрактиковаться.

Ну а сейчас, нас интересует то, как на основании имеющегося в нашем распоряжении
кода начать старт нового игрового проекта, который будет существенно отличаться
от игры simple game.

Для начала нужно попробовать собрать проект simple game из папки
fge\samples\simple_game\

Чтобы убедиться, что все необходимое у вас корректно установлено и настроено.

О том, как настроить проект simple_game написано в приложенном файле
fge\samples\simple_game\readme.txt

Все что вам нужно это открыть проект
fge\samples\simple_game\start.sln

из Microsoft Visual Studio 2005

и выполнить в нем ряд настроек:


1) Указать расположение подключаемых файлов DX SDK Aug 2008 из папки Include -

свойства проекта

Допустим, что 

c:\DXSDK9_Aug2008\

это папка в которой установлен DirectX SDK Aug 2008. Тогда

свойства проекта Additional Include Directories

в поле Additional Include Directories

вместо ..\..\..\..\..\..\..\Include

вам нужно прописать корректный путь к папке Include, входящей в состав DirectX SDK August 2008.

В моем примере получился такой путь: 
..\..\..\..\..\DXSDK9_Aug2008\Include

fge у меня установлен в папке

c:\fge\

2) Configuration properties > Linker > General 

и в поле

Additional Library Directories

измените значение

свойства проекта Additional Library Directories

..\..\..\..\..\..\..\Lib\x86

изменить на (но это только в моем примере! у вас этот путь может быть другим)

..\..\..\..\..\DXSDK9_Aug2008\Lib\x86


Данное действие нужно повторить для debug сборки проекта (если Вы настраивали release) и
наоборот (см. на рисунке выше - слева вверху поле Configuration: Active(Release) )



Более подробно о том, как настроить проект, а также где скачать DX SDK Aug 2008 описано
в статье -
Создание игры на fle game engine - Simple game - страница 6 - Загрузка игровой сцены / Пример простой игры

Пробуем выполнить сборку проекта simple_game для release и для debug конфигураций проекта.
И если в обоих случаях не вылезло никаких ошибок и нормально создался исполняемый файл start.exe
внутри папки

fge\samples\simple_game\simple_game\

Значит первый шаг почти сделан !

Если собранный fge\samples\simple_game\simple_game\start.exe

simple game exe пример простой игры

simple game exe пример простой игры

simple game exe пример простой игры

Нормально запускается и приложение работает. Значит ура ! Двигаемся дальше.

Собственно теперь у вас в руках уже есть шаблон вашей будущей игры -
на базе примера simple game.

В режиме отладки (сборка в конфигурации debug) позволит вам пошагово исследовать код,
а из уроков simple game Вы можете
подробнее узнать о том, что и как работает.

Все что требуется сделать, это создать свою папку и скопировать туда все содержимое
папки

fge\samples\simple_game\

И таким образом можно уже приступать к модификациям кода и ресурсов, чтобы создать
ваш собственный игровой проект.

Например так - fge\samples\my_first_game\

подробнее

Веселый Буквоежка - онлайн комикс - страница 2

представляем Веселый Буквоежка - онлайн комикс.

Я понимал, что надо идти. Я снял с плеча моток веревки и передал его Лукьянычу. Сам взялся за конец. - Будете страховать, - сказал я. Лукьяныч кивнул. Он был напуган. Я нагнулся и пошел в трубу. Я присел на корточки и попытался разорвать пленку. Пленка с треском лопнула, и я увидел - совсем близко, на расстоянии метра - запрокинутую голову Жоры, которая медленно вползала в черную глянцевую трясину. Почему-то я совсем не испугался, наверное был готов к подобному. Я бросил конец веревки Жоре, а сам упал на скользкий пол трубы и крикнул Лукьянычу, чтобы держал крепче. Когда мы с Лукьянычем стали тянуть, трясина с хлюпаньем и всхлипом отпустила Жору, и через минуту отчаянного напряжения он оказался рядом со мной. От него несло отвратительной вонью. - Живой, прохрипел он, - живой... - Ты знал ? - спросил я. - Ты знал и пошел ? - Оно редко открывается. А с четырех закрыто. - Весь в дерьме, - укоризненно произнес Лукьяныч.

Веселый Буквоежка - онлайн комикс - страница 2

если кликать картинку она будет последовательно меняться в размерах от 620 до 2048 пиксель.

[страница 1]  [страница 2]  [страница 3]  [страница 4]  [страница 5]  [страница 6]  [страница 7]  [страница 8]  [страница 9]  [страница 10]  [страница 11]  [страница 12]  [страница 13]  [страница 14]  [страница 15]  [страница 16]  [страница 17]  [страница 18]  [страница 19]  [страница 20]  [страница 21]  [страница 22]  [страница 23] 

Веселый Буквоежка - онлайн комикс - страница 1

представляем Веселый Буквоежка - онлайн комикс.

Жора, Щукин и Лукьяныч отправляются в глубь свалки, именуемую Зоной, на поиски Гали. Щукин размышляет. В пять тридцать мы вышли. Скоро сумерки. А ночь в Зоне еще никто не проводил. А если провел, уже не расскажет. Я шел в середине. Первым Жора Васюнин, легкий, худой, злой. Замыкал Лукьяныч. Лукьяныч робел, поминутно оглядывался. Директор соблазнил его большой премией. Впрочем на что Лукьянычу премия ? Удивительно несоизмеримы наши дела и их последствия ! Любопытно, а что если бы и я потребовал премию ? Я внутренне усмехнулся. Я понимал, что мы должны найти девочку до темноты. Директор взял с нас слово, что до темноты мы вернемся.

Веселый Буквоежка - онлайн комикс - страница 1

если кликать картинку она будет последовательно меняться в размерах от 620 до 2048 пиксель.

[страница 1]  [страница 2]  [страница 3]  [страница 4]  [страница 5]  [страница 6]  [страница 7]  [страница 8]  [страница 9]  [страница 10]  [страница 11]  [страница 12]  [страница 13]  [страница 14]  [страница 15]  [страница 16]  [страница 17]  [страница 18]  [страница 19]  [страница 20]  [страница 21]  [страница 22]  [страница 23] 

megainformatic live chat
Начать беседу
X
 

Оставленные комментарии



fle game engine - движок для создания игр
fle game engine - движок для создания игр


Something: Unexplained 2 captive of desires / Нечто: Необъяснимое 2 в плену желаний
Костя Коробкин Комикс Коллекционное издание - 6 комиксов, 81 страница, 220 mp3 треков
megainformatic Размещение баннерной рекламы у нас
Время загрузки: 1,1763