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

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

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

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

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

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

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

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

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

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

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

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

Цитата Сообщение от XLAT Посмотреть сообщение
std::string textShort, std::string textLong
сколько там приблизительно будет символов в каждой строке? т.е. хочу узнать, что это за тексты?
1
Just Do It!
 Аватар для XLAT
4204 / 2662 / 654
Регистрация: 23.09.2014
Сообщений: 9,055
Записей в блоге: 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
6189 / 2891 / 1042
Регистрация: 01.06.2021
Сообщений: 10,602
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
4204 / 2662 / 654
Регистрация: 23.09.2014
Сообщений: 9,055
Записей в блоге: 3
15.12.2025, 23:26  [ТС]
Цитата Сообщение от Royal_X Посмотреть сообщение
как-то так получилось
ок.

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

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

если ты уверен, что так хорошо, то так тому и быть)
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6189 / 2891 / 1042
Регистрация: 01.06.2021
Сообщений: 10,602
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
4204 / 2662 / 654
Регистрация: 23.09.2014
Сообщений: 9,055
Записей в блоге: 3
16.12.2025, 11:11  [ТС]
Цитата Сообщение от Royal_X Посмотреть сообщение
Вот последний вариант, выше был баг:
Текущий самый страшный баг,
который ОБЯЗАТЕЛЬНО нужно исправить:
ЗАМЕНИТЬ ШРИФТ НА ШРИФТ С ПОДДЕРЖКОЙ РУССКОГО ЯЗЫКА.

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

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

...

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


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

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

но если ты не доволен - то внеси изменения, которые посчитаешь нужными.
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6189 / 2891 / 1042
Регистрация: 01.06.2021
Сообщений: 10,602
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
4204 / 2662 / 654
Регистрация: 23.09.2014
Сообщений: 9,055
Записей в блоге: 3
16.12.2025, 12:24  [ТС]
Цитата Сообщение от Royal_X Посмотреть сообщение
оскольку нет возможности выбрать шрифт
задача рискует стать блокирующей для текущей реализованной версии ui?
ок. нуно посмотреть, неспеша...


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

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

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

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

это(выше) я не читал -
я ушёл заниматься корзиной ...
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6189 / 2891 / 1042
Регистрация: 01.06.2021
Сообщений: 10,602
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
4204 / 2662 / 654
Регистрация: 23.09.2014
Сообщений: 9,055
Записей в блоге: 3
16.12.2025, 13:24  [ТС]
Цитата Сообщение от Royal_X Посмотреть сообщение
я попробую копаться в сорцах и посмотрю, как можно решить проблему
я тупо надеюсь подменить шрифты в ресах ...

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

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

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

а я по прежнему занять колодцем(well)...
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6189 / 2891 / 1042
Регистрация: 01.06.2021
Сообщений: 10,602
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
4204 / 2662 / 654
Регистрация: 23.09.2014
Сообщений: 9,055
Записей в блоге: 3
16.12.2025, 22:35  [ТС]
Цитата Сообщение от Royal_X Посмотреть сообщение
можешь просто принять
угу,

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

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

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

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


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

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


1
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6189 / 2891 / 1042
Регистрация: 01.06.2021
Сообщений: 10,602
16.12.2025, 23:42
XLAT, я еще один пул сделал. касается разархивирования assimp
0
Just Do It!
 Аватар для XLAT
4204 / 2662 / 654
Регистрация: 23.09.2014
Сообщений: 9,055
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 01.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 31.01.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru