SFML и C++ Уроки \ Разработка игр › Форумы › SFML Graphics › уроки sfml ,вопросы по урокам
В этой теме 9 ответов, 2 участника, последнее обновление Alex 8 года/лет, 3 мес. назад.
-
АвторСообщения
-
вопрос следующий: при добавлении функции void interactionWithMap(),после компиляции появляется один белый экран, и windows аварийно завершает программу,в чем может быть проблема?(урок 11)
если закомментируешь эту строку то всё норм?
может у тебя персонаж появляется в месте, где не должен и застревает благодаря этой ф-ции?
скидывай на будущее весь код, может рисование не так проходит в конечном счёте. и проект тоже кидай.
сейчас ситуация немного другая, я поменял местами, в функции , как было в уроке (<span class=”crayon-v”>TileMap</span><span class=”crayon-sy”>[</span><span class=”crayon-v”>i</span><span class=”crayon-sy”>]</span><span class=”crayon-sy”>[</span><span class=”crayon-v”>j</span><span class=”crayon-sy”>]</span> <span class=”crayon-o”>==</span> <span class=”crayon-s”>’0′) на (<span class=”crayon-v”>TileMap</span><span class=”crayon-sy”>[j</span><span class=”crayon-sy”>]</span><span class=”crayon-sy”>[</span><span class=”crayon-v”>i</span><span class=”crayon-sy”>]</span> <span class=”crayon-o”>==</span> <span class=”crayon-s”>’0′)?то есть x с y местами поменял, после этого почему то заработало, но не все, </span></span>
<span class=”crayon-s”><span class=”crayon-s”>что получилось,влево персонаж останавливается как надо, вправо останавливается заранее почти на пол карты</span></span>
сейчас ситуация немного другая, я поменял местами, в функции , как было в уроке (TileMap[i][j] == ‘0’) на (TileMap[j][i] == ‘0’)то есть x с y местами поменял, после этого почему то заработало, но не все,
что получилось,влево персонаж останавливается как надо, вправо останавливается заранее почти на пол картыкод немного изменил под тип “марио” и добавил возвращение анимации при остановке персонажа
#include <SFML/Graphics.hpp>
#include <iostream>
#include “map.h”
#include “viev.h”using namespace sf;//включаем пространство имен sf, чтобы постоянно не писать sf::
class Player//class igroka
{private:float x, y;
public:
float w,h, dx,dy,speed;
int dir =0;
String File;
Image image;
Texture texture;
Sprite sprite;Player(String F,float X,float Y,float W,float H)//конструктор
{
dx = 0;dy = 0;speed = 0;dir = 0;
File = F;
w=W,h=H;
image.loadFromFile(“imaj/” + File);
image.createMaskFromColor(Color(255,255,255));
image.createMaskFromColor(Color(41,33,59));
texture.loadFromImage(image);
sprite.setTexture(texture);
x=X,y=Y;sprite.setTextureRect(IntRect(0, 0, w, h));
}void ogivlenie (float time)
{
switch(dir)
{
case 0: dx = speed; dy = 0;break;
case 1: dx = -speed; dy = 0;break;
case 3: dx = 0;dy =-speed;}
x += dx*time;
y+= dy*time;speed =0;
sprite.setPosition(x,y);
interactionWithMap();}
void interactionWithMap()//ф-ция взаимодействия с картой
{for (int j = x / 32; j<(x + w) / 32; j++)
for (int i = y / 32; i < (y + h) / 32; i++)
{
if (TileMap[j][i] == ‘0’)//если наш квадратик соответствует символу 0 (стена), то проверяем “направление скорости” персонажа:
{if (dx>0)
{
x = j * 32 ;break;//если идем вправо, то координата Х равна стена (символ 0) минус ширина персонажа
}
if (dx < 0)
{
x = j * 32 + 32;break;//аналогично идем влево
}
}if (TileMap[j][i] == ‘s’) { //если символ равен ‘s’ (камень)
TileMap[j][i] = ‘ ‘;//убираем камень, типа взяли бонус. можем и не убирать, кстати.
}
}
}float getplayercoordinateX(){ //этим методом будем забирать координату Х
return x;
}float getplayercoordinateY(){ //этим методом будем забирать координату Y
return y;
}};
int main()
{
RenderWindow window(sf::VideoMode(640, 480), “Marin”); //увеличили для удобства размер окна
view.reset(sf::FloatRect(0,0, 640, 480));//размер “вида” камеры при создании объекта вида камеры. (потом можем менять как хотим) Что то типа инициализации.// карта//////////////////////////////////////
Image map_image;//объект изображения для карты
map_image.loadFromFile(“imaj/11.png”);//загружаем файл для карты
Texture map;//текстура карты
map.loadFromImage(map_image);//заряжаем текстуру картинкой
Sprite s_map;//создаём спрайт для карты
s_map.setTexture(map);//заливаем текстуру спрайтом
// //////////////////////////////////////////////////Player p(“martin.png”,100,390,120,125);//ввод в коструктор
p.sprite.setTextureRect(IntRect(0,200, 120, 125));//начальное расположение спрайта
p.sprite.setScale(0.5, 0.5);//размер персонажа
float CurrentFrame = 0;//хранит текущий кадр
Clock clock;//переменная времени
while (window.isOpen())
{float time = clock.getElapsedTime().asMicroseconds(); //дать прошедшее время в микросекундах
clock.restart();//перезагружает время
time = time/800; //скорость игрыsf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}/////////////////////////////Движение обекта//////////////////////////////////////
if (Keyboard::isKeyPressed(Keyboard::Right)){
p.dir = 0; p.speed = 0.3;
CurrentFrame += 0.008*time;//скорость анимации
if(CurrentFrame >6)CurrentFrame -= 6;
p.sprite.setTextureRect(IntRect(150 * int(CurrentFrame),0, 120,125));
getplayercoordinateforview(p.getplayercoordinateX(), p.getplayercoordinateY());
}
else
p.sprite.setTextureRect(IntRect(0,200, 120, 125));//начальное расположение спрайтаif (Keyboard::isKeyPressed(Keyboard::Left)){
p.dir = 1; p.speed = 0.3;
CurrentFrame += 0.008*time;
if(CurrentFrame >6)CurrentFrame -= 6;
p.sprite.setTextureRect(IntRect(150* int(CurrentFrame)+150,0, -130, 125));
getplayercoordinateforview(p.getplayercoordinateX(), p.getplayercoordinateY());
}
else if (p.dir ==1){
p.sprite.setTextureRect(IntRect(120,200, -120, 125));//начальное расположение спрайта
}if (Keyboard::isKeyPressed(Keyboard::Up)){
p.dir = 3; p.speed = 0.3;p.sprite.setTextureRect(IntRect(450,0, 120,125));
}
// //////////////////////////////////////////////////
p.ogivlenie(time);//оживление ввод времени
window.clear(Color(246,236,211));
// ///////////карта(печатаем карту по квадратику)////////////////////// //
for (int i = 0; i < visota; i++)
for (int j = 0; j < shirina; j++)
{
if (TileMap[i][j] == ‘ ‘) s_map.setTextureRect(IntRect(283,157, 32, 32)); //если встретили символ пробел, то рисуем 1й квадратик
if (TileMap[i][j] == ‘s’) s_map.setTextureRect(IntRect(32, 329, 32, 32));//если встретили символ s, то рисуем 2й квадратик
if ((TileMap[i][j] == ‘0’)) s_map.setTextureRect(IntRect(0, 409, 32, 32));//если встретили символ 0, то рисуем 3й квадратикs_map.setPosition(j * 32, i * 32);//по сути раскидывает квадратики, превращая в карту. то есть задает каждому из них позицию. если убрать, то вся карта нарисуется в одном квадрате 32*32 и мы увидим один квадрат
window.draw(s_map);//выводим карту
}
window.setView(view);
window.draw(p.sprite);//выводим спрайт на экран
window.display();
}return 0;
}строка “x = j * 32 ;break;//если идем вправо, то координата Х равна стена (символ 0) минус ширина персонажа” – это уже я сам эксперементировал что бы изменить ситуацию
все разобрался в чем причина, проблема была из за функции p.sprite.setScale(1, 1); она уменьшала картинку, но не сам спрайт поэтому, поэтому персонаж останавливался раньше нужного, так же закрывалось окно из за того что спрайт был распложен там где не должен был быть, так как он был больше самой картинки я этого не мог видеть
почистил сам файл с изображением что бы не было лишнего места и персонаж мог вплотную подходить к стенке,
добавил один таил для положения персонажа в положении покоя и когда он подходит к препятствию
код который получился :
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263#include <SFML/Graphics.hpp>#include <iostream>#include "map.h"#include "viev.h"using namespace sf;//включаем пространство имен sf, чтобы постоянно не писать sf::class Player//class igroka{private:float x, y;public:float w,h, dx,dy,speed;int dir =0;String File;Image image;Texture texture;Sprite sprite;Player(String F,float X,float Y,float W,float H)//конструктор{dx = 0;dy = 0;speed = 0;dir = 0;File = F;w=W,h=H;image.loadFromFile("imaj/" + File);image.createMaskFromColor(Color(255,255,255));image.createMaskFromColor(Color(41,33,59));texture.loadFromImage(image);sprite.setTexture(texture);x=X,y=Y;sprite.setTextureRect(IntRect(0, 0, w, h));}void ogivlenie (float time){switch(dir){case 0: dx = speed; dy = 0;break;case 1: dx = -speed; dy = 0;break;case 2: dx = 0; dy = speed;break;case 3: dx = 0;dy =-speed;}x += dx*time;y+= dy*time;speed =0;sprite.setPosition(x,y);interactionWithMap();}void interactionWithMap()//ф-ция взаимодействия с картой{for (int i = y / 32; i < (y + h) / 32; i++)//проходимся по тайликам, контактирующим с игроком,, то есть по всем квадратикам размера 32*32, которые мы окрашивали в 9 уроке. про условия читайте ниже.for (int j = x / 32; j<(x + w) / 32; j++)//икс делим на 32, тем самым получаем левый квадратик, с которым персонаж соприкасается. (он ведь больше размера 32*32, поэтому может одновременно стоять на нескольких квадратах). А j<(x + w) / 32 - условие ограничения координат по иксу. то есть координата самого правого квадрата, который соприкасается с персонажем. таким образом идем в цикле слева направо по иксу, проходя по от левого квадрата (соприкасающегося с героем), до правого квадрата (соприкасающегося с героем){if (TileMap[i][j] == '0')//если наш квадратик соответствует символу 0 (стена), то проверяем "направление скорости" персонажа:{if (dy>0)//если мы шли вниз,{y = i * 32 -h;//то стопорим координату игрек персонажа. сначала получаем координату нашего квадратика на карте(стены) и затем вычитаем из высоты спрайта персонажа.}if (dy<0){y = i * 32 + 32;//аналогично с ходьбой вверх. dy<0, значит мы идем вверх (вспоминаем координаты паинта)}if (dx>0){x = j * 32 - w;//если идем вправо, то координата Х равна стена (символ 0) минус ширина персонажаsprite.setTextureRect(IntRect(865,0, 68, 125));}if (dx < 0){x = j * 32 + 32;//аналогично идем влевоsprite.setTextureRect(IntRect(933,0, -68, 125));}}if (TileMap[i][j] == 's') { //если символ равен 's' (камень)y = 200;//какое то действие... например телепортация герояTileMap[i][j] = ' ';//убираем камень, типа взяли бонус. можем и не убирать, кстати.}}}float getplayercoordinateX(){ //этим методом будем забирать координату Хreturn x;}float getplayercoordinateY(){ //этим методом будем забирать координату Yreturn y;}};int main(){RenderWindow window(sf::VideoMode(640, 480), "Marin"); //увеличили для удобства размер окнаview.reset(sf::FloatRect(0,0, 640, 480));//размер "вида" камеры при создании объекта вида камеры. (потом можем менять как хотим) Что то типа инициализации.// карта//////////////////////////////////////Image map_image;//объект изображения для картыmap_image.loadFromFile("imaj/11.png");//загружаем файл для картыTexture map;//текстура картыmap.loadFromImage(map_image);//заряжаем текстуру картинкойSprite s_map;//создаём спрайт для картыs_map.setTexture(map);//заливаем текстуру спрайтом// //////////////////////////////////////////////////Player p("martin.png",100,335,72,110);//ввод в кострукторp.sprite.setTextureRect(IntRect(865,0, 68, 125));//начальное расположение спрайтаgetplayercoordinateforview(p.getplayercoordinateX(), p.getplayercoordinateY());//p.sprite.setScale(1, 1);//размер персонажаfloat CurrentFrame = 0;//хранит текущий кадрClock clock;//переменная времениwhile (window.isOpen()){float time = clock.getElapsedTime().asMicroseconds(); //дать прошедшее время в микросекундахclock.restart();//перезагружает времяtime = time/800; //скорость игрыsf::Event event;while (window.pollEvent(event)){if (event.type == sf::Event::Closed)window.close();}/////////////////////////////Движение обекта//////////////////////////////////////if (Keyboard::isKeyPressed(Keyboard::Right)){p.dir = 0; p.speed = 0.3;CurrentFrame += 0.008*time;//скорость анимацииif(CurrentFrame >6)CurrentFrame -= 6;p.sprite.setTextureRect(IntRect(145 * int(CurrentFrame),0, 135,125));getplayercoordinateforview(p.getplayercoordinateX(), p.getplayercoordinateY());}elsep.sprite.setTextureRect(IntRect(865,0, 68, 125));//начальное расположение спрайтаif (Keyboard::isKeyPressed(Keyboard::Left)){p.dir = 1; p.speed = 0.3;CurrentFrame += 0.008*time;if(CurrentFrame >6)CurrentFrame -= 6;p.sprite.setTextureRect(IntRect(140* int(CurrentFrame)+140,0, -135, 125));getplayercoordinateforview(p.getplayercoordinateX(), p.getplayercoordinateY());}else if (p.dir ==1){p.sprite.setTextureRect(IntRect(933,0, -68, 125));//начальное расположение спрайта}if (Keyboard::isKeyPressed(Keyboard::Up)){p.dir = 3; p.speed = 0.3;p.sprite.setTextureRect(IntRect(450,0, 120,125));}if (Keyboard::isKeyPressed(Keyboard::Down)){p.dir = 2; p.speed = 0.3;p.sprite.setTextureRect(IntRect(450,0, 120,125));getplayercoordinateforview(p.getplayercoordinateX(), p.getplayercoordinateY());}// //////////////////////////////////////////////////p.ogivlenie(time);//оживление ввод времениwindow.clear(Color(246,236,211));// ///////////карта(печатаем карту по квадратику)////////////////////// //for (int i = 0; i < visota; i++)for (int j = 0; j < shirina; j++){if (TileMap[i][j] == ' ') s_map.setTextureRect(IntRect(283,157, 32, 32)); //если встретили символ пробел, то рисуем 1й квадратикif (TileMap[i][j] == 's') s_map.setTextureRect(IntRect(0, 362, 32, 32));//если встретили символ s, то рисуем 2й квадратикif ((TileMap[i][j] == '0')) s_map.setTextureRect(IntRect(0, 409, 32, 32));//если встретили символ 0, то рисуем 3й квадратикs_map.setPosition(j * 32, i * 32);//по сути раскидывает квадратики, превращая в карту. то есть задает каждому из них позицию. если убрать, то вся карта нарисуется в одном квадрате 32*32 и мы увидим один квадратwindow.draw(s_map);//выводим карту}window.setView(view);window.draw(p.sprite);//выводим спрайт на экранwindow.display();}return 0;} -
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.