Форум программистов, компьютерный форум, киберфорум
Программирование игр
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Just Do It!
 Аватар для XLAT
4219 / 2680 / 656
Регистрация: 23.09.2014
Сообщений: 9,235
Записей в блоге: 3

Давайте сделаем игру Columns

09.12.2025, 17:46. Показов 20776. Ответов 315
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Igor3D Посмотреть сообщение
Какие есть предложения?
давай лучше игру запилим
например, ТЗ https://disk.yandex.ru/d/l7-X5wW48Zn9Ig

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

который гораздо прогрессивнее:

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

затем части складываются в одно целое, которое и есть целевая программа - игра.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.12.2025, 17:46
Ответы с готовыми решениями:

Господа программисты есть идея создать игру. Давайте объединимся
Итак есть идея создать онлайн игру. Игра платная, приносящая доход владельцам. Предложение такое:...

Может соберемся и сделаем игрушку?
Вообщем. Предлогаю отписаться здесь всем энтузиастам и желающим. Не спрашивайте про диздоки и всё...

Может соберемся и сделаем что-нибудь вместе?
Предлагаю вполне закономерную для веб-программистов идею создать какой-нибудь(какой после...

315
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6313 / 3036 / 1053
Регистрация: 01.06.2021
Сообщений: 11,558
15.12.2025, 20:16
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от XLAT Посмотреть сообщение
смогёшь?
попробую

Цитата Сообщение от XLAT Посмотреть сообщение
std::string textShort, std::string textLong
сколько там приблизительно будет символов в каждой строке? т.е. хочу узнать, что это за тексты?
1
Just Do It!
 Аватар для XLAT
4219 / 2680 / 656
Регистрация: 23.09.2014
Сообщений: 9,235
Записей в блоге: 3
15.12.2025, 21:55  [ТС]
Цитата Сообщение от Royal_X Посмотреть сообщение
сколько там приблизительно будет символов в каждой строке? т.е. хочу узнать, что это за тексты?
изначально планируется так юзать:
1. в уголке экрана кликабельный лейбл с "F1::Help"
2. при клике или F1 появляется текст "какие клавиши за что отвечают"
3. там(на увеличенном лейбле) ещё можно кнопку приделать "Разрабы"
4. а разрабах твой ник будет))

пока этого хватит,
но можно туда и настройки и тп. прилепить будет по позже))

главное всё инкапсулируй в одном файле: ui.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
///----------------------------------------------------------------------------|
/// "ui.h"
/// Автор: Royal_X
///----------------------------------------------------------------------------:
#ifndef UI_H
#define UI_H
#include "config-game.h"
 
///---------|
/// Modules.|
///---------:
namespace mdl
{   
    struct  UI : Base ///<--- в Base можно взять указатели манагера сцены...
    {       UI()
            {   std::cout << "Объект UI создан! Автор: Royal_X\n";
            }
        
        
    };
}
 
 
#endif // UI_H
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6313 / 3036 / 1053
Регистрация: 01.06.2021
Сообщений: 11,558
15.12.2025, 23:24
Цитата Сообщение от XLAT Посмотреть сообщение
namespace mdl
я в этом пространстве в файле ui.h создал класс ClickableTextBox

Добавлено через 1 час 19 минут
XLAT, как-то так получилось

ui.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
///----------------------------------------------------------------------------|
/// "ui.h"
/// Автор: XLAT
///----------------------------------------------------------------------------:
#ifndef UI_H
#define UI_H
#include "config-game.h"
 
///---------|
/// Models. |
///---------:
namespace mdl
{   
    struct  UI
    {       
        UI()
        {   
            std::cout << "Объект UI создан! Автор: XLAT\n";
        }
    };
 
    class ClickableTextBox
    {
    private:
        TrayManager* mTrayMgr;
        TextBox* mTextBox;
 
        std::string mTextShort;
        std::string mTextLong;
        std::string mCaption;
 
        int mX;
        int mY;
        int mWidth = 300;
        int mShortHeight = 100;
        int mLongHeight = 500;
 
        bool mIsLongText = false;
 
        void createTextBox();
        void destroyTextbox()
        {
            if (mTrayMgr && mTextBox)
            {
                mTrayMgr->destroyWidget(mTextBox);
                mTextBox = nullptr;
            }
        }
        void toggleText()
        {
            if (mTextBox == nullptr)
                return;
            mIsLongText = !mIsLongText;
            destroyTextbox();
            createTextBox();
        }
    public:
        ClickableTextBox(TrayManager* trayManager)
            : mTrayMgr(trayManager)
            , mTextShort("")
            , mTextLong("")
            , mCaption("")
            , mX(0)
            , mY(0)
        {
            createTextBox();
        }
        ClickableTextBox(TrayManager* trayManager, 
            const std::string& textShort, 
            const std::string& textLong,
            const std::string& caption,
            int x, int y)
            : mTrayMgr(trayManager)
            , mTextShort(textShort)
            , mTextLong(textLong)
            , mCaption(caption)
            , mX(x)
            , mY(y)
        {
            createTextBox();
        }
        ~ClickableTextBox()
        { 
        }
        void setup(int x, int y)
        {
            mX = x;
            mY = y;
        }
        void setText(const std::string& textShort, const std::string& textLong)
        {
            mTextShort = textShort;
            mTextLong = textLong;
            if (mTextBox)
                mTextBox->setText(mIsLongText ? mTextLong : mTextShort);
        }
        void setCaption(const std::string& caption)
        {
            mCaption = caption;
            if (mTextBox)
                mTextBox->setCaption(mCaption);
        }
        bool mousePressed(const OgreBites::MouseButtonEvent& evt)
        {
            if (evt.button != OgreBites::BUTTON_LEFT)
                return false;
 
            if (mTextBox && mTextBox->isVisible())
            {
                
                Vector2 pos = Vector2(mX, mY);
                Vector2 size = Vector2(mWidth, mIsLongText ? mLongHeight : mShortHeight);
 
                if (evt.x >= pos.x &&
                    evt.x <= pos.x + size.x &&
                    evt.y >= pos.y &&
                    evt.y <= pos.y + size.y)
                {
                    toggleText();
                    return true;
                }
            }
            return false;
        }
 
 
    };
 
    inline void ClickableTextBox::createTextBox()
    {
        static int id = 0;
        std::string name = "ClickableTextBox_" + std::to_string(id++);
        mTextBox = mTrayMgr->createTextBox(
            TrayLocation::TL_TOPLEFT,
            name,
            mCaption,
            mWidth,
            mIsLongText ? mLongHeight : mShortHeight
        );
        mTextBox->setText(mIsLongText ? mTextLong : mTextShort);
    }
}
 
 
 
 
#endif // UI_H


inspector.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
///----------------------------------------------------------------------------|
/// "inspector.h"
///----------------------------------------------------------------------------:
#ifndef INSPECTOR_H
#define INSPECTOR_H
#include "well.h"
#include "ui.h"
 
 
///---------|
/// Models. |
///---------:
namespace mdl
{  
    ///------------------------------------------------------------------------|
    /// InspectorRoot.("Test-Columns-2025")
    ///---------------------------------------------------------- InspectorRoot:
    struct  InspectorRoot
            :   Base
            ,   OgreBites::ApplicationContext
            ,   OgreBites::InputListener
    {       InspectorRoot( ): OgreBites::ApplicationContext("")
            {}
        
        Ogre::Root*           root;
        Ogre::SceneManager* scnMgr;
        SceneNode*        nodeBase;
        SceneNode*        nodeUse ;
        TrayManager*        trayMgr;
        ClickableTextBox*       ctb;
 
        Camera       camera;
        Ninja         ninja;
        Sphere       sphere;
        Lights       lights;
        UI               ui;
        Tree           tree;
        Well           well;
        Ground       ground;
        
        Ogre::RTShader::ShaderGenerator* shadergen;
 
 
    protected:
 
        ///-------------------------------------------|
        /// Свой путь к "ogre.h" ---> (box.cpp)       |
        ///-------------------------------------------:
        void createRoot() override;
 
        void setup() override
        {   
            OgreBites::ApplicationContext::setup();
 
            addInputListener(this);
 
            Base::pInspectorRoot = this;
            Base::ctx             = this;
 
            root   = getRoot();
            scnMgr = root->createSceneManager();
            scnMgr->setAmbientLight(ColourValue(0, 0, 0));
            scnMgr->setShadowTechnique(
                ShadowTechnique::SHADOWTYPE_STENCIL_ADDITIVE);
 
            nodeBase = scnMgr->getRootSceneNode()->createChildSceneNode();
            nodeUse  = scnMgr->getRootSceneNode()->createChildSceneNode();
 
            Base::scnMgr   = scnMgr;
            Base::nodeBase = nodeBase;
 
            ////////////////////////////////////////////////////////////////////
            Ogre::RenderWindow* window = getRenderWindow();
            setWindowIcon      (window);
            ////////////////////////////////////////////////////////////////////
 
        /// root->loadPlugin("OgreAssimp");
 
            shadergen = RTShader::ShaderGenerator::getSingletonPtr();
            shadergen-> addSceneManager(scnMgr);
 
            camera   .setup(nodeUse);
            lights   .setup(camera.camNode);
            ninja    .setup();
        /// sphere   .setup();
            tree     .setup();
            well     .setup();
            ground   .setup();
 
            // Добавьте ВСЕ папки с ресурсами перед инициализацией
            ResourceGroupManager& rgm = ResourceGroupManager::getSingleton();
 
            // Добавляем основную папку media
            rgm.addResourceLocation("media", "FileSystem", "General");
 
            // Добавляем папку со шрифтами отдельно (важно!)
            rgm.addResourceLocation("media/fonts", "FileSystem", "General");
 
            // Явно загружаем .fontdef файл
            rgm.initialiseResourceGroup("General");
 
            // ИЛИ инициализируем все
            //rgm.initialiseAllResourceGroups();
 
            
            OverlaySystem*  overlaySystem = getOverlaySystem();
            scnMgr->addRenderQueueListener(overlaySystem);
 
            Ogre::RenderWindow* mWindow = getRenderWindow();
            trayMgr = new OgreBites::TrayManager("UI", mWindow);
            addInputListener(trayMgr);
            trayMgr->hideCursor();
 
            ctb = new ClickableTextBox(trayMgr);
            ctb->setup(50, 50);
            ctb->setText("Short text", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam a lacinia diam. Pellentesque et dolor ac sem gravida imperdiet quis ornare dui. Donec in odio vulputate, mattis justo sed, finibus ligula. Etiam egestas urna vel sapien pulvinar, et vehicula libero tincidunt. Sed ullamcorper dolor at dolor consequat, non pharetra libero tincidunt. Nam volutpat blandit bibendum. Phasellus ligula ipsum, varius vitae vulputate ornare, dapibus quis arcu.");
            ctb->setCaption("F1 - Help");
            
        }
 
        ///-------------------------------------------|
        /// Обработка клавиш.                         |
        ///-------------------------------------------:
        bool keyPressed(const KeyboardEvent& evt)
        {   if (evt.keysym.sym == SDLK_ESCAPE)
            {   getRoot()->queueEndRendering();
            }
            else if (isRotWold && evt.keysym.sym == SDLK_SPACE)
            {   isRotWold = false;
                return      true;
            }
            
            return well.keyPressed(evt);
        }
 
        float accumulatedTime{0};  // Накопленное время
        float intervalTime   {4};  // Интервал (1 секунда)
        bool  isRotWold   {true};
 
        ///-------------------------------------------|
        /// Тут крутятся фреймы.                      |
        ///-------------------------------------------:
        void frameRendered(const Ogre::FrameEvent& evt) override
        {
            Base::deltaTime = evt.timeSinceLastFrame;
 
            accumulatedTime += evt.timeSinceLastFrame;
       
            if(accumulatedTime >= intervalTime)
            {
            /// changeFigure();
                accumulatedTime -= intervalTime;
            }
 
            well.update(evt.timeSinceLastFrame);
 
            if(isRotWold) nodeBase->yaw  (Ogre::Degree(30 * deltaTime));
 
        }
 
 
        bool mousePressed(const OgreBites::MouseButtonEvent& evt) override
        {
            if (ctb->mousePressed(evt))
                return true;
        }
 
        ///-------------------------------------------|
        /// Установка иконки на окно.                 |
        ///-------------------------------------------:
        void setWindowIcon(Ogre::RenderWindow* window)
        {
#ifdef _WIN32
            HWND  hwnd   ; window->getCustomAttribute("WINDOW", &hwnd);
            HICON hIcon{};
 
            if (hwnd)
            {   /*
                hIcon = (HICON)LoadImage(
                    NULL,
                    L"icon.ico",
                    IMAGE_ICON,
                    0, 0,
                    LR_LOADFROMFILE | LR_DEFAULTSIZE
                );
                */
                if (!hIcon)
                {   // Из ресурсов (если есть .rc файл)
                    hIcon = LoadIcon(GetModuleHandle(NULL),
                                     MAKEINTRESOURCE(101));
                }
            
                if (hIcon)
                {   // WM_SETICON - сообщение Windows API
                    SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
                    SendMessage(hwnd, WM_SETICON, ICON_BIG  , (LPARAM)hIcon);
                }
            }
#endif
        }
    };
}
 
#endif // INSPECTOR_H


Добавлено через 35 секунд
XLAT, изменения вносил тока в эти два файла
1
Just Do It!
 Аватар для XLAT
4219 / 2680 / 656
Регистрация: 23.09.2014
Сообщений: 9,235
Записей в блоге: 3
15.12.2025, 23:26  [ТС]
Цитата Сообщение от Royal_X Посмотреть сообщение
как-то так получилось
ок.

спешки нет никакой.

я щас занят - тестировать буду завтра.

если ты уверен, что так хорошо, то так тому и быть)
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6313 / 3036 / 1053
Регистрация: 01.06.2021
Сообщений: 11,558
15.12.2025, 23:33
Цитата Сообщение от XLAT Посмотреть сообщение
если ты уверен, что так хорошо, то так тому и быть)
Вот последний вариант, выше был баг:

ui.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
///----------------------------------------------------------------------------|
/// "ui.h"
/// Автор: XLAT
///----------------------------------------------------------------------------:
#ifndef UI_H
#define UI_H
#include "config-game.h"
 
///---------|
/// Models. |
///---------:
namespace mdl
{   
    struct  UI
    {       
        UI()
        {   
            std::cout << "Объект UI создан! Автор: XLAT\n";
        }
    };
 
    class ClickableTextBox
    {
    private:
        TrayManager* mTrayMgr;
        TextBox* mTextBox;
 
        std::string mTextShort;
        std::string mTextLong;
        std::string mCaption;
 
        int mWidth = 300;
        int mShortHeight = 100;
        int mLongHeight = 500;
 
        bool mIsLongText = false;
 
        void createTextBox();
        void destroyTextbox()
        {
            if (mTrayMgr && mTextBox)
            {
                mTrayMgr->destroyWidget(mTextBox);
                mTextBox = nullptr;
            }
        }
        void toggleText()
        {
            if (mTextBox == nullptr)
                return;
            mIsLongText = !mIsLongText;
            destroyTextbox();
            createTextBox();
        }
    public:
        ClickableTextBox(TrayManager* trayManager)
            : mTrayMgr(trayManager)
            , mTextShort("")
            , mTextLong("")
            , mCaption("")
        {
            createTextBox();
        }
        ClickableTextBox(TrayManager* trayManager, 
            const std::string& textShort, 
            const std::string& textLong,
            const std::string& caption,
            int x, int y)
            : mTrayMgr(trayManager)
            , mTextShort(textShort)
            , mTextLong(textLong)
            , mCaption(caption)
        {
            createTextBox();
        }
        ~ClickableTextBox()
        { 
        }
        void setText(const std::string& textShort, const std::string& textLong)
        {
            mTextShort = textShort;
            mTextLong = textLong;
            if (mTextBox)
                mTextBox->setText(mIsLongText ? mTextLong : mTextShort);
        }
        void setCaption(const std::string& caption)
        {
            mCaption = caption;
            if (mTextBox)
                mTextBox->setCaption(mCaption);
        }
        bool mousePressed(const OgreBites::MouseButtonEvent& evt)
        {
            if (evt.button != OgreBites::BUTTON_LEFT)
                return false;
 
            if (mTextBox && mTextBox->isVisible())
            {
                
                Vector2 size = Vector2(mWidth, mIsLongText ? mLongHeight : mShortHeight);
 
                if (evt.x <= size.x && evt.y <= size.y)
                {
                    toggleText();
                    return true;
                }
            }
            return false;
        }
 
 
    };
 
    inline void ClickableTextBox::createTextBox()
    {
        static int id = 0;
        std::string name = "ClickableTextBox_" + std::to_string(id++);
        mTextBox = mTrayMgr->createTextBox(
            TrayLocation::TL_TOPLEFT,
            name,
            mCaption,
            mWidth,
            mIsLongText ? mLongHeight : mShortHeight
        );
        mTextBox->setText(mIsLongText ? mTextLong : mTextShort);
    }
}
 
 
 
 
#endif // UI_H



inspector.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
///----------------------------------------------------------------------------|
/// "inspector.h"
///----------------------------------------------------------------------------:
#ifndef INSPECTOR_H
#define INSPECTOR_H
#include "well.h"
#include "ui.h"
 
 
///---------|
/// Models. |
///---------:
namespace mdl
{  
    ///------------------------------------------------------------------------|
    /// InspectorRoot.("Test-Columns-2025")
    ///---------------------------------------------------------- InspectorRoot:
    struct  InspectorRoot
            :   Base
            ,   OgreBites::ApplicationContext
            ,   OgreBites::InputListener
    {       InspectorRoot( ): OgreBites::ApplicationContext("")
            {}
        
        Ogre::Root*           root;
        Ogre::SceneManager* scnMgr;
        SceneNode*        nodeBase;
        SceneNode*        nodeUse ;
        TrayManager*        trayMgr;
        ClickableTextBox*       ctb;
 
        Camera       camera;
        Ninja         ninja;
        Sphere       sphere;
        Lights       lights;
        UI               ui;
        Tree           tree;
        Well           well;
        Ground       ground;
        
        Ogre::RTShader::ShaderGenerator* shadergen;
 
 
    protected:
 
        ///-------------------------------------------|
        /// Свой путь к "ogre.h" ---> (box.cpp)       |
        ///-------------------------------------------:
        void createRoot() override;
 
        void setup() override
        {   
            OgreBites::ApplicationContext::setup();
 
            addInputListener(this);
 
            Base::pInspectorRoot = this;
            Base::ctx             = this;
 
            root   = getRoot();
            scnMgr = root->createSceneManager();
            scnMgr->setAmbientLight(ColourValue(0, 0, 0));
            scnMgr->setShadowTechnique(
                ShadowTechnique::SHADOWTYPE_STENCIL_ADDITIVE);
 
            nodeBase = scnMgr->getRootSceneNode()->createChildSceneNode();
            nodeUse  = scnMgr->getRootSceneNode()->createChildSceneNode();
 
            Base::scnMgr   = scnMgr;
            Base::nodeBase = nodeBase;
 
            ////////////////////////////////////////////////////////////////////
            Ogre::RenderWindow* window = getRenderWindow();
            setWindowIcon      (window);
            ////////////////////////////////////////////////////////////////////
 
        /// root->loadPlugin("OgreAssimp");
 
            shadergen = RTShader::ShaderGenerator::getSingletonPtr();
            shadergen-> addSceneManager(scnMgr);
 
            camera   .setup(nodeUse);
            lights   .setup(camera.camNode);
            ninja    .setup();
        /// sphere   .setup();
            tree     .setup();
            well     .setup();
            ground   .setup();
 
            // Добавьте ВСЕ папки с ресурсами перед инициализацией
            ResourceGroupManager& rgm = ResourceGroupManager::getSingleton();
 
            // Добавляем основную папку media
            rgm.addResourceLocation("media", "FileSystem", "General");
 
            // Добавляем папку со шрифтами отдельно (важно!)
            rgm.addResourceLocation("media/fonts", "FileSystem", "General");
 
            // Явно загружаем .fontdef файл
            rgm.initialiseResourceGroup("General");
 
            // ИЛИ инициализируем все
            //rgm.initialiseAllResourceGroups();
 
            
            OverlaySystem*  overlaySystem = getOverlaySystem();
            scnMgr->addRenderQueueListener(overlaySystem);
 
            Ogre::RenderWindow* mWindow = getRenderWindow();
            trayMgr = new OgreBites::TrayManager("UI", mWindow);
            addInputListener(trayMgr);
            trayMgr->hideCursor();
 
            ctb = new ClickableTextBox(trayMgr);
            ctb->setText("Short text", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam a lacinia diam. Pellentesque et dolor ac sem gravida imperdiet quis ornare dui. Donec in odio vulputate, mattis justo sed, finibus ligula. Etiam egestas urna vel sapien pulvinar, et vehicula libero tincidunt. Sed ullamcorper dolor at dolor consequat, non pharetra libero tincidunt. Nam volutpat blandit bibendum. Phasellus ligula ipsum, varius vitae vulputate ornare, dapibus quis arcu.");
            ctb->setCaption("F1 - Help");
            
        }
 
        ///-------------------------------------------|
        /// Обработка клавиш.                         |
        ///-------------------------------------------:
        bool keyPressed(const KeyboardEvent& evt)
        {   if (evt.keysym.sym == SDLK_ESCAPE)
            {   getRoot()->queueEndRendering();
            }
            else if (isRotWold && evt.keysym.sym == SDLK_SPACE)
            {   isRotWold = false;
                return      true;
            }
            
            return well.keyPressed(evt);
        }
 
        float accumulatedTime{0};  // Накопленное время
        float intervalTime   {4};  // Интервал (1 секунда)
        bool  isRotWold   {true};
 
        ///-------------------------------------------|
        /// Тут крутятся фреймы.                      |
        ///-------------------------------------------:
        void frameRendered(const Ogre::FrameEvent& evt) override
        {
            Base::deltaTime = evt.timeSinceLastFrame;
 
            accumulatedTime += evt.timeSinceLastFrame;
       
            if(accumulatedTime >= intervalTime)
            {
            /// changeFigure();
                accumulatedTime -= intervalTime;
            }
 
            well.update(evt.timeSinceLastFrame);
 
            if(isRotWold) nodeBase->yaw  (Ogre::Degree(30 * deltaTime));
 
        }
 
 
        bool mousePressed(const OgreBites::MouseButtonEvent& evt) override
        {
            if (ctb->mousePressed(evt))
                return true;
        }
 
        ///-------------------------------------------|
        /// Установка иконки на окно.                 |
        ///-------------------------------------------:
        void setWindowIcon(Ogre::RenderWindow* window)
        {
#ifdef _WIN32
            HWND  hwnd   ; window->getCustomAttribute("WINDOW", &hwnd);
            HICON hIcon{};
 
            if (hwnd)
            {   /*
                hIcon = (HICON)LoadImage(
                    NULL,
                    L"icon.ico",
                    IMAGE_ICON,
                    0, 0,
                    LR_LOADFROMFILE | LR_DEFAULTSIZE
                );
                */
                if (!hIcon)
                {   // Из ресурсов (если есть .rc файл)
                    hIcon = LoadIcon(GetModuleHandle(NULL),
                                     MAKEINTRESOURCE(101));
                }
            
                if (hIcon)
                {   // WM_SETICON - сообщение Windows API
                    SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
                    SendMessage(hwnd, WM_SETICON, ICON_BIG  , (LPARAM)hIcon);
                }
            }
#endif
        }
    };
}
 
#endif // INSPECTOR_H


XLAT, но есть одна проблема. Положение задать нельзя (но можно менять ширину и высоту текстовой области). Текст будет появляться в верхнем левом углу. Проверь и скажи, нравится ли тебе текущая реализация? Если нет, то надо будет отказаться от OgreBites::TextBox и от GUI системы Trays, поскольку нет способа задать позицию в пикселях. Можно будет рассмотреть OverlayElements, а именно использовать элемент TextArea. Но TextArea вроде не будет таким красивым о объемным, как TextBox, ведь это просто оверлейный текст. И скорее всего придется еще сделать оверлейную панель в качество фона для текста. Так что, если текущий вариант в верхнем левом углу тебе нравится, то можно его и оставить. Преимущество текущего варианта еще в том, что его при желании можно даже скролить текст (сейчас это не реализовано, поскольку прокрутка мыши у тебя отвечает за другое), а у оверлейного варианта такой фичи нет, т.е. там просто текст на экране. Там можно выбрать только шрифт, размер, цвет, положение.
1
Just Do It!
 Аватар для XLAT
4219 / 2680 / 656
Регистрация: 23.09.2014
Сообщений: 9,235
Записей в блоге: 3
16.12.2025, 11:11  [ТС]
Цитата Сообщение от Royal_X Посмотреть сообщение
Вот последний вариант, выше был баг:
Текущий самый страшный баг,
который ОБЯЗАТЕЛЬНО нужно исправить:
ЗАМЕНИТЬ ШРИФТ НА ШРИФТ С ПОДДЕРЖКОЙ РУССКОГО ЯЗЫКА.

твой ui cейчас уже на гитхабе.
ВНИМАНИЕ, пжлста, если есть необходимость что-то исправить,
то отталкивайся от текущей гитхабовской версии:
ДЕЛАЙ ПУЛ ПЕРЕД ТЕМ КАК НАЧИНАТЬ ПРАВИТЬ.

Цитата Сообщение от Royal_X Посмотреть сообщение
Проверь и скажи, нравится ли тебе текущая реализация?
всё отлично - критиковать тя не буду, а то ощетинишься))

...

видел ли ты фильм «Легенда о пьяном мастере» (1994) с Джекки Чаном,
где он мастер пьяного стиля кунг-фу?


я поправил согласно ключевым положениям любого архитектурирования:
1. код модуля должен весь находиться в своём модуля - не размазываться по всем сырцам.
2. варнингов не должно быть вовсе.

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

но если ты не доволен - то внеси изменения, которые посчитаешь нужными.
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6313 / 3036 / 1053
Регистрация: 01.06.2021
Сообщений: 11,558
16.12.2025, 12:23
Цитата Сообщение от XLAT Посмотреть сообщение
Текущий самый страшный баг,
который ОБЯЗАТЕЛЬНО нужно исправить:
ЗАМЕНИТЬ ШРИФТ НА ШРИФТ С ПОДДЕРЖКОЙ РУССКОГО ЯЗЫКА.
OgreBites::TextBox не поддерживает кириллицу, поскольку нет возможности выбрать шрифт. Вообще, он не слишком кастомизируемый, поскольку цель именно в том, чтобы использовать готовый TextBox в стиле Ogre.

Решением этого бага является переход из TrayManager на OverlayManager. Но опять же, там такой красивый бокс уже не получится. Можно сделать какую-то прямоугольную панель с материалом и на ней вывести текст. В этот раз уже могу создать текст на любой позиции, можно выбрать любой шрифт*, размеры текста, цвет и пр. Но такого объемного бокса в стиле Ogre не будет.

* это означает, что можно добавить строчку
Code
1
code_points 1024-1279
в файле MyFont (это твой arial.ttf) и кириллица заработает

Что думаешь? Менять или будет на английском?
0
Just Do It!
 Аватар для XLAT
4219 / 2680 / 656
Регистрация: 23.09.2014
Сообщений: 9,235
Записей в блоге: 3
16.12.2025, 12:24  [ТС]
Цитата Сообщение от Royal_X Посмотреть сообщение
оскольку нет возможности выбрать шрифт
задача рискует стать блокирующей для текущей реализованной версии ui?
ок. нуно посмотреть, неспеша...


текущие задачи:
https://github.com/users/BDOTimer/projects/5
0
Just Do It!
 Аватар для XLAT
4219 / 2680 / 656
Регистрация: 23.09.2014
Сообщений: 9,235
Записей в блоге: 3
16.12.2025, 12:30  [ТС]
Цитата Сообщение от Royal_X Посмотреть сообщение
Что думаешь? Менять или будет на английском?
то есть реализацию(её отсутствие) важных моментов будет определять инструмент,
а не целевая аудитория, то есть потребитель?

очевидно,
что многоязычность - это обязаловка - мастхэв - мы же не секта! - верно?
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6313 / 3036 / 1053
Регистрация: 01.06.2021
Сообщений: 11,558
16.12.2025, 12:32
Цитата Сообщение от XLAT Посмотреть сообщение
верно?
тебе решать

  • если хочешь Ogre-стильный бокс, то нужно оставить английский
  • если устроит панелька с текстом, то могу менять
0
Just Do It!
 Аватар для XLAT
4219 / 2680 / 656
Регистрация: 23.09.2014
Сообщений: 9,235
Записей в блоге: 3
16.12.2025, 12:37  [ТС]
Цитата Сообщение от Royal_X Посмотреть сообщение
OgreBites::TextBox
а где сам шрифт от него лежит в ресурсах ?

Добавлено через 1 минуту
Цитата Сообщение от Royal_X Посмотреть сообщение
если хочешь Ogre-стильный бокс, то нужно оставить английский
если устроит панелька с текстом, то могу менять
если можно расширять в полноценный ui, то устроит,
но многоязычность мастхэв.
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6313 / 3036 / 1053
Регистрация: 01.06.2021
Сообщений: 11,558
16.12.2025, 12:40
Цитата Сообщение от XLAT Посмотреть сообщение
а где сам шрифт от него лежит в ресурсах ?
скорее всего он в бинарном виде, поскольку в ресурсах я не видел
1
Just Do It!
 Аватар для XLAT
4219 / 2680 / 656
Регистрация: 23.09.2014
Сообщений: 9,235
Записей в блоге: 3
16.12.2025, 12:40  [ТС]
Цитата Сообщение от Royal_X Посмотреть сообщение
OgreBites::TextBox не поддерживает кириллицу, поскольку нет возможности выбрать шрифт
Цитата Сообщение от ds
"Я добавил поддержку русского языка в ваш код. Основные изменения: ..."
https://chat.deepseek.com/share/ls1fxnqrh4lid3ulwo

это(выше) я не читал -
я ушёл заниматься корзиной ...
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6313 / 3036 / 1053
Регистрация: 01.06.2021
Сообщений: 11,558
16.12.2025, 12:54
Цитата Сообщение от XLAT Посмотреть сообщение
если можно расширять в полноценный ui, то устроит
дело в том, TrayManager не только позволяет создать красивый с нативным луком TextBox, но позволяет создать еще кнопки, слайдеры и прочие элементы и все в родном стиле и довольно доработанные.

OverlayManager это более низкоуровневая штука. То есть тут ты все сам лепишь из нуля говна и палок. Теоретически полноценный ui, как TrayManager, можно создать, если потратить столько времени, сколько сами разрабы, чего я точно не буду. Могу простенький UI. Панельку с текстом. Материал панельки и параметры текста можно настроить, но это будет все равно плоская панель и текст.

Добавлено через 2 минуты
Цитата Сообщение от XLAT Посмотреть сообщение
https://chat.deepseek.com/share/ls1fxnqrh4lid3ulwo
ты проверял, потому что я не думаю, что так можно решить проблему. ИИ просто выдает мусор

Добавлено через 7 минут
XLAT, я попробую копаться в сорцах и посмотрю, как можно решить проблему
1
Just Do It!
 Аватар для XLAT
4219 / 2680 / 656
Регистрация: 23.09.2014
Сообщений: 9,235
Записей в блоге: 3
16.12.2025, 13:24  [ТС]
Цитата Сообщение от Royal_X Посмотреть сообщение
я попробую копаться в сорцах и посмотрю, как можно решить проблему
я тупо надеюсь подменить шрифты в ресах ...

если у тя это получится - кричи громко.

в остальном пока всё ок.

Royal_X, ты проделал много работы - тя теперь на седня можно отдохнуть)

а я по прежнему занять колодцем(well)...
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6313 / 3036 / 1053
Регистрация: 01.06.2021
Сообщений: 11,558
16.12.2025, 19:51
XLAT, сделал пул.

https://github.com/BDOTimer/Ogre3d-Beginner/pulls

конфликтов с твоей главной веткой нет, можешь просто принять

***
Смысл изменений в том, что я добавил функционала в OgreTrays.h, чтобы получить доступ к защищенным членам класса. Дело в том, что TextBox состоит из множества оверлейных элементов. И вот, мне нужно было получить доступ к оверлейным элементам типа TextArea, которые уже имеют метод смены шрифта.
Иначе, пришлось бы создать не только кастомный TextBox, который наследуется от оригинального, но и кастомный TrayManager (и хз сработало бы вообще или нет). Короче, проще так. И уже хорошо, что не нужно заново собирать движок.
Аналогично, если нужно, можем скрыть вертикальный скролбар, потому что он сейчас бесполезен.

Добавлено через 3 часа 19 минут
XLAT, я еще прочел на гитхабе, что ты хочешь реализовать снег.

Я уже делал снег, там очень легко, поскольку в Media уже есть готовый эффект. Т.е. там уже грамотно настроен эффект.

https://mega.nz/file/YQxGQIxT#... hJbNU_hYlI

Снег в моей игре появляется с запозданием, поскольку эмиттер находится на высоте 200 метров. Пока первая партия доходит земли, протекает некоторое время. Можно, конечно, опустить эмиттер, но выглядит реалистичнее, когда он высоко.

C++
1
2
3
4
5
6
ParticleSystem* pSys = scnMgr->createParticleSystem("SnowParticleSystem", "Examples/Snow");
pSys->setDefaultDimensions(0.3f, 0.3f); // размер снежинок
pSys->getEmitter(0)->setParameter("time_to_live", "10"); // лучше менять параметры так, а не редактировать сам файл эффекта в Media
// таким же образом через код можно менять размеры бокса - эмиттера: высоту, ширину и глубину, но я оставил дефолтные
SceneNode* snowNode = scnMgr->getRootSceneNode()->createChildSceneNode("SnowNode");
snowNode->attachObject(pSys);
1
Just Do It!
 Аватар для XLAT
4219 / 2680 / 656
Регистрация: 23.09.2014
Сообщений: 9,235
Записей в блоге: 3
16.12.2025, 22:35  [ТС]
Цитата Сообщение от Royal_X Посмотреть сообщение
можешь просто принять
угу,

а у тя что там показывает?

Royal_X,
слушай, ты мя удивил сильно - ты сделал изменения только в одном файле!
браво!

Цитата Сообщение от Royal_X Посмотреть сообщение
Т.е. там уже грамотно настроен эффект.
ок, буду посмотреть.
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6313 / 3036 / 1053
Регистрация: 01.06.2021
Сообщений: 11,558
16.12.2025, 22:54
Цитата Сообщение от XLAT Посмотреть сообщение
а у тя что там показывает?
Когда загрузил снова из гитхаба, то тоже были иероглифы вместо кириллицы.

XLAT, но я нашел решение.


Пересохрани в Visual Studio файлик ui.h. Нажми сохранить как и потом выбери "Сохранить с кодировкой", потом измени кодировку. Сейчас там UTF-8 без подписи, а надо UTF-8 с подписью.

Видимо, github испортил кодировку, я там напрямую редактировал, а не загружал файл.


1
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6313 / 3036 / 1053
Регистрация: 01.06.2021
Сообщений: 11,558
16.12.2025, 23:42
XLAT, я еще один пул сделал. касается разархивирования assimp
0
Just Do It!
 Аватар для XLAT
4219 / 2680 / 656
Регистрация: 23.09.2014
Сообщений: 9,235
Записей в блоге: 3
17.12.2025, 00:14  [ТС]
Royal_X,
да, я починил сразу, спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.12.2025, 00:14

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

Давайте отыщем "Грааль"
Думаю, что в условиях нынешней экономической ситуации, эта тема будет актуальна. Предлагаю...

Давайте напишем соц.сеть. Объединяемся.
Короче давайте напишем двиг.соц.сети. Как это будет происходить? Открываем закрытый форум. В...

А давайте свою операционку забабахаем
Есть желающие операционку на полном энтузиазме делать?

Сюжет и название игрушки
Сюда постим по предложениям создания игрушки. Сюжету и названию.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
160
Ответ Создать тему
Новые блоги и статьи
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров В текущей версии модели успешно реализован ключевой механизм. . .
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям Реализованные компоненты: Механизм закисления почвы через протонную помпу Конкуренция между типами микориз pH как триггер сукцессии C/ P соотношение. . .
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
сукцессия 25. Хронология ошибок
anaschu 12.07.2026
# От 50-тонного гриба до устойчивого леса: хроника ошибок при построении модели вековой сукцессии микоризы ## О чём эта статья В процессе построения ОДУ-модели (система дифференциальных. . .
сукцессия 24. Промежуточное общее описание модели
anaschu 12.07.2026
Хендофф: модель АМ→ЭКМ сукцессии микоризы (ризосфера, 50 лет) Содержание проекта Симуляция вековой (50 лет) экологической сукцессии в почве леса Основные участники: АМ-гриб, ЭКМ-гриб,. . .
сукцессия 23. Более физиологичная физиология, более экологичная экология, более диффурные диффуры.
anaschu 12.07.2026
Что реально нашли и починили за эти 5 часов Правило Линдемана (КПД конверсии сахара в тело, kEff) — раньше 100% полученного углерода шло прямо в биомассу гриба; теперь только kEff=0. 5 (после. . .
сукцессия 22. От артефактов к физиологии: калибровка агентной модели грибной сукцессии для воспроизведения сезонной динамики и pH-плато
anaschu 11.07.2026
Аннотация В данной работе представлена калибровка агентной модели динамики грибных сообществ (fungal-succession), направленная на устранение нефизичных артефактов (коллапс биомассы, мгновенное. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru