Author Topic: Как создать Шутер от 1-го лица (серия уроков)  (Read 4289 times)

0 Members and 1 Guest are viewing this topic.

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 910
  • Reputation 36
  • Game making is my hobby for life!
Как создать Шутер от 1-го лица (серия уроков)
Ну что ж, уважаемые WS3D-юзеры и все, интресующиеся движком и созданием игр, особенно шутеров, да да, я решил написать серию уроков по созданию шутера от 1-го лица (англ. First Person Shooter, FPS) на WS3D!

Особенно теперь, с выходом WS3D 0.9.5, стало для этого больше возможностей, т.к. появились декали.
Итак, вот план на несколько уроков вперёд:

0. Подготавливаем проект с помощью Мастера создания проектов. (готово)
1. Создаём уровень (карту) и добавляем камеру.                                (готово)
2. Прикрепляем оружие к камере                                                        (готово)
3. Делаем анимацию отдачи от оружия                                              (готово)
4. Улучшенное управление Главным героем (камерой): любыми клавишами + прыжок (готово)
5. Анимация шагов                                                                               (готово)
6. Добавим озвучивание: фоновая музыка, звуки выстрела, шагов и др.
7. Делаем количество боеприпасов (ammo) и индикатор на экране
8. Расставляем врагов и делаем им простой ИИ
9. Делаем здоровье и его индикатор
10. Внедряем декали (следы от пуль)

11... там видно будет


Уроки будут небольшими и рассчитанными на начинающего, который уже немного познакомился с движком.
Вы можете спокойно что-то обсуждать в этой теме и задавать вопросы по теме.
« Last Edit: October 16, 2015, 07:27:52 PM by Alec - WS3D Developer »
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 910
  • Reputation 36
  • Game making is my hobby for life!
Итак, начнём. Но не с 1-го, а с 0-го урока, так как нужно ещё подготовить проект, так сказать "заложить фундамент".

0-й урок готов. (Я не буду материал уроков на форум добавлять напрямую), вместо этого, я буду сюда выкладывать готовые уроки в pdf формате.

Урок 0: скачать
« Last Edit: October 10, 2015, 06:14:35 PM by Alec - WS3D Developer »
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 910
  • Reputation 36
  • Game making is my hobby for life!
Дописываю урок 1...  ;)
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 910
  • Reputation 36
  • Game making is my hobby for life!
Урок 1 готов. Скачать pdf

Код для ленивых (шутка)
Code: [Select]
'' ----------------------------------------------------------------------------
'' Название проекта (игры): MyFPS
'' Автор(ы) проекта:
'' Дата начала создания проекта:
'' Дата окончания проекта:
'' ----------------------------------------------------------------------------
'' Краткое описание.
''
''
'' ----------------------------------------------------------------------------
'' Для удобства уберём подключение заголовков, а также разные пользовательские
'' (т.е. созданные вами) функции в отдельный модуль, который мы подключаем здесь,
'' в самом начале проекта.
#include "MyFunctions.bi"
'' Для удобства и порядка в коде можно убрать переменные, первоначальные настройки
'' и меню в отдельные модули и затем здесь подключить их.
'' ------------------------------------------------------------------------------
'' ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
'' Для порядка в коде лучше разделить объявление переменных по типам, тогда сразу
'' будет видно, где какая переменная.

'' [1.] Для работы со звуками
Dim Sounds_Init As FBSBOOLEAN
Dim as Integer hWave,hSound 'для работы со звуком
Dim PlayTime As Integer = 0     'для начала времени проигрывания звука

'' [2.] Объекты WorldSim3D (Меши, Ноды, Текстуры, Камеры, Селекторы и т.д.)
DIM MapMesh as wMesh
DIM MapNode as wNode
Dim MazeTexture As wTexture
DIM Camera as wCamera
DIM CameraNode as wNode
DIM MapCollision as wSelector
DIM BitmapFont as wFont
DIM Collision_anim as wSelector
DIM KeyEvent as wKEY_EVENT PTR
DIM MouseEvent as wMOUSE_EVENT Ptr

'' [3.] Другие переменные, не связанные напрямую с объектами и звуком. Это могут быть
'' разные флаги, счётчики, математика, а также для отладочных целей.
DIM XPOS as single
DIM YPOS as single
DIM ZPOS as single
DIM metrics as wstring * 256
Dim vX as wVECTOR
DIM vY as wVECTOR
DIM vZ as wVECTOR
DIM i As Integer
Dim flag As Integer

'' [4.] Для работы с текстом, если в проекте много разных сообщений, выводимых на экран, например,
'' тексты для меню, диалогов между персонажами, GUI и т.д.
Dim gameover_mes As String

'' [5.] Для сохранения состояния игры, первоначальных настроек игры, таблицы результатов (рекордов)
'' и т.д.

'' [6.] Другие переменные, не вошедшие в предыдущие разделы.

'' Естественно, в зависимосчти от типа вашего проекта, какие-то разделы переменных вам не понадобятся,
'' а какие-то, наоборот, вы захотите добавить.
'' =============================================================================================
'' Запускаем интерфейс WorldSim3D
wStart( wDT_OPENGL, 800, 600, wBITS_PER_PIXEL_32,_
          wWINDOWED, wSHADOWS, wCAPTURE_EVENTS, wVERTICAL_SYNC_ON )

'' ++++++++++++++++++  ПЕРВОНАЧАЛЬНЫЕ НАСТРОЙКИ ПРОЕКТА  ++++++++++++++++++++++++++++++++++
'' Сюда включается всё, что должно быть выполнено только один раз или инициализировано для
'' последующей работы только один раз. Эта часть кода расположена до главного цикла,
'' который начинается с While wRunning. Также здесь расположены функции, инициализирующие
'' работу объектов WorldSim3D, которые будут продолжать работать и в главном цикле:
'' камеры, аниматоры и другие.
'' Также в этом разделе можно сделать работу меню, ведь обычно послезапуска игры сначала
'' появляется меню, из которого можно уже начать игру.

'' ------------------  ИНИЦИАЛИЗАЦИЯ РАБОТЫ ЗВУКОВ  ---------------------------------------
'' Показана на примере одного звука. Возможно вам не нужно озвучивание или вы предпочитаете
'' пользоваться другой звуковой библиотекой. Тогда просто уберите эту часть кода.
'' Расскомметируйте здесь, если вам нужно озвучивание и ниже.
Sounds_Init = fbs_Init(48000) ' инициализируем работу библиотеки FBSound
if Sounds_Init = false then
  ? "error: fbs_Init() !"
  ? FBS_Get_PlugError()
  beep:sleep:end 1
end if

' загружаем файл звука
Sounds_Init = fbs_Load_OGGFile ("media/Dark_Ambience.ogg",@hWave)
if Sounds_Init = false then
  ? "error: fbs_Load_OGGFile() !"
  beep:sleep:end 1
end If
' создаём звук для работы со всеми возможностями библиотеки FBSound
fbs_Create_Sound (hWave,@hSound)
'/
'' ---------------------------------------------------------------------------------------
' Устанавливаем текст заголовка окна приложения
wSetWindowCaption( "My Project" )
' загружаем нужный шрифт из папки ресурсов через функцию wGetFont
BitmapFont = wGetFont ( "media/3.png" )

'' ------- ЗАГРУЗКА ИГРОВЫХ ОБЪЕКТОВ НА СЦЕНУ ---------------------------------------------
'' Загрузку игровых объектов (3D моделей, частиц, скайбоксов и др.) на сцену.
'' [1.] Ноды для 3D моделей
wAddZipFile( "media/BSPmaps/ctfcomp02_hazard.pk3", wIGNORE_CASE, wIGNORE_PATHS )

' load the BSP map from the archive as a mesh object. any polygons in the mesh
' that do not have textures will be removed from the scene!
MapMesh = wGetMesh( "ctfcomp02_hazard.bsp" )

' add the map to the scene as a node. when adding the mesh this call uses a
' mechanism called an octtree that if very efficient at rendering large amounts
' of complex geometry most of which cant be seen, using this call for maps
' will greatly improve your framerates
MapNode = wAddMeshToSceneAsOcttree (MapMesh)
'' [2.] Аниматоры Нодов, например, wAddFlyCircleAnimator, wAddRotationAnimator и др.

'' [3.] Камеры, Ноды для них и первоначальные настройки камер
Camera = wAddFPSCamera
CameraNode = Camera
wSetNodePosition( CameraNode, 386, 366, 2726 )
wSetNodeRotation( CameraNode, 0, 0, 0 )
wSetCameraClipDistance ( CameraNode, 12000 )

'' [4.] Частицы (огонь, взрыв, снег и т.д. )

'' ------------------ УСТАНОВКА ФИЗИКИ: ПРОВЕРКИ СТОЛКНОВЕНИЙ И ДР. -------------------
'' Это может быть как базовая физика, встроенная в WorldSim3D так и сторонних библиотек,
'' например, ODE, Newton и других.
MapCollision = wGetCollisionGroupFromComplexMesh (MapMesh, MapNode)

wAddCollisionAnimator(_
                        MapCollision,_
                        CameraNode,_
                        30.0,30.0,30.0,_
                        0.0,-9.8,0.0,_
                        0.0,50.0,0.0 )
'' ------------------------------------------------------------------------------------
'' ------------------ ОСВЕЩЕНИЕ -------------------------------------------------------
' добавим в проект яркий свет, освещающий всё вокруг
wSetAmbientLight ( 1, 1, 1 )

'' ------------------ ДРУГИЕ НАСТРОЙКИ или КОД ------------------------------------------------
' Скрываем указатель мыши, если он не нужен
wHideMouse

' -----------------------------------------------------------------------------
'******************************************************************************
'----------------------- ГЛАВНЫЙ ЦИКЛ ВАШЕГО ПРОЕКТА --------------------------
' здесь главный цикл приложения, поэтому
' мы устанавливаем цикл с условием: пока движок работает (функция wRunning)
' внутри цикла постоянно выполняются определённые команды, в основном для отображения сцены
While wRunning
        ' начинаем отрисовку сцены с цветом фона, например зелёный (который устанавливаем числами 0,55,0)
        wBeginScene( 0, 55, 0 )
       
      ' задаём момент времени, когда начать проигрывать звук
      If PlayTime = 1 Then ' начинаем проигрывать на 1-й миллисекунде работы цикла
           ''fbs_Play_Sound (hSound,10) ' Воспроизводим загруженный и созданный звук
           ' 10 означает сколько раз проиграть звук
      EndIf
      PlayTime +=1 'запускаем работу счётчика кадров цикла
     
      '' ------------------------ СОБЫТИЯ КЛАВИАТУРЫ ----------------------------
        ' если события клавиатуры могут быть обработаны, то:
        while wKeyEventAvailable
            ' читаем события клавиатуры.
            KeyEvent = wReadKeyEvent
   
            ' если нажата какая-либо клавиша, связываем с ней событие, оторое мы хотим
            ' чтобы оно произошло. Это может быть что угодно:
            select case as const KeyEvent->key
                case KEY_KEY_D     ' клавиша D
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                End If
   
                case KEY_KEY_W     ' клавиша W
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                End If
                   
                case KEY_KEY_A     ' клавиша A
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                End If
                   
                case KEY_KEY_S     ' клавиша S
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                End If
            ' Добавим функцию для закрытия окна через клавишу ESCAPE.
                ' Если клавиатура не исчпользуется, то для этой цели нужно использовать
                ' другую функцию - wCloseESC(), которую можно поместить в конце главного цикла.
                wCloseKEY_ESC()
            end Select
        Wend
       
        '' --------------------------- СОБЫТИЯ МЫШИ -----------------------------------------
        '
        While wMouseEventAvailable
            MouseEvent = wReadMouseEvent
   
            if MouseEvent->action = wME_MOUSE_MOVED then
   
            End If
   
        Wend
      '' ----------------------------------------------------------------------------------   
      '' Завершение отрисовки 3D сцены
        wDrawScene
  '' ------------------------- ОТОБРАЖЕНИЕ ТЕКСТА НА ЭКРАНЕ ---------------------------------
  '' отображаем на экране загруженный ранее шрифт. Это нужно сделать после функции wDrawScene,
  '' т.е. после отрисовки 3D сцены, чтобы выводимый на экран текст отображался поверх объектов
  '' сцены, иначе объекты сцены будут закрывать текст.
  '' последние 4 числа - координаты текста: X,Y левого верхнего угла и X,Y правого нижнего угла
          w2DFontDraw ( BitmapFont, "Press W,A,S,D to move around the map", 200, 570, 450, 590 )
   
        ' заканчиваем отрисовку всего, что на экране и отображаем это
        wEndScene
        wSetFPS   'устанавливаем фреймрейт по умолчанию 60 кадров в секунду
Wend
' -----------------------КОНЕЦ ГЛАВНОГО ЦИКЛА ВАШЕГО ПРОЕКТА ----------------------------------
'**********************************************************************************************

' ---------------------------------------------------------------------------------------------
' Останавливаем работу движка и высвобождаем ресурсы памяти
wStop
« Last Edit: October 11, 2015, 11:21:19 AM by Alec - WS3D Developer »
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 910
  • Reputation 36
  • Game making is my hobby for life!
Пишу 2-й урок. Написал как прицепить оружие к камере (кстати на форуме есть пример, но не так подробно объясняется как в уроке). Когда начал писать об отдаче от оружия, подумал, что инфы сильно много получилось для начинающих. Решил перенести этой в 3-й урок. А 2-й скоро выложу.
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 910
  • Reputation 36
  • Game making is my hobby for life!
Урок 2 готов. Скачать pdf

Обновлённый код:
Code: [Select]
'' ----------------------------------------------------------------------------
'' Название проекта (игры): MyFPS
'' Автор(ы) проекта:
'' Дата начала создания проекта:
'' Дата окончания проекта:
'' ----------------------------------------------------------------------------
'' Краткое описание.
''
''
'' ----------------------------------------------------------------------------
'' Для удобства уберём подключение заголовков, а также разные пользовательские
'' (т.е. созданные вами) функции в отдельный модуль, который мы подключаем здесь,
'' в самом начале проекта.
#include "MyFunctions.bi"
'' Для удобства и порядка в коде можно убрать переменные, первоначальные настройки
'' и меню в отдельные модули и затем здесь подключить их.
'' ------------------------------------------------------------------------------
'' ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
'' Для порядка в коде лучше разделить объявление переменных по типам, тогда сразу
'' будет видно, где какая переменная.

'' [1.] Для работы со звуками
Dim Sounds_Init As FBSBOOLEAN
Dim as Integer hWave,hSound 'для работы со звуком
Dim PlayTime As Integer = 0     'для начала времени проигрывания звука

'' [2.] Объекты WorldSim3D (Меши, Ноды, Текстуры, Камеры, Селекторы и т.д.)
DIM MapMesh as wMesh
DIM MapNode as wNode
Dim MazeTexture As wTexture
DIM Camera as wCamera
DIM CameraNode as wNode
DIM MapCollision as wSelector
DIM BitmapFont as wFont
DIM Collision_anim as wSelector
DIM KeyEvent as wKEY_EVENT PTR
DIM MouseEvent as wMOUSE_EVENT Ptr

Dim GunMesh As wMesh         'для меша оружия
DIM GunNode as wNode         'для нода оружия
Dim GunTexture As wTexture  'для текстуры оружия


'' [3.] Другие переменные, не связанные напрямую с объектами и звуком. Это могут быть
'' разные флаги, счётчики, математика, а также для отладочных целей.
DIM XPOS as single
DIM YPOS as single
DIM ZPOS as single
DIM metrics as wstring * 256
Dim vX as wVECTOR
DIM vY as wVECTOR
DIM vZ as wVECTOR
DIM i As Integer
Dim flag As Integer

'' [4.] Для работы с текстом, если в проекте много разных сообщений, выводимых на экран, например,
'' тексты для меню, диалогов между персонажами, GUI и т.д.
Dim gameover_mes As String

'' [5.] Для сохранения состояния игры, первоначальных настроек игры, таблицы результатов (рекордов)
'' и т.д.

'' [6.] Другие переменные, не вошедшие в предыдущие разделы.

'' Естественно, в зависимосчти от типа вашего проекта, какие-то разделы переменных вам не понадобятся,
'' а какие-то, наоборот, вы захотите добавить.
'' =============================================================================================
'' Запускаем интерфейс WorldSim3D
wStart( wDT_OPENGL, 800, 600, wBITS_PER_PIXEL_32,_
          wWINDOWED, wSHADOWS, wCAPTURE_EVENTS, wVERTICAL_SYNC_ON )

'' ++++++++++++++++++  ПЕРВОНАЧАЛЬНЫЕ НАСТРОЙКИ ПРОЕКТА  ++++++++++++++++++++++++++++++++++
'' Сюда включается всё, что должно быть выполнено только один раз или инициализировано для
'' последующей работы только один раз. Эта часть кода расположена до главного цикла,
'' который начинается с While wRunning. Также здесь расположены функции, инициализирующие
'' работу объектов WorldSim3D, которые будут продолжать работать и в главном цикле:
'' камеры, аниматоры и другие.
'' Также в этом разделе можно сделать работу меню, ведь обычно послезапуска игры сначала
'' появляется меню, из которого можно уже начать игру.

'' ------------------  ИНИЦИАЛИЗАЦИЯ РАБОТЫ ЗВУКОВ  ---------------------------------------
'' Показана на примере одного звука. Возможно вам не нужно озвучивание или вы предпочитаете
'' пользоваться другой звуковой библиотекой. Тогда просто уберите эту часть кода.
'' Расскомметируйте здесь, если вам нужно озвучивание и ниже.
Sounds_Init = fbs_Init(48000) ' инициализируем работу библиотеки FBSound
if Sounds_Init = false then
  ? "error: fbs_Init() !"
  ? FBS_Get_PlugError()
  beep:sleep:end 1
end if

' загружаем файл звука
Sounds_Init = fbs_Load_OGGFile ("media/Dark_Ambience.ogg",@hWave)
if Sounds_Init = false then
  ? "error: fbs_Load_OGGFile() !"
  beep:sleep:end 1
end If
' создаём звук для работы со всеми возможностями библиотеки FBSound
fbs_Create_Sound (hWave,@hSound)
'/
'' ---------------------------------------------------------------------------------------
' Устанавливаем текст заголовка окна приложения
wSetWindowCaption( "My FPS game" )
' загружаем нужный шрифт из папки ресурсов через функцию wGetFont
BitmapFont = wGetFont ( "media/3.png" )

'' ------- ЗАГРУЗКА ИГРОВЫХ ОБЪЕКТОВ НА СЦЕНУ ---------------------------------------------
'' Загрузку игровых объектов (3D моделей, частиц, скайбоксов и др.) на сцену.
'' [1.] Ноды для 3D моделей
wAddZipFile( "media/BSPmaps/ctfcomp02_hazard.pk3", wIGNORE_CASE, wIGNORE_PATHS )

' load the BSP map from the archive as a mesh object. any polygons in the mesh
' that do not have textures will be removed from the scene!
MapMesh = wGetMesh( "ctfcomp02_hazard.bsp" )

' add the map to the scene as a node. when adding the mesh this call uses a
' mechanism called an octtree that if very efficient at rendering large amounts
' of complext geometry most of which cant be seen, using this call for maps
' will greatly improve your framerates
MapNode = wAddMeshToSceneAsOcttree (MapMesh)

' Загружаем в проект модель оружия
GunMesh = wGetMesh( "media/models/pistol.3ds")

' Загружаем текстуру для модели оружия
GunTexture = wGetTexture ("media/models/pistol.jpg")

' Добавляем на сцену нод только что загруженного оружия
GunNode = wAddMeshToScene(GunMesh)

' применяем текстуру оружия к ноду оружия
wSetNodeMaterialTexture (GunNode, GunTexture, 0)

' пока отключим освещение оружия, а то по умолчанию оно будет неосвещённым (чёрным)
wSetNodeMaterialFlag (GunNode, wMF_LIGHTING, wOFF)

wSetNodePosition (GunNode, 7, -3, 12)
'' [2.] Аниматоры Нодов, например, wAddFlyCircleAnimator, wAddRotationAnimator и др.

'' [3.] Камеры, Ноды для них и первоначальные настройки камер
Camera = wAddFPSCamera
CameraNode = Camera
wSetNodePosition( CameraNode, 386, 366, 2726 )
wSetNodeRotation( CameraNode, 0, 0, 0 )
wSetCameraClipDistance ( CameraNode, 12000 )

'' [4.] Частицы (огонь, взрыв, снег и т.д. )

wAddChildToParent (GunNode, CameraNode)
'' ------------------ УСТАНОВКА ФИЗИКИ: ПРОВЕРКИ СТОЛКНОВЕНИЙ И ДР. -------------------
'' Это может быть как базовая физика, встроенная в WorldSim3D так и сторонних библиотек,
'' например, ODE, Newton и других.
MapCollision = wGetCollisionGroupFromComplexMesh (MapMesh, MapNode)

wAddCollisionAnimator(_
                        MapCollision,_
                        CameraNode,_
                        30.0,30.0,30.0,_
                        0.0,-9.8,0.0,_
                        0.0,50.0,0.0 )
'' ------------------------------------------------------------------------------------
'' ------------------ ОСВЕЩЕНИЕ -------------------------------------------------------
' добавим в проект яркий свет, освещающий всё вокруг
wSetAmbientLight ( 1, 1, 1 )

'' ------------------ ДРУГИЕ НАСТРОЙКИ или КОД ------------------------------------------------
' Скрываем указатель мыши, если он не нужен
wHideMouse

' -----------------------------------------------------------------------------
'******************************************************************************
'----------------------- ГЛАВНЫЙ ЦИКЛ ВАШЕГО ПРОЕКТА --------------------------
' здесь главный цикл приложения, поэтому
' мы устанавливаем цикл с условием: пока движок работает (функция wRunning)
' внутри цикла постоянно выполняются определённые команды, в основном для отображения сцены
While wRunning
        ' начинаем отрисовку сцены с цветом фона, например зелёный (который устанавливаем числами 0,55,0)
        wBeginScene( 0, 55, 0 )
       
      ' задаём момент времени, когда начать проигрывать звук
      If PlayTime = 1 Then ' начинаем проигрывать на 1-й миллисекунде работы цикла
           ''fbs_Play_Sound (hSound,10) ' Воспроизводим загруженный и созданный звук
           ' 10 означает сколько раз проиграть звук
      EndIf
      PlayTime +=1 'запускаем работу счётчика кадров цикла
     
      '' ------------------------ СОБЫТИЯ КЛАВИАТУРЫ ----------------------------
        ' если события клавиатуры могут быть обработаны, то:
        while wKeyEventAvailable
            ' читаем события клавиатуры.
            KeyEvent = wReadKeyEvent
   
            ' если нажата какая-либо клавиша, связываем с ней событие, оторое мы хотим
            ' чтобы оно произошло. Это может быть что угодно:
            select case as const KeyEvent->key
                case KEY_KEY_D     ' клавиша D
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                End If
   
                case KEY_KEY_W     ' клавиша W
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                End If
                   
                case KEY_KEY_A     ' клавиша A
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                End If
                   
                case KEY_KEY_S     ' клавиша S
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                End If
            ' Добавим функцию для закрытия окна через клавишу ESCAPE.
                ' Если клавиатура не исчпользуется, то для этой цели нужно использовать
                ' другую функцию - wCloseESC(), которую можно поместить в конце главного цикла.
                wCloseKEY_ESC()
            end Select
        Wend
       
        '' --------------------------- СОБЫТИЯ МЫШИ -----------------------------------------
        '
        While wMouseEventAvailable
            MouseEvent = wReadMouseEvent
   
            if MouseEvent->action = wME_MOUSE_MOVED then
   
            End If
   
        Wend
      '' ----------------------------------------------------------------------------------   
      '' Завершение отрисовки 3D сцены
        wDrawScene
  '' ------------------------- ОТОБРАЖЕНИЕ ТЕКСТА НА ЭКРАНЕ ---------------------------------
  '' отображаем на экране загруженный ранее шрифт. Это нужно сделать после функции wDrawScene,
  '' т.е. после отрисовки 3D сцены, чтобы выводимый на экран текст отображался поверх объектов
  '' сцены, иначе объекты сцены будут закрывать текст.
  '' последние 4 числа - координаты текста: X,Y левого верхнего угла и X,Y правого нижнего угла
          w2DFontDraw ( BitmapFont, "Press arrows to move around the map", 200, 570, 450, 590 )
   
        ' заканчиваем отрисовку всего, что на экране и отображаем это
        wEndScene
        wSetFPS   'устанавливаем фреймрейт по умолчанию 60 кадров в секунду
Wend
' -----------------------КОНЕЦ ГЛАВНОГО ЦИКЛА ВАШЕГО ПРОЕКТА ----------------------------------
'**********************************************************************************************

' ---------------------------------------------------------------------------------------------
' Останавливаем работу движка и высвобождаем ресурсы памяти
wStop
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Nikolas - WS3D Developer

  • Programmer
  • Global Moderator
  • Marquess
  • *
  • Posts: 888
  • Reputation 63
Начну играть в эту игру, когда автор внедрит AI и монстров из Doom3.
Среди оружейного арсенала хотелось бы видеть и бензопилу.  :) :)
Под лежачий камень мы всегда успеем...

Offline Vuvk

  • Friends
  • Baron (-ess)
  • *
  • Posts: 345
  • Reputation 34
  • Lokemundux Desco Domus Shaantitus
Было бы неплохо прикладывать к урокам пример того, что получается в итоге, не только в виде картинки, но и исходных файлов ::)
Crudux Cruo!

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 910
  • Reputation 36
  • Game making is my hobby for life!
Здесь на форуме я прикладываю. Или где-то ещё?
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Vuvk

  • Friends
  • Baron (-ess)
  • *
  • Posts: 345
  • Reputation 34
  • Lokemundux Desco Domus Shaantitus
Я имею ввиду не только код, а со всеми прилагаемыми ресурсами. Чтобы можно было скачать и поглядеть уже готовый вариант того, что получится, если следовать урокам. Обычно так делают
Crudux Cruo!

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 910
  • Reputation 36
  • Game making is my hobby for life!
Ну, все ресурсы уже имеются в дистрибутиве движка и в уроках я на это обращаю внимание. Например, в 1-м уроке, в 1-м шаге я написал:
"В начале 0-го урока я сказал, что для уролвня мы будем использовать квейковскую карту 'ctfcomp02_hazard.pk3'. Она находится в папке /media/BSPmaps. Скопируйте папку BSPmaps в папку /media  в вашем проекте, т.е. в папку MyProjects/MyFPS/media. В этой папке 3 карты и текстовый файл, удалите всё, кроме нашей карты."

Во 2-м уроке, во 2-м шаге я написал: "Вы можете сами найти модель оружия, но пока можно обойтись и бесплатной моделью из папки media/Models/Psionic/4guns. Там есть 4 разных видов оружия. Я возьму pistol.3ds. Перекидываем его из этой папки в папку нашего проекта, создав в папке media папку models; у меня это WorldSim3D_Win32_0.9.5_ru/MyProjects/MyFPS/media/models"

Ну, а когда появится более менее вразумительная демка (с моей т.з.), я скомпилирую и выложу.
« Last Edit: October 12, 2015, 10:43:07 AM by Alec - WS3D Developer »
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 910
  • Reputation 36
  • Game making is my hobby for life!
Цель этой серии уроков не только показать как сделать стрелялку, но и освоить некоторые функции движка, т.е. научиться работать на WS3D. Поэтому, некоторые моменты, я буду писать подробно. (Если кому-то нужна готовая демка без подробных объяснений, я сделаю по заказу за деньги, обращайтесь).
Пишу урок 3...
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 910
  • Reputation 36
  • Game making is my hobby for life!
Урок 3 будет с небольшим видео, демонстрирующем отдачу. Сейчас залью его на ютьюб и потом добавлю урок.
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 910
  • Reputation 36
  • Game making is my hobby for life!
Урок 3 скачать pdf

Смотреть видео

Обновлённый Код:

Code: [Select]
'' ----------------------------------------------------------------------------
'' Название проекта (игры): MyFPS
'' Автор(ы) проекта:
'' Дата начала создания проекта:
'' Дата окончания проекта:
'' ----------------------------------------------------------------------------
'' Краткое описание.
''
''
'' ----------------------------------------------------------------------------
'' Для удобства уберём подключение заголовков, а также разные пользовательские
'' (т.е. созданные вами) функции в отдельный модуль, который мы подключаем здесь,
'' в самом начале проекта.
#include "MyFunctions.bi"
'' Для удобства и порядка в коде можно убрать переменные, первоначальные настройки
'' и меню в отдельные модули и затем здесь подключить их.
'' ------------------------------------------------------------------------------
'' ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
'' Для порядка в коде лучше разделить объявление переменных по типам, тогда сразу
'' будет видно, где какая переменная.

'' [1.] Для работы со звуками
Dim Sounds_Init As FBSBOOLEAN
Dim as Integer hWave,hSound 'для работы со звуком
Dim PlayTime As Integer = 0     'для начала времени проигрывания звука

'' [2.] Объекты WorldSim3D (Меши, Ноды, Текстуры, Камеры, Селекторы и т.д.)
DIM MapMesh as wMesh
DIM MapNode as wNode
Dim MazeTexture As wTexture
DIM Camera as wCamera
DIM CameraNode as wNode
DIM MapCollision as wSelector
DIM BitmapFont as wFont
DIM Collision_anim as wSelector
DIM KeyEvent as wKEY_EVENT PTR
DIM MouseEvent as wMOUSE_EVENT Ptr

Dim GunMesh As wMesh         'для меша оружия
DIM GunNode as wNode         'для нода оружия
Dim GunTexture As wTexture  'для текстуры оружия


'' [3.] Другие переменные, не связанные напрямую с объектами и звуком. Это могут быть
'' разные флаги, счётчики, математика, а также для отладочных целей.
DIM XPOS as single
DIM YPOS as single
DIM ZPOS as single
DIM metrics as wstring * 256
Dim vX as wVECTOR
DIM vY as wVECTOR
DIM vZ as wVECTOR
DIM i As Integer
Dim flag As Integer

'' [4.] Для работы с текстом, если в проекте много разных сообщений, выводимых на экран, например,
'' тексты для меню, диалогов между персонажами, GUI и т.д.
Dim gameover_mes As String

'' [5.] Для сохранения состояния игры, первоначальных настроек игры, таблицы результатов (рекордов)
'' и т.д.

'' [6.] Другие переменные, не вошедшие в предыдущие разделы.
Dim recoil As Integer = 0
Dim recoil_timer As Integer = 1
'' Естественно, в зависимосчти от типа вашего проекта, какие-то разделы переменных вам не понадобятся,
'' а какие-то, наоборот, вы захотите добавить.
'' =============================================================================================
'' Запускаем интерфейс WorldSim3D
wStartAdvanced( wDT_OPENGL, 1024, 720, wBITS_PER_PIXEL_32,_
          wWINDOWED, wSHADOWS, wCAPTURE_EVENTS, wVERTICAL_SYNC_ON )

'' ++++++++++++++++++  ПЕРВОНАЧАЛЬНЫЕ НАСТРОЙКИ ПРОЕКТА  ++++++++++++++++++++++++++++++++++
'' Сюда включается всё, что должно быть выполнено только один раз или инициализировано для
'' последующей работы только один раз. Эта часть кода расположена до главного цикла,
'' который начинается с While wRunning. Также здесь расположены функции, инициализирующие
'' работу объектов WorldSim3D, которые будут продолжать работать и в главном цикле:
'' камеры, аниматоры и другие.
'' Также в этом разделе можно сделать работу меню, ведь обычно послезапуска игры сначала
'' появляется меню, из которого можно уже начать игру.

'' ------------------  ИНИЦИАЛИЗАЦИЯ РАБОТЫ ЗВУКОВ  ---------------------------------------
'' Показана на примере одного звука. Возможно вам не нужно озвучивание или вы предпочитаете
'' пользоваться другой звуковой библиотекой. Тогда просто уберите эту часть кода.
'' Расскомметируйте здесь, если вам нужно озвучивание и ниже.
Sounds_Init = fbs_Init(48000) ' инициализируем работу библиотеки FBSound
if Sounds_Init = false then
  ? "error: fbs_Init() !"
  ? FBS_Get_PlugError()
  beep:sleep:end 1
end if

' загружаем файл звука
Sounds_Init = fbs_Load_OGGFile ("media/Dark_Ambience.ogg",@hWave)
if Sounds_Init = false then
  ? "error: fbs_Load_OGGFile() !"
  beep:sleep:end 1
end If
' создаём звук для работы со всеми возможностями библиотеки FBSound
fbs_Create_Sound (hWave,@hSound)
'/
'' ---------------------------------------------------------------------------------------
' Устанавливаем текст заголовка окна приложения
wSetWindowCaption( "My FPS game" )
' загружаем нужный шрифт из папки ресурсов через функцию wGetFont
BitmapFont = wGetFont ( "media/3.png" )

'' ------- ЗАГРУЗКА ИГРОВЫХ ОБЪЕКТОВ НА СЦЕНУ ---------------------------------------------
'' Загрузку игровых объектов (3D моделей, частиц, скайбоксов и др.) на сцену.
'' [1.] Ноды для 3D моделей
wAddZipFile( "media/BSPmaps/ctfcomp02_hazard.pk3", wIGNORE_CASE, wIGNORE_PATHS )

' load the BSP map from the archive as a mesh object. any polygons in the mesh
' that do not have textures will be removed from the scene!
MapMesh = wGetMesh( "ctfcomp02_hazard.bsp" )

' add the map to the scene as a node. when adding the mesh this call uses a
' mechanism called an octtree that if very efficient at rendering large amounts
' of complext geometry most of which cant be seen, using this call for maps
' will greatly improve your framerates
MapNode = wAddMeshToSceneAsOcttree (MapMesh)

' Загружаем в проект модель оружия
GunMesh = wGetMesh( "media/models/pistol.3ds")

' Загружаем текстуру для модели оружия
GunTexture = wGetTexture ("media/models/pistol.jpg")

' Добавляем на сцену нод только что загруженного оружия
GunNode = wAddMeshToScene(GunMesh)

' применяем текстуру оружия к ноду оружия
wSetNodeMaterialTexture (GunNode, GunTexture, 0)

' пока отключим освещение оружия, а то по умолчанию оно будет неосвещённым (чёрным)
wSetNodeMaterialFlag (GunNode, wMF_LIGHTING, wOFF)

wSetNodePosition (GunNode, 7, -3, 12)
'' [2.] Аниматоры Нодов, например, wAddFlyCircleAnimator, wAddRotationAnimator и др.

'' [3.] Камеры, Ноды для них и первоначальные настройки камер
Camera = wAddFPSCamera
CameraNode = Camera
wSetNodePosition( CameraNode, 386, 366, 2726 )
wSetNodeRotation( CameraNode, 0, 0, 0 )
wSetCameraClipDistance ( CameraNode, 12000 )

'' [4.] Частицы (огонь, взрыв, снег и т.д. )

wAddChildToParent (GunNode, CameraNode)
'' ------------------ УСТАНОВКА ФИЗИКИ: ПРОВЕРКИ СТОЛКНОВЕНИЙ И ДР. -------------------
'' Это может быть как базовая физика, встроенная в WorldSim3D так и сторонних библиотек,
'' например, ODE, Newton и других.
MapCollision = wGetCollisionGroupFromComplexMesh (MapMesh, MapNode)

wAddCollisionAnimator(_
                        MapCollision,_
                        CameraNode,_
                        30.0,30.0,30.0,_
                        0.0,-9.8,0.0,_
                        0.0,50.0,0.0 )
'' ------------------------------------------------------------------------------------
'' ------------------ ОСВЕЩЕНИЕ -------------------------------------------------------
' добавим в проект яркий свет, освещающий всё вокруг
wSetAmbientLight ( 1, 1, 1 )

'' ------------------ ДРУГИЕ НАСТРОЙКИ или КОД ------------------------------------------------
' Скрываем указатель мыши, если он не нужен
wHideMouse

' -----------------------------------------------------------------------------
'******************************************************************************
'----------------------- ГЛАВНЫЙ ЦИКЛ ВАШЕГО ПРОЕКТА --------------------------
' здесь главный цикл приложения, поэтому
' мы устанавливаем цикл с условием: пока движок работает (функция wRunning)
' внутри цикла постоянно выполняются определённые команды, в основном для отображения сцены
While wRunning
        ' начинаем отрисовку сцены с цветом фона, например зелёный (который устанавливаем числами 0,55,0)
        wBeginScene( 0, 55, 0 )
       
      ' задаём момент времени, когда начать проигрывать звук
      If PlayTime = 1 Then ' начинаем проигрывать на 1-й миллисекунде работы цикла
           ''fbs_Play_Sound (hSound,10) ' Воспроизводим загруженный и созданный звук
           ' 10 означает сколько раз проиграть звук
      EndIf
      PlayTime +=1 'запускаем работу счётчика кадров цикла
     
      '' ------------------------ СОБЫТИЯ КЛАВИАТУРЫ ----------------------------
        ' если события клавиатуры могут быть обработаны, то:
        while wKeyEventAvailable
            ' читаем события клавиатуры.
            KeyEvent = wReadKeyEvent
   
            ' если нажата какая-либо клавиша, связываем с ней событие, оторое мы хотим
            ' чтобы оно произошло. Это может быть что угодно:
            select case as const KeyEvent->key
                case KEY_KEY_D     ' клавиша D
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                End If
   
                case KEY_KEY_W     ' клавиша W
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                End If
                   
                case KEY_KEY_A     ' клавиша A
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                End If
                   
                case KEY_KEY_S     ' клавиша S
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                End If
            ' Добавим функцию для закрытия окна через клавишу ESCAPE.
                ' Если клавиатура не исчпользуется, то для этой цели нужно использовать
                ' другую функцию - wCloseESC(), которую можно поместить в конце главного цикла.
                wCloseKEY_ESC()
            end Select
        Wend
       
        '' --------------------------- СОБЫТИЯ МЫШИ -----------------------------------------
        '
        While wMouseEventAvailable
            MouseEvent = wReadMouseEvent
   
            if MouseEvent->action = wME_LMOUSE_PRESSED_DOWN then
                    recoil = 1
            End If
   
        Wend
       
        If recoil_timer >= 1 And recoil_timer <= 4 Then
                wSetNodePosition (GunNode, 7, -3, 10.5 )
          Else
                wSetNodePosition(GunNode, 7, -3, 10 )
        End If
       
        If recoil = 1 Then recoil_timer +=1 'время отдачи пошло, если игрок нажал ЛКМ
       
        If recoil_timer >= 4 Then
             recoil_timer = 0
              recoil = 0
          EndIf


      '' ----------------------------------------------------------------------------------   
      '' Завершение отрисовки 3D сцены
        wDrawScene
  '' ------------------------- ОТОБРАЖЕНИЕ ТЕКСТА НА ЭКРАНЕ ---------------------------------
  '' отображаем на экране загруженный ранее шрифт. Это нужно сделать после функции wDrawScene,
  '' т.е. после отрисовки 3D сцены, чтобы выводимый на экран текст отображался поверх объектов
  '' сцены, иначе объекты сцены будут закрывать текст.
  '' последние 4 числа - координаты текста: X,Y левого верхнего угла и X,Y правого нижнего угла
          w2DFontDraw ( BitmapFont, "Press arrows to move around the map and LMB to shoot", 250, 640, 450, 660 )
          ''w2DFontDraw ( BitmapFont, " Make games of your dream with WorldSim3D game engine (Worldsim3D.com)", 300, 600, 450, 620 )

        ' заканчиваем отрисовку всего, что на экране и отображаем это
        wEndScene
        wSetFPS   'устанавливаем фреймрейт по умолчанию 60 кадров в секунду
Wend
' -----------------------КОНЕЦ ГЛАВНОГО ЦИКЛА ВАШЕГО ПРОЕКТА ----------------------------------
'**********************************************************************************************

' ---------------------------------------------------------------------------------------------
' Останавливаем работу движка и высвобождаем ресурсы памяти
wStop

WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 910
  • Reputation 36
  • Game making is my hobby for life!
Quote
хотелось бы видеть и бензопилу
А для этого нужно написать серию уроков "Бензопилитель от 1-го лица".  ;D
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!