SFML и C++ Уроки \ Разработка игр › Форумы › SFML Graphics › Не загружаются текстуры после перехода с меню в игру. › Ответ в теме: Не загружаются текстуры после перехода с меню в игру.
main.cpp:
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 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
#include <SFML/Graphics.hpp> #include <SFML/OpenGL.hpp> #include <GL/glu.h> #pragma comment(lib,"glu32.lib") #include <iostream> #include "StartMenu.h" #include "helpFile.hpp" using namespace sf; float angleX, angleY; // Углы поворота камеры от 360 по гориз. и от -90 до 90 по вертикали class Player { public: float x, y, z; //координаты игрока float dx, dy, dz; //смещение float w, h, d; // ширина, высота, длина bool onGround; float speed; Player(float x0, float y0, float z0) { x = x0; y = y0; z = z0; dx = 0; dy = 0; dz = 0; w = 5; h = 20; d = 5; speed = 5; // половина высоты, ширины и длины (удобнее работать) onGround = false; } // проверка на столкновение при смещении void update(float time) { if (!onGround) dy -= 1.5*time; onGround = 0; // смещаемься по x - проверяем на столкновение x += dx*time; collision(dx, 0, 0); // смещаемься по y - проверяем на столкновение y += dy*time; collision(0, dy, 0); // смещаемься по z - проверяем на столкновение z += dz*time; collision(0, 0, dz); dx = dz = 0; } //функция столкновения с каждым предметом void collision(float Dx, float Dy, float Dz) { //цыкл по нужным клеточкам x,y,z for (int X = (x - w) / size; X<(x + w) / size; X++) for (int Y = (y - h) / size; Y<(y + h) / size; Y++) for (int Z = (z - d) / size; Z<(z + d) / size; Z++) //если столкнулись, разрешаем столкновение (отдельно по x,y,z) if (check(X, Y, Z)) { if (Dx>0) x = X*size - w; if (Dx<0) x = X*size + size + w; if (Dy>0) y = Y*size - h; if (Dy<0) { y = Y*size + size + h; onGround = true; dy = 0; } if (Dz>0) z = Z*size - d; if (Dz<0) z = Z*size + size + d; } } // движение и прижок void keyboard() { if (Keyboard::isKeyPressed(Keyboard::Space)) if (onGround) { onGround = false; dy = 12; }; if (Keyboard::isKeyPressed(Keyboard::W)) { //смещаемься в данном направлении со скоросью speed dx = -sin(angleX / 180 * PI) * speed; dz = -cos(angleX / 180 * PI) * speed; } if (Keyboard::isKeyPressed(Keyboard::S)) { dx = sin(angleX / 180 * PI) * speed; dz = cos(angleX / 180 * PI) * speed; } if (Keyboard::isKeyPressed(Keyboard::D)) { dx = sin((angleX + 90) / 180 * PI) * speed; dz = cos((angleX + 90) / 180 * PI) * speed; } if (Keyboard::isKeyPressed(Keyboard::A)) { dx = sin((angleX - 90) / 180 * PI) * speed; dz = cos((angleX - 90) / 180 * PI) * speed; } } }; bool startGame() { RenderWindow window(VideoMode(1366, 768), "Minecraft C++", sf::Style::Default, sf::ContextSettings(24)); menu(window);//вызов меню ShowCursor(FALSE); //отключаем курсов в окне //волшебные слова для иннициализации OpenGl glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glClearDepth(1.f); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(90.f, 1.f, 1.f, 2000.f); glEnable(GL_TEXTURE_2D); ////карта высот//// Image im; im.loadFromFile("resources/heightmap1.png"); //величина карты в зависимости от цвета for (int x = 0; x<10; x++) // от 0 до 256 for (int z = 0; z<10; z++) { int c = im.getPixel(x, z).r / 15; for (int y = 0; y<c; y++) if (y>c - 3) mass[x][y][z] = 1; } ///////текстуры/////// Texture t; t.loadFromFile("resources/cursor.png"); Sprite s(t); s.setOrigin(8, 8); s.setPosition(683, 384); // Установление текстур по типу SkyBox GLuint skybox[6]; skybox[0] = LoadTexture("resources/skybox/front.png"); skybox[1] = LoadTexture("resources/skybox/back.png"); skybox[2] = LoadTexture("resources/skybox/left.png"); skybox[3] = LoadTexture("resources/skybox/right.png"); skybox[4] = LoadTexture("resources/skybox/bottom.png"); skybox[5] = LoadTexture("resources/skybox/top.png"); // Установление текстур для квадратов GLuint box[6]; box[0] = LoadTexture("resources/grassBox/side.jpg"); box[1] = LoadTexture("resources/grassBox/side.jpg"); box[2] = LoadTexture("resources/grassBox/side.jpg"); box[3] = LoadTexture("resources/grassBox/side.jpg"); box[4] = LoadTexture("resources/grassBox/bottom.jpg"); box[5] = LoadTexture("resources/grassBox/top.jpg"); ////////////////////////// Clock clock; bool mLeft = 0, mRight = 0; // переменные для нажатия кнопок мыши Player p(100, 200, 100); // координаты плеера //////основной цикл///////// while (window.isOpen()) { // привязка по времени float time = clock.getElapsedTime().asMilliseconds(); clock.restart(); time = time / 50; if (time>3) time = 3; Event event; while (window.pollEvent(event)) { if (event.type == Event::Closed) window.close(); if ((event.type == Event::KeyPressed) && (event.key.code == Keyboard::Escape)) window.close(); if (event.type == Event::MouseButtonPressed) { // Если клавиша на мыши нажата, то переменная получает 1 - т.е. True if (event.key.code == Mouse::Right) mRight = 1; if (event.key.code == Mouse::Left) mLeft = 1; } } glClear(GL_DEPTH_BUFFER_BIT); // очищаем экран p.keyboard(); p.update(time); // нахождения отклонения мыши от центра экрана POINT mousexy; // переменная для считывания GetCursorPos(&mousexy); // считывание кординат int xt = window.getPosition().x + 683; int yt = window.getPosition().y + 384; angleX += (xt - mousexy.x) / 4; //4 — чувствительность angleY += (yt - mousexy.y) / 4; //ограничения вращения камеры if (angleY<-89.0) { angleY = -89.0; } if (angleY>89.0) { angleY = 89.0; } SetCursorPos(xt, yt); ////---------------------- if (mRight || mLeft) { // Если переменные True, то фиксируем начальные позиции мыши float x = p.x; float y = p.y + p.h / 2; float z = p.z; int X, Y, Z, oldX, oldY, oldZ; int dist = 0; // Дистанция создания кубиков while (dist<120) // радиус действия { dist++; x += -sin(angleX / 180 * PI); X = x / size; y += tan(angleY / 180 * PI); Y = y / size; z += -cos(angleX / 180 * PI); Z = z / size; // проверка на столкновение. Если столкнулись и нажата клавиша, то if (check(X, Y, Z)) if (mLeft) { mass[X][Y][Z] = 0; break; } else { mass[oldX][oldY][oldZ] = 1; break; } oldX = X; oldY = Y; oldZ = Z; } } mLeft = mRight = 0; glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // задаем с какой точки будем смотреть и куда gluLookAt(p.x, p.y + p.h / 2, p.z, p.x - sin(angleX / 180 * PI), p.y + p.h / 2 + (tan(angleY / 180 * PI)), p.z - cos(angleX / 180 * PI), 0, 1, 0); //////////рисуем боксы/////// int R = 50; //радиус видимости int X = p.x / size; int Y = p.y / size; int Z = p.z / size; for (int x = X - R; x<X + R; x++) for (int y = 0; y<25; y++) for (int z = Z - R; z<Z + R; z++) { if (!check(x, y, z)) continue; // координаты отрисовки glTranslatef(size*x + size / 2, size*y + size / 2, size*z + size / 2); createBox(box, size / 2); // после возвращаемся в исходную точку glTranslatef(-size*x - size / 2, -size*y - size / 2, -size*z - size / 2); } //создание коробки с фоном - отображение glTranslatef(p.x, p.y, p.z); //координаты для выявления центра createBox(skybox, 1000); //размер коробки glTranslatef(-p.x, -p.y, -p.z); window.pushGLStates(); window.draw(s); //рисуем курсор window.popGLStates(); window.display(); if (Keyboard::isKeyPressed(Keyboard::Tab)) { return true; }//если таб, то перезагружаем игру if (Keyboard::isKeyPressed(Keyboard::Escape)) { return false; }//если эскейп, то выходим из игры } return 0; } void gameRunning() {//ф-ция перезагружает игру , если это необходимо if (startGame()) { gameRunning(); }////если startGame() == true, то вызываем занова ф-цию isGameRunning, которая в свою очередь опять вызывает startGame() } int main() { gameRunning();//запускаем процесс игры return 0; } |
StartMenu.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 |
#pragma once #include <SFML/Graphics.hpp> #include <SFML/OpenGL.hpp> #include <GL/glu.h> #pragma comment(lib,"glu32.lib") #include <iostream> using namespace sf; void menu(RenderWindow & window) { ShowCursor(TRUE); Texture menuTexture1, menuTexture2, menuTexture3, aboutTexture, menuBackground; menuTexture1.loadFromFile("resources/StartMenu/111.png"); menuTexture2.loadFromFile("resources/StartMenu/222.png"); menuTexture3.loadFromFile("resources/StartMenu/333.png"); //aboutTexture.loadFromFile("resources/StartMenu/112.png"); menuBackground.loadFromFile("resources/StartMenu/background.png"); Sprite menu1(menuTexture1), menu2(menuTexture2), menu3(menuTexture3), about(aboutTexture), menuBg(menuBackground); bool isMenu = 1; int menuNum = 0; menu1.setPosition(420, 400); menu2.setPosition(420, 470); menu3.setPosition(420, 535); menuBg.setPosition(0, 0); //////////////////////////////МЕНЮ/////////////////// while (isMenu) { menu1.setColor(Color::White); menu2.setColor(Color::White); menu3.setColor(Color::White); menuNum = 0; window.clear(Color(129, 181, 221)); if (IntRect(420, 400, 500, 70).contains(Mouse::getPosition(window))) { menu1.setColor(Color::Green); menuNum = 1; } if (IntRect(420, 470, 500, 70).contains(Mouse::getPosition(window))) { menu2.setColor(Color::Green); menuNum = 2; } if (IntRect(520, 535, 270, 70).contains(Mouse::getPosition(window))) { menu3.setColor(Color::Green); menuNum = 3; } if (Mouse::isButtonPressed(Mouse::Left)) { if (menuNum == 1) isMenu = false;//если нажали первую кнопку, то выходим из меню if (menuNum == 2) { window.draw(about); window.display(); while (!Keyboard::isKeyPressed(Keyboard::Escape)); } if (menuNum == 3) { window.close(); isMenu = false; } } window.draw(menuBg); window.draw(menu1); window.draw(menu2); window.draw(menu3); window.display(); } //////////////////////////////////////////////////// } |
и helpFile.hpp (отрысовка кубиков)
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 |
#pragma once #ifndef HELPFILE_H #define HELPFILE_H #include <SFML/Graphics.hpp> #include <SFML/OpenGL.hpp> #include <GL/glu.h> #pragma comment(lib,"glu32.lib") #include <iostream> using namespace sf; #define GL_CLAMP_TO_EDGE 0x812F // чтобы понял, что такое GL_CLAMP_TO_EDGE const float PI = 3.141592653; bool mass[1000][1000][1000]; // массив с генерации карты float size = 20.f; // принимаем путь к картинке по name GLuint LoadTexture(String name) { Image image; if (!image.loadFromFile(name)) return EXIT_FAILURE; image.flipVertically(); // переварачивает (ибо у OpenGl 0.0 внизу, а у SFML - сверху) // загрузка текстуры в OpenGL // Сначала загружаем картинку в программу GLuint texture = 0; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); //затем передаем её OpenGl //записываем переменную image в texture, с которой уже работает OpenGL gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, image.getSize().x, image.getSize().y, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); //убираем разрез/отсуп между текстурой/гранями skybox glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); return texture; } //window.pushGLStates(); //window.draw(background); //window.popGLStates(); // рисование (принимает массив текстур и размер кубика) void createBox(GLuint skybox[], float size) { glBindTexture(GL_TEXTURE_2D, skybox[0]); // включаем текстуру glBegin(GL_QUADS); // запускаем рисовани //front glTexCoord2f(0, 0); glVertex3f(-size, -size, -size); glTexCoord2f(1, 0); glVertex3f(size, -size, -size); glTexCoord2f(1, 1); glVertex3f(size, size, -size); glTexCoord2f(0, 1); glVertex3f(-size, size, -size); glEnd(); glBindTexture(GL_TEXTURE_2D, skybox[1]); glBegin(GL_QUADS); //back glTexCoord2f(0, 0); glVertex3f(size, -size, size); glTexCoord2f(1, 0); glVertex3f(-size, -size, size); glTexCoord2f(1, 1); glVertex3f(-size, size, size); glTexCoord2f(0, 1); glVertex3f(size, size, size); glEnd(); glBindTexture(GL_TEXTURE_2D, skybox[2]); glBegin(GL_QUADS); //left glTexCoord2f(0, 0); glVertex3f(-size, -size, size); glTexCoord2f(1, 0); glVertex3f(-size, -size, -size); glTexCoord2f(1, 1); glVertex3f(-size, size, -size); glTexCoord2f(0, 1); glVertex3f(-size, size, size); glEnd(); glBindTexture(GL_TEXTURE_2D, skybox[3]); glBegin(GL_QUADS); //right glTexCoord2f(0, 0); glVertex3f(size, -size, -size); glTexCoord2f(1, 0); glVertex3f(size, -size, size); glTexCoord2f(1, 1); glVertex3f(size, size, size); glTexCoord2f(0, 1); glVertex3f(size, size, -size); glEnd(); glBindTexture(GL_TEXTURE_2D, skybox[4]); glBegin(GL_QUADS); //bottom glTexCoord2f(0, 0); glVertex3f(-size, -size, size); glTexCoord2f(1, 0); glVertex3f(size, -size, size); glTexCoord2f(1, 1); glVertex3f(size, -size, -size); glTexCoord2f(0, 1); glVertex3f(-size, -size, -size); glEnd(); glBindTexture(GL_TEXTURE_2D, skybox[5]); glBegin(GL_QUADS); //top glTexCoord2f(0, 0); glVertex3f(-size, size, -size); glTexCoord2f(1, 0); glVertex3f(size, size, -size); glTexCoord2f(1, 1); glVertex3f(size, size, size); glTexCoord2f(0, 1); glVertex3f(-size, size, size); glEnd(); } //вспомогательная функция, находимься ли мы в нутри массива координат или нет //чтобы избежать ошибок передвижения bool check(int x, int y, int z) { if ((x<0) || (x >= 1000) || (y<0) || (y >= 1000) || (z<0) || (z >= 1000)) return false; return mass[x][y][z]; } #endif HELPFILE_H#pragma once |
Шел на Вашим урокам, за что огромное спасибо, но вот такая беда получилась)