Author Topic: Выбрать объект и добавить на сцену  (Read 933 times)

0 Members and 1 Guest are viewing this topic.

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 911
  • Reputation 36
  • Game making is my hobby for life!
Как выбрать объект для добавления на сцену?

Для версии 0.9.0

Например, у нас в игре нужно добавлять здания на сцену, кликая по спрайту добавления здания (как в игре 'Settlers').
Это обычно в стратегиях, экономических симуляторах и RPG.

ЛКМ над спрайтом - выбор здания (держать нажатой не надо, чтобы двигать здание)
ПКМ - установить выбранное здание

Дополн. ресурсы:
- модель здания (в папке) - кинуть в  /Media/Models/
- Building.png, Building_no.png и Building_t.png  кинуть в /Media/Sprites/
- surface.png  кинуть в /Media/Textures/

Code: [Select]
'' ----------------------------------------------------------------------------
'' Сделал Alec (WorldSim3D developer) 16.07.2014


'' ////////////////////////////////////////////////////////////////////////////
'' Includes for extension libraries
#include "WorldSim3D.bi"

'' ////////////////////////////////////////////////////////////////////////////
'' global variables

' WorldSim3D objects
DIM Mesh_building1 as wMesh
Dim Node_building1 as wNode
Dim Texture_building1 As wTexture
Dim Node_building_t (1 To 10) as wNode

Dim OurCamera as wCamera

DIM BitmapFont as wFont
DIM MouseEvent as wMOUSE_EVENT Ptr
DIM event_mes as wstring * 256
Dim Back_Image As wGUIobject ' объект-фон для ГУИ
Dim SpriteImage As wGUIobject ' объект-изображение для ГУИ
Dim Back_texture As wTexture' текстура для невидимого фона
Dim Sprite_texture As wTexture ' текстура для спрайта здания
Dim Sprite_texture_t As wTexture' текстура для спрайта здания, когда наведена мышка
Dim Sprite_texture_no As wTexture ' текстура для спрайта здания, когда они закончились
DIM GUIEvent as wGUI_EVENT Ptr
DIM guiStatic as wGUIobject ' объект ГУИ для вывода сообщений

Dim screen_width As Integer = 800
Dim screen_height As Integer = 600

' флаги
Dim a As Integer ' находится ли мышка над спрайтом здания
Dim b As Integer ' закончили или нет с установкой очередного здания

Dim i as Integer ' счётчик для количества зданий и цикла

Dim debug As Integer
'========
' для координат устанавливаемого здания
Dim XPosition As Single
Dim YPosition As Single
Dim ZPosition As Single
Dim normalX As single, normalY As single, normalZ As single

' -----------------------------------------------------------------------------
' start the WorldSim3D interface
wStart( wDT_OPENGL, screen_width, screen_height, wBITS_PER_PIXEL_32,_
          wWINDOWED, wSHADOWS, wCAPTURE_EVENTS, wVERTICAL_SYNC_ON )

' send the window caption
wSetWindowCaption( "Selecting a building" )

Mesh_building1 = wGetMesh( "../media/Models/Buildings/1/1.x" )
'Node_building1 = wAddMeshToScene( Mesh_building1 )
Texture_building1 = wGetTexture( "../media/Models/Buildings/1/1.jpg" )
'wSetNodeMaterialTexture( Node_building1, Texture_building1, 0 )
'wSetNodeRotation ( Node_building1, -5,-40,5 )
'wSetNodeMaterialFlag( Node_building1, wMF_LIGHTING, wOFF )

' добавляем 10 однотипных зданий и делаем их сначала невидимиыми
for i = 1 to 10
Node_building_t (i) = wAddMeshToScene( Mesh_building1 )
wSetNodeMaterialTexture( Node_building_t (i), Texture_building1, 0 )
wSetNodeRotation ( Node_building_t (i), -5,-40,5 )
wSetNodeMaterialFlag( Node_building_t(i), wMF_LIGHTING, wOFF )
wSetNodeVisibility ( Node_building_t (i), wINVISIBLE )
Next i
' счётчик стал равен 10
i = 0 ' обнуляем счётчик, чтобы добавлять здания поочерёдно с 1-го по 10-е

' для спрайтов GUI
Back_texture = wGetTexture( "../Media/Textures/surface.png" )
Sprite_texture = wGetTexture( "../Media/Sprites/Building.png" )
Sprite_texture_t = wGetTexture( "../Media/Sprites/Building_t.png" )
Sprite_texture_no = wGetTexture( "../Media/Sprites/Building_no.png" )

' load the bitmap font as a texture
BitmapFont = wGetFont ( "../media/Fonts/bitmapfont2.bmp" )
wGUISetFont( BitmapFont )

' GUI
Back_Image = wAddImage ( Back_texture, 0, 0, wUSE_ALPHA, 1 )
SpriteImage = wAddImage ( Sprite_texture, 10, screen_height - 70, wUSE_ALPHA, 2 )
guiStatic = wAddStaticText( _
                   "Hello World", _     ' Text to display
                   10, 500, 150, 520, _        ' Size
                   wGUI_BORDER, _ ' border around the text
                   wGUI_WRAP )    ' text wrapped
                   
                   
OurCamera = wAddCamera( 0,5,10, 0,0,0 )
' -----------------------------------------------------------------------------
' while the WorldSim3D environment is still running
Dim as Single frameTime = timer + 0.0167
WHILE wRunning
    ' is it time for another frame
    if timer > frameTime then
        ' calculate the time the next frame starts
        frameTime = timer + 0.0167
       
        ' begin the scene, erasing the canvas with sky-blue before rendering
        wBeginScene( 125, 125, 125 )
       
        ' серый спрайт, чтобы показать, что здания закончились
        wDraw2DImage ( Sprite_texture_no, 10, screen_height - 70 )
       
    If wGUIEventAvailable then

        ' read the GUI event out
        GUIEvent = wReadGUIEvent
        ' process the particular control
        select case GUIEvent->id
        Case 1
        If GUIEvent->event = wGUI_ET_ELEMENT_HOVERED Then
            ' if this is a mouse move event
            wGUISetText( guiStatic, "Nothing selected")
    a = 0 ' мышка не над спрйтом здания
        End If
   
        Case 2
        If GUIEvent->event = wGUI_ET_ELEMENT_HOVERED Then
            ' if this is a mouse move event
            wGUISetText( guiStatic, "Building 1 selected")
            a = 1 ' мышка над спрйтом здания
        End If
        End Select
       
    EndIf
   
    While wMouseEventAvailable
            ' read the mouse event out
            MouseEvent = wReadMouseEvent
            If a = 1 And MouseEvent->action = wME_LMOUSE_PRESSED_DOWN Then
            If b = 0 Then i = i + 1 ' если очередное здание добавлено, то переходим кследующему
            If i >= 10 Then wGUIRemove ( SpriteImage ) 'если уже добавлено 10 зданий, то удаляем
            ' спрайт добавляемого здания
            wSetNodeMaterialType ( Node_building_t (i), wMT_TRANSPARENT_ADD_COLOR )'делаем добавляемое
            'здание прозрачным
            b = 1 ' игрок ещё не установил здание, только выбрал
            EndIf
    If b = 1 And MouseEvent->action = wME_MOUSE_MOVED Then 'если двигает мышкой неустановленное здание
    ' получаем 3d-координаты из координат мышки
            wGet3DPositionFromScreenCoordinates ( MouseEvent->x, MouseEvent->y, XPosition, YPosition, ZPosition, OurCamera, normalX = 1.0, normalY = 0.0, normalZ = 0.0)
            ' соответственно меняем позицию здания, пока он водит мышкой - куда бы установить
            wSetNodePosition ( Node_building_t (i), XPosition, YPosition, ZPosition )
            ' делаем здание видимым
wSetNodeVisibility ( Node_building_t (i), wVISIBLE )
            '
    EndIf
    ' если здание выбрано и игрок кликает на правую кнопку мыши
    If b = 1 And MouseEvent->action = wME_RMOUSE_PRESSED_DOWN Then
    ' устанавливаем здание, переключая флаг b на ноль
    ' меняем материал здания с прозрачного на обычный
    wSetNodeMaterialType ( Node_building_t (i), wMT_SOLID )
    b = 0 ' очередное здание добавлено
    EndIf
    Wend
        debug = i ' для того, чтобы видеть количество зданий
       

  wDrawGUI
 
  ' draw the scene
        wDrawScene
        ' если мышка над спрайтом,топоказываемдругой спрайт - выбранного здания
      If a = 1 Then wDraw2DImageElement ( Sprite_texture_t, 2, 520,  0, 0, 80, 80, wUSE_ALPHA )
       
        'w2DFontDraw ( BitmapFont, event_mes, 10, 10, 250, 24 )
        w2DFontDraw ( BitmapFont, Str(debug), 400, 10, 400, 24 )
   
        ' end drawing the scene and render it
        wEndScene
    End if

WEND

' -----------------------------------------------------------------------------
' Stop the WorldSim3D engine and release resources
wStop

Удачной разработки стратегии!  :)
« Last Edit: November 12, 2014, 09:51:48 PM by Alec - WS3D Developer »
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 911
  • Reputation 36
  • Game making is my hobby for life!
Re: Выбрать объект и добавить на сцену
« Reply #1 on: July 17, 2014, 08:20:59 AM »
Забыл сказать:
ЛКМ над спрайтом - выбор здания (держать нажатой не надо, чтобы двигать здание)
ПКМ - установить выбранное здание
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 911
  • Reputation 36
  • Game making is my hobby for life!
Re: Выбрать объект и добавить на сцену
« Reply #2 on: August 12, 2014, 07:57:24 PM »
Вспомнил я про этот пример, что в нём как бы что-то недоработано. В тех стратегиях, которые я играл и видел в обзорах -  все здания, юниты и другие объекты на сцене расположены под одним углом, а игрок просто перемещается влево-вправо, вверх-вниз и ближе (к) - дальше от объектов. И как бы он не перемещался по карте, объекты всегда остаются под одним углом.

Чтобы так было, нужно просто добавить одну функцию:

Code: [Select]
wSetCameraOrthagonal (OurCamera,0,5,10)
Таким образом мы делаем ортогональный вид. Для сравнения: посмотрите как выглядят государства и др. объекты на глобусе (под разным углом) и как они выглядят на обычной карте (все под одним углом). Так вот эта функция превращает вид камеры из глобуса в карту.

3 числовых значения у этой функции - точка наблюдения (смотрите справку).
Добавить функцию нужно после:
Code: [Select]
OurCamera = wAddCamera( 0,5,10, 0,0,0 )
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!