SFML и C++ Уроки \ Разработка игр › Форумы › SFML Graphics › Вертикальные белые полосы
В этой теме 5 ответов, 3 участника, последнее обновление KindRedSand 5 года/лет, 3 мес. назад.
-
АвторСообщения
-
Здравствуйте! Нужна помощь…
В общем, как и все, пишу свою игру. Но столкнулся с одной проблемой: прорисовка карты иногда пролагивает, а именно периодически появляются вертикальные белые полосы.
Я проверял с другими текстурами и всё нормально работает, т.е. никаких пролагиваний. А с этими которые я решил поставить, что-то не так.
Примечаение: (если что, цветовую маску тоже накладывал) image.createMaskFromColor(Color(255, 0, 255));
Пытался в фотошопе обработать, сохранять как для web т.е. чтобы объём картинки сжать – не помогло. Я знаю, кто-то скажет: “да что ты прицепился к этим текстурам – возьми другие”. Мой ответ: Я не привык сдаваться и всегда стою на своём!
Буду рад, если кто поможет…
Вот код main.cpp
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204#include<SFML\Graphics.hpp>#include"view.h"using namespace sf;#define HEIGHT_MAP 15#define WIDTH_MAP 44String TileMap[WIDTH_MAP] = {"00000000000000000000000000000000000000000000","0 0","0 a a #*+?- 0","0 0","0 cccc ccc 0","0 a I a I a 0","0 d I d i d0","0ccccccc i ccccccc I ccccc0","0 I a I I I a I 0","0 i I i i i 0","0 I cccccc I I cccccc I 0","0B I I I I I I 0","012 i d i i 56 i i i 0","034b I !@$% I j I 78 I I I 0","00000000000000000000000000000000000000000000"};class Player{public:float x, y, dx, dy, speed, currentFrame;int w, h, health;bool life, onGround;enum stateObject { left, right, up, down, jump, stay } state;Texture texture;Sprite sprite;Player(Image &image, float x, float y, int w, int h){this->x = x; this->y = y;this->w = w; this->h = h;speed = 0;currentFrame = 0;dx = 0; dy = 0;health = 100;state = stay;life = true;onGround = false;texture.loadFromImage(image);sprite.setTexture(texture);sprite.setOrigin(w / 2, h / 2);sprite.setTextureRect(IntRect(0, 191, w, h));sprite.setPosition(x + w / 2, y + h / 2);}void control(float time){if (Keyboard::isKeyPressed(Keyboard::Left)) {state = left; speed = 0.1;currentFrame += 0.005*time;if (currentFrame > 6) currentFrame -= 6;sprite.setTextureRect(IntRect(40 * int(currentFrame) + 40, 246, -40, 46));}if (Keyboard::isKeyPressed(Keyboard::Right)) {state = right; speed = 0.1;currentFrame += 0.005*time;if (currentFrame > 6) currentFrame -= 6;sprite.setTextureRect(IntRect(40 * int(currentFrame), 246, 40, 46));}if (Keyboard::isKeyPressed(Keyboard::Space) && onGround) {state = jump; dy = -0.4; onGround = false;}}void checkCollisionWithMap(float dx, float dy){for(int i = y / 32; i < (y + h)/32; i++)for (int j = x / 32; j < (x + w) / 32; j++){if (TileMap[i][j] == '0' || TileMap[i][j] == 'c'){if (dy > 0) { y = i * 32 - h; this->dy = 0; onGround = true; }if (dy < 0) { y = i * 32 + 32; this->dy = 0; }if (dx > 0) { x = j * 32 - w; }if (dx < 0) { x = j * 32 + 32; }}if (TileMap[i][j] == 'a')TileMap[i][j] = ' ';}}void Update(float time){control(time);switch (state){case left: dx = -speed; break;case right: dx = speed; break;}onGround = false;x += dx*time;checkCollisionWithMap(dx, 0);y += dy*time;checkCollisionWithMap(0, dy);speed = 0;sprite.setPosition(x + w / 2, y + h / 2);if (health <= 0) { life = false; speed = 0; health = 0; }if (life) setPlayerCoordinateForView(x + w / 2, y + h / 2);dy += 0.0006*time;}};int main(){RenderWindow window(VideoMode(640, 480), "Game #5", Style::Close);camera.reset(FloatRect(0, 0, 640, 480));Image heroImage;heroImage.loadFromFile("images/fang.png");Image mapImage;mapImage.loadFromFile("images/industrialMap.png");mapImage.createMaskFromColor(Color(255, 0, 255));Texture mapTexture;mapTexture.loadFromImage(mapImage);Sprite s_map;s_map.setTexture(mapTexture);Player hero(heroImage, 100, 100, 41, 46);Clock clock;while (window.isOpen()){float time = clock.getElapsedTime().asMicroseconds();clock.restart();time /= 500;Event event;while (window.pollEvent(event)){if (event.type == Event::Closed)window.close();if (event.type == Event::KeyPressed)if (event.key.code == Keyboard::Escape)window.close();}hero.Update(time);window.setView(camera);window.clear();for (int i = 0; i < HEIGHT_MAP; i++)for (int j = 0; j < WIDTH_MAP; j++){if (TileMap[i][j] == ' ') s_map.setTextureRect(IntRect(512, 192, 32, 32));if (TileMap[i][j] == '0') s_map.setTextureRect(IntRect(384, 96, 32, 32));if (TileMap[i][j] == 'c') s_map.setTextureRect(IntRect(480, 192, 32, 32));if (TileMap[i][j] == '1') s_map.setTextureRect(IntRect(64, 96, 32, 32));if (TileMap[i][j] == '2') s_map.setTextureRect(IntRect(96, 96, 32, 32));if (TileMap[i][j] == '3') s_map.setTextureRect(IntRect(224, 96, 32, 32));if (TileMap[i][j] == '4') s_map.setTextureRect(IntRect(256, 96, 32, 32));if (TileMap[i][j] == '5') s_map.setTextureRect(IntRect(128, 128, 32, 32));if (TileMap[i][j] == '6') s_map.setTextureRect(IntRect(160, 128, 32, 32));if (TileMap[i][j] == '7') s_map.setTextureRect(IntRect(288, 128, 32, 32));if (TileMap[i][j] == '8') s_map.setTextureRect(IntRect(320, 128, 32, 32));if (TileMap[i][j] == 'b') s_map.setTextureRect(IntRect(448, 224, 32, 32));if (TileMap[i][j] == 'B') s_map.setTextureRect(IntRect(416, 256, 32, 32));if (TileMap[i][j] == 'd') s_map.setTextureRect(IntRect(0, 256, 32, 32));if (TileMap[i][j] == '!') s_map.setTextureRect(IntRect(0, 224, 32, 32));if (TileMap[i][j] == '@') s_map.setTextureRect(IntRect(32, 224, 32, 32));if (TileMap[i][j] == '$') s_map.setTextureRect(IntRect(64, 224, 32, 32));if (TileMap[i][j] == '%') s_map.setTextureRect(IntRect(96, 224, 32, 32));if (TileMap[i][j] == '#') s_map.setTextureRect(IntRect(160, 64, 32, 32));if (TileMap[i][j] == '*') s_map.setTextureRect(IntRect(192, 64, 32, 32));if (TileMap[i][j] == '+') s_map.setTextureRect(IntRect(224, 64, 32, 32));if (TileMap[i][j] == '?') s_map.setTextureRect(IntRect(256, 64, 32, 32));if (TileMap[i][j] == '-') s_map.setTextureRect(IntRect(352, 64, 32, 32));if (TileMap[i][j] == 'i') s_map.setTextureRect(IntRect(288, 96, 32, 32));if (TileMap[i][j] == 'j') s_map.setTextureRect(IntRect(384, 256, 32, 32));if (TileMap[i][j] == 'I') s_map.setTextureRect(IntRect(288, 64, 32, 32));if (TileMap[i][j] == 'a') s_map.setTextureRect(IntRect(0, 64, 32, 32));s_map.setPosition(j * 32, i * 32);window.draw(s_map);}window.draw(hero.sprite);window.display();}return 0;}view.h
C++12345678910111213141516171819202122#pragma once#ifndef CAMERA_H#define CAMERA_H#include<SFML\Graphics.hpp>using namespace sf;View camera;void setPlayerCoordinateForView(float x, float y){float tempX = x, tempY = y;if (x < 320) tempX = 320;if (x > 1090) tempX = 1090;if (y < 240) tempY = 240;if (y > 240) tempY = 240;camera.setCenter(tempX, tempY);}#endifВложения:
You must be logged in to view attached files.Вот примечания:
Вложения:
You must be logged in to view attached files.Дело в том, что на каждом кадре игры ты в цикле заново присваиваешь единственному(!) спрайту TextureRect, после чего сразу же его отрисовываешь. Гораздо правильнее было бы создать массив этих спрайтов, присвоить им TextureRect’ы и позицию до главного цикла while, а во время выполнения приложения просто отрисовывать каждый спрайт по очереди.
Я попробовал данный способ, но ничего не сработало. Как я уже сказал: это дело в картинке! С ДРУГИМИ картинками всё нормально работает. Может нужно как-то обработать картинку… Перепробовал разные способы: сжимал в объёме, сохраняя в PhotoShop как для Web и т.д. Но мне нужны именно эти текстуры. Посоветуйте как обработать изображение, чтобы не было пролагиваний…
Вот реализованный код map.h
C++1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071#pragma once#ifndef MAP_H#define MAP_H#include<SFML\Graphics.hpp>using namespace sf;#define HEIGHT_MAP 15#define WIDTH_MAP 44String TileMap[WIDTH_MAP] = {"00000000000000000000000000000000000000000000","0 0","0 0","0 0","0 0","0 0","0 0","0 0","0 0","0 0","0 0","0 0","0 0","0 0","00000000000000000000000000000000000000000000"};Sprite mapRender[HEIGHT_MAP][WIDTH_MAP];Vector2i mapCoordinate[HEIGHT_MAP][WIDTH_MAP];class Map{public:Texture texture;Sprite sprite;Map(Image &image){image.createMaskFromColor(Color(255, 0, 255));texture.loadFromImage(image);sprite.setTexture(texture);}void render(){for (int i = 0; i < HEIGHT_MAP; i++)for (int j = 0; j < WIDTH_MAP; j++){Vector2i coordinate(j * 32, i * 32);mapCoordinate[i][j] = coordinate;if (TileMap[i][j] == ' ') { sprite.setTextureRect(IntRect(512, 192, 32, 32)); mapRender[i][j] = sprite; }if (TileMap[i][j] == '0') { sprite.setTextureRect(IntRect(384, 96, 32, 32)); mapRender[i][j] = sprite; }}}void draw(RenderWindow &window){for (int i = 0; i < HEIGHT_MAP; i++)for (int j = 0; j < WIDTH_MAP; j++){mapRender[i][j].setPosition(mapCoordinate[i][j].x, mapCoordinate[i][j].y);window.draw(mapRender[i][j]);}}};#endifЕсли кто-то всё таки увидит данный пост, то решение нашлось: просто координаты камеры приводить к типу int. Не знаю может это был глюк камеры при использовании float.
C++1camera.setCenter((int)tempX, (int)tempY);Правильно, ибо SFML производит отрисовку “По пиксельно” в отношении ОКНА и НЕ применяет сглаживание по умолчанию. Для активации сглаживания в конструктор окна надо передавать sf::ContextSettings с заданым значением зглаживани (Antialiasing).
-
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.