Images not displayed using sprites in SFML
我已经使用C 17在Linux Mint 18.1上学习了SFML 2.3.2,以学习如何使用GUI。作为Hello World之后的第二个项目,我试图重现Snake,即旧手机已预装的游戏。到目前为止,大多数内容都可以使用,除了一些较小的例外,我稍后必须处理,其中一些是由于游戏尚未完全完成引起的。
请确保我理解正确,因为我以前从未使用过低级语言来处理GUI和图像。首先,将图像加载到纹理中,然后将纹理添加到sprite中,然后将该sprite绘制到窗口上?
该程序可以完美编译,正确初始化所有内容,并且运行时没有重大无法解释的问题。除非图像不显示。sprite在那里并以其默认的单色背景色显示,但不显示任何图像。
我该怎么做,以及如何解决?谢谢!
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 282 283 284 285 286 287 288 | // HEADERS #include <iostream> #include <SFML/Graphics.hpp> #include <SFML/Graphics/Color.hpp> #include <SFML/Graphics/Font.hpp> #include <SFML/Graphics/Image.hpp> #include <SFML/Graphics/Rect.hpp> #include <SFML/Graphics/Sprite.hpp> #include <SFML/Graphics/Texture.hpp> #include <SFML/System/String.hpp> #include <SFML/Window/Keyboard.hpp> // CREATE NEW FONT sf::Font create_font() { sf::Font f; bool id = f.loadFromFile("/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-B.ttf"); if (id == false) { std::cerr <<"Font:\\tCould not be loaded." << std::endl; } else { std::cerr <<"Font:\\tLoaded successfully." << std::endl; } return f; } // CREATE NEW SPRITE USING TEXTURE, GIVEN ARE PATH WITH COORDINATES AND DIMENSIONS sf::Sprite load_img(std::string path, long x, long y, long w, long h) { sf::Texture t; bool id = t.loadFromFile(path); if (id == false) { std::cerr <<"Texture:\\t" << path <<"\\tFailed to load." << std::endl; } else { std::cerr <<"Texture:\\t" << path <<"\\tLoaded successfully." << std::endl; } sf::Sprite s(t); s.setTextureRect(sf::IntRect((int)x, (int)y, (int)w, (int)h)); s.setPosition(x, y); return s; } // MAIN FUNCTION int main() { // DECLARING/DEFINING VARIABLES unsigned long window_width = 512; unsigned long window_height = 512; unsigned long score = 0; unsigned long head_old_position_x, head_old_position_y; std::string title ="Snek"; std::string wdir ="/home/kate/Documents/coding/snek/"; // WINDOW sf::RenderWindow window(sf::VideoMode(window_width, window_height), title); window.setFramerateLimit(60); // SPRITES sf::Sprite background = load_img(wdir +"img/background.png", 0, 0, 512, 512); sf::Sprite head = load_img(wdir +"img/head.png", 47, 39, 8, 8); sf::Sprite body = load_img(wdir +"img/body.png", 39, 39, 8, 8); sf::Sprite poison = load_img(wdir +"img/poison.png", 119, 119, 8, 8); sf::Sprite trap = load_img(wdir +"img/trap.png", 159, 159, 8, 8); sf::Sprite candy = load_img(wdir +"img/candy.png", 199, 199, 8, 8); // FONT sf::Font font = create_font(); // TEXT sf::Text score_display(title, font, 20); sc// HEADERS #include <iostream> #include <SFML/Graphics.hpp> #include <SFML/Graphics/Color.hpp> #include <SFML/Graphics/Font.hpp> #include <SFML/Graphics/Image.hpp> #include <SFML/Graphics/Rect.hpp> #include <SFML/Graphics/Sprite.hpp> #include <SFML/Graphics/Texture.hpp> #include <SFML/System/String.hpp> #include <SFML/Window/Keyboard.hpp> // CREATE NEW FONT sf::Font create_font() { sf::Font f; bool id = f.loadFromFile("/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-B.ttf"); if (id == false) { std::cerr <<"Font:\\tCould not be loaded." << std::endl; } else { std::cerr <<"Font:\\tLoaded successfully." << std::endl; } return f; } // CREATE NEW SPRITE USING TEXTURE, GIVEN ARE PATH WITH COORDINATES AND DIMENSIONS sf::Sprite load_img(std::string path, long x, long y, long w, long h) { sf::Texture t; bool id = t.loadFromFile(path); if (id == false) { std::cerr <<"Texture:\\t" << path <<"\\tFailed to load." << std::endl; } else { std::cerr <<"Texture:\\t" << path <<"\\tLoaded successfully." << std::endl; } sf::Sprite s(t); s.setTextureRect(sf::IntRect((int)x, (int)y, (int)w, (int)h)); s.setPosition(x, y); return s; } // MAIN FUNCTION int main() { // DECLARING/DEFINING VARIABLES unsigned long window_width = 512; unsigned long window_height = 512; unsigned long score = 0; unsigned long head_old_position_x, head_old_position_y; std::string title ="Snek"; std::string wdir ="/home/kate/Documents/coding/snek/"; // WINDOW sf::RenderWindow window(sf::VideoMode(window_width, window_height), title); window.setFramerateLimit(60); // SPRITES sf::Sprite background = load_img(wdir +"/img/background.png", 0, 0, 512, 512); sf::Sprite head = load_img(wdir +"/img/head.png", 47, 39, 8, 8); sf::Sprite body = load_img(wdir +"/img/body.png", 39, 39, 8, 8); sf::Sprite poison = load_img(wdir +"/img/poison.png", 119, 119, 8, 8); sf::Sprite trap = load_img(wdir +"/img/trap.png", 159, 159, 8, 8); sf::Sprite candy = load_img(wdir +"/img/candy.png", 199, 199, 8, 8); // FONT sf::Font font = create_font(); // TEXT sf::Text score_display(title, font, 20); score_display.setString(std::to_string(score)); score_display.setPosition(5, 5); // LOOP while (window.isOpen()) { sf::Event event; while ( window.pollEvent(event)) { if (event.type == sf::Event::Closed) { window.close(); } head_old_position_x = head.getPosition().x; head_old_position_y = head.getPosition().y; // MOVEMENT BASED ON KEYBOARD INPUT if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) { head.setPosition(head.getPosition().x - 8, head.getPosition().y); body.setPosition(head_old_position_x, head_old_position_y); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) { head.setPosition(head.getPosition().x, head.getPosition().y - 8); body.setPosition(head_old_position_x, head_old_position_y); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) { head.setPosition(head.getPosition().x + 8, head.getPosition().y); body.setPosition(head_old_position_x, head_old_position_y); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) { head.setPosition(head.getPosition().x, head.getPosition().y + 8); body.setPosition(head_old_position_x, head_old_position_y); } if (body.getPosition().x == candy.getPosition().x && body.getPosition().y == candy.getPosition().y) { score ++; score_display.setString(std::to_string(score)); } // REFRESH WINDOW window.clear(); window.draw(background); window.draw(head); window.draw(body); window.draw(poison); window.draw(trap); window.draw(candy); window.draw(score_display); window.display(); } } return 0; } ore_display.setString(std::to_string(score)); score_display.setPosition(5, 5); // LOOP while (window.isOpen()) { sf::Event event; while ( window.pollEvent(event)) { if (event.type == sf::Event::Closed) { window.close(); } head_old_position_x = head.getPosition().x; head_old_position_y = head.getPosition().y; // MOVEMENT BASED ON KEYBOARD INPUT if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) { head.setPosition(head.getPosition().x - 8, head.getPosition().y); body.setPosition(head_old_position_x, head_old_position_y); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) { head.setPosition(head.getPosition().x, head.getPosition().y - 8); body.setPosition(head_old_position_x, head_old_position_y); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) { head.setPosition(head.getPosition().x + 8, head.getPosition().y); body.setPosition(head_old_position_x, head_old_position_y); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) { head.setPosition(head.getPosition().x, head.getPosition().y + 8); body.setPosition(head_old_position_x, head_old_position_y); } if (body.getPosition().x == candy.getPosition().x && body.getPosition().y == candy.getPosition().y) { score ++; score_display.setString(std::to_string(score)); } // REFRESH WINDOW window.clear(); window.draw(background); window.draw(head); window.draw(body); window.draw(poison); window.draw(trap); window.draw(candy); window.draw(score_display); window.display(); } } return 0; } |
好吧,我想我已经知道了。
可能未显示任何内容,因为事件循环中包含所有绘图内容
尝试将这些内容放入
您已经丢失了对纹理的引用。在您的情况下,纹理是
在任何sprite使用它时,应保持纹理加载并可用。
我建议您阅读SFML教程的这一部分,其中解释了此问题。
您的纹理超出范围,请参阅对象何时"超出范围"?更多细节。您可以在load_img函数中声明纹理,但是在退出load_img并返回sprite之后,将删除
因此这是一个更新的函数,您可以在其中将纹理存储在load_img函数之外,并通过引用将其传递。仅显示相关部分。首先,将纹理传递给load_img函数。删除
1 2 3 4 5 | sf::Sprite load_img(std::string path, long x, long y, long w, long h, sf::Texture& t) { bool id = t.loadFromFile(path); [...] } |
声明纹理并将其传递给load_img函数。
1 2 | sf::Texture headtexture; sf::Sprite head = load_img(wdir +"img/head.png", 47, 39, 8, 8, headtexture); |
如果对所有sprite进行此操作,它将起作用并正确显示图像/sprite。
编辑2017年9月25日
根据评论,这是一个不带功能的最小工作示例:
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 | // HEADERS #include <iostream> #include <SFML/Graphics.hpp> #include <SFML/Graphics/Color.hpp> #include <SFML/Graphics/Font.hpp> #include <SFML/Graphics/Image.hpp> #include <SFML/Graphics/Rect.hpp> #include <SFML/Graphics/Sprite.hpp> #include <SFML/Graphics/Texture.hpp> #include <SFML/System/String.hpp> #include <SFML/Window/Keyboard.hpp> // MAIN FUNCTION int main() { // DECLARING/DEFINING VARIABLES unsigned long window_width = 512; unsigned long window_height = 512; std::string title ="Snek"; std::string wdir ="/home/kate/Documents/coding/snek/"; // WINDOW sf::RenderWindow window(sf::VideoMode(window_width, window_height), title); window.setFramerateLimit(60); // SPRITES sf::Texture headtexture; sf::Sprite head; headtexture.loadFromFile(wdir +"img/head.png"); head.setTexture(headtexture); head.setTextureRect(sf::IntRect(47, 39, 8, 8)); head.setPosition(30, 30); // LOOP while (window.isOpen()) { sf::Event event; while ( window.pollEvent(event)) { if (event.type == sf::Event::Closed) { window.close(); } // REFRESH WINDOW window.clear(); window.draw(head); window.display(); } } return 0; } |