SFML и C++ Уроки \ Разработка игр › Форумы › SFML Project (делимся своими проектами) › кнопки для меню
В этой теме 2 ответа, 2 участника, последнее обновление Mihalo15z 8 года/лет, 2 мес. назад.
-
АвторСообщения
-
Первым делом большое спасибо за ресурс.
Появилась идея сделать что-то на подобии Pacman, упрощенный вариант не в ОПП набросал для восприятия, сейчас перевожу в ООП. Возникли кое-какие вопросы, но о них в конце. Один из компонентов проекта “Меню”. Ну и соответственно код для кнопки “button.h”
Заранее извиняюсь за стиль, точнее за его отсутствие. Я честно пытался привести все к культурному…C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248#ifndef BUTTON_H#define BUTTON_H#include <SFML/Graphics.hpp>#include <string>#include <iostream>class button // : public sf::Drawable{private:sf::Texture _txGround;sf::Sprite _spGround;sf::Font _font;sf::Text _txtCaption;sf::Vector2f _position;bool _click;bool _press;bool _releas;bool _contains;float _H_txt, _W_txt, _H_ground, _W_ground;void _obgreydButton();float _factorW;float _factorH;public:button(){};button(std::string caption, std::string fileTexture = "resource/200x40.png", std::string fileFont = "resource/Abduction.ttf");virtual ~button(){/*delete this;*/};void setTexture( std::string file_texture ); //загрузка текстуры (и спрайта)void setFont( std::string fileFont );void setCaption( std::string caption );void setPosition( sf::Vector2f position );void setPosition( float x, float y );void setSizeFont( unsigned int size );void draw( sf::RenderWindow &window );bool containsCursorButton( const sf::RenderWindow &window);bool pressedMouseButton();bool releasedMouseButton();// значение отпущенной клавиши устанавливает true, обратно запрещено!!!(хотя хз мб и стоит разрешить)bool isClick();protected:};///**************************************************************button::button( std::string сaption, std::string fileTexture , std::string fileFont ){_font.loadFromFile( fileFont ); //загрузка файла шрифта_txGround.loadFromFile( fileFexture ); //загрузка файла текстуры основания кнопки_txtCaption.setString( caption ); //ввод текста надписи_txtCaption.setFont( _font ); // установка шрифта_position = { 0, 0 }; // установка позиции_spGround.setTexture( _txGround ); // загрузка текстуры в спрайт_click = false; // состояния кнопки относительно указателя мыши,_press = false; // мб они и лишние_releas = false;_contains = false;_factorH = 1; // множители размеров для фона кнопки_factorW = 1;_obgreydButton();}//button::~button()//{// //dtor//}inline void button::setTexture( std::string fileTexture ) // загрузка фона{_txGround.loadFromFile( file_texture );_spGround.setTexture( _txGround );_obgreydButton();}inline void button::setFont( std::string file_font ){_font.loadFromFile( fileFont );_txtCaption.setFont( _font );_obgreydButton();}inline void button::setCaption( std::string caption ){_txtCaption.setString( caption );_obgreydButton();}inline void button::setPosition( sf::Vector2f position ){_position = position;_spGround.setPosition( _position );_txtCaption.setPosition( _position.x + 0.01*_W_txt, _position.y - 0.01*_H_txt ); // смещение 0,01* Х можно убрать, основная настройка расположения делается в _obgreydButton(), а эти остались... так сказать, для более тонкой))// размер текста ну никак не совпадает с размерностью шрифта}inline void button::setPosition( float x, float y ){_position.x = x;_position.y = y;_spGround.setPosition( _position );_txtCaption.setPosition( _position.x + 0.01*_W_txt, position.y - 0.01*_H_txt );}inline void button::setSizeFont( unsigned int size )// установка размера шрифта{_txtCaption.setCharacterSize( size );_obgreydButton();}inline void button::draw( sf::RenderWindow &window ) // отрисовка кнопки в окне// можно наследовать sf::Drawable, и в дальнейшем проводить отрисовку через контейнер объектов sf::Drawable (удалил , пока разбирался с button.cpp){window.draw(_spGround );window.draw(_txtCaption);containsCursorButton(window); // проверка на наличия курсора в области кнопки// window.display();}inline void button::_obgreydButton () // нормирование размеров кнопки к тексту{_H_txt = _txtCaption.getLocalBounds().height; // узнаем размеры текста_W_txt = _txtCaption.getLocalBounds().width;_txtCaption.setOrigin(_W_txt/2, _H_txt/2 + _H_txt*0.22 ); // чтобы ровно по центру находился относительно фона_W_ground = _spGround.getLocalBounds().width; // узнаем размеры основания_H_ground = _spGround.getLocalBounds().height;_spGround.setOrigin(_W_ground/2, _H_ground/2);if ( (_H_txt*0.1 + _H_txt) > _H_ground ) // подгонка размеров, возможно нужно проводить всегда , а не только при размере текста больше основания{_factorH = ((_H_txt + 0.2 * _H_txt)/_H_ground);}if ((0.1 * _W_txt + _W_txt) > _W_ground){_factorW =((_W_txt + 0.2 * _W_txt)/_W_ground);}_spGround.setScale(_factorW, _factorH);// std:: cout << H_txt << " - h_T" << std::endl// << W_txt << " - w_T" << std::endl// << factorH * H_ground << std::endl// << factorW * W_ground << std::endl// << H_ground << " - h_G" << std::endl// << W_ground << " - w_G" << std::endl;}bool button::containsCursorButton( const sf::RenderWindow &window) // проверка положения курсора относительно кнопки{sf::Vector2i cursor(sf::Mouse::getPosition(window));sf::Vector2f wcursor =(window.mapPixelToCoords(cursor));if( _spGround.getGlobalBounds().contains(wcursor)){_txtCaption.setColor(sf::Color::Green);_contains = true;return true;}else{_txtCaption.setColor(sf::Color ::White);_contains = false;return false;}}bool button::pressedMouseButton() //нажатая кнопка{if (_contains) // нажатие при условии наличия курсора на кнопке, работает если навести в нажатом состоянии курсор( можно сделать проверку на нажатие именно на кнопке , но пока мне важнее что ее там отпустили){//if ((event.type == sf::Event::MouseButtonPressed) && (sf::Event::MouseButtonEvent.button == sf::Mouse::Left))// и хз наф нужен event если все события возможно проверит и без него( мб внутри где-то и предается)if( sf::Mouse::isButtonPressed( sf::Mouse::Left)){_spGround.setScale(_factorW* 1.1,_factorH*1.1); // увеличение размера кнопки в нажатом состоянии_press = true;return true;}else _spGround.setScale(_factorW, _factorH);_press = false;return false; // мб лишние возвраты в исходное, но пока пусть будут}else{_spGround.setScale(_factorW, _factorH);_press = false;return false;}}bool button::releasedMouseButton(){if(_contains){if(_press){if(!(sf::Mouse::isButtonPressed(sf::Mouse::Left))) // а вот тут и недоработочка, отпускание клавиши есть ток в Event, хз на скок норм такой вариант, критические тесты не проводил{//std::cout << "*/*/*/*/" <<std::endl; // тест_releas = true;_press = false;}else_releas = false;return false;}else{_releas = false;return false;}}}bool button::isClick(){pressedMouseButton();releasedMouseButton();if (_releas){_click = true;return true;}else{_click = false;return false;}}#endif // BUTTON_HИспользование как мне кажется понятно, но если надо, пишите, покажу и расскажу.
Возникли следующие проблемы:
– сразу реализацию методов класса делал в butto.cpp , но при попытки использовать компилятор не мог определить откуда брать реализацию. Лазя по форумам нашел инфу, что эта из-за шаблоности методов и для устранения их ошибки надо закинуть в button.h. Оно то помогло, но не удовлетворило…(( Мб надо компилировать как *.lib и дальше так использовать..
– пытался закинуть все кнопки в вектор( в том числе по указателю и ссылке), но выдает ошибку выделения памяти, как решить пока не знаю, если кто поможет буду благодарен.
– долго мучался с централизацией текста относительно основания, пока с другими шрифтами не пробовалБуду благодарен за советы по коду, к примеру, стоило ли разбить на более мелкие классы и какие. А то пока опыта нормального нету((
Немного вопросов по Pacman : когда меняешь направление в лабиринте, очень сложно попасть в проход на ‘T’ ‘X’ -образных перекрестках при смене направления движения. Пробовал ” уменьшить” размеры Pacman, но также не удовлетворило, хотя играть стало терпимо. Мыслю об автодоводке до нужной координаты, но когда и как, пока не решил. Если есть у кого какие предложения, буду благодарен.
Ну если не заброшу, выложу готовый проект тут.
смещение dx и dy должны быть достаточно маленькими, и размер пакмана чуть меньше размера прохода
Скорость пакмана 1 пиксель в кадр(100 кадров в секунду), размеры плиток 40х40 (наверное стоит перейти на кратное степени двойки для быстроты) размер пакмана пробовал уменьшать до 30 пикселей.
Пока наверное поищу такого типа игры, что бы банально поиграть, посмотреть на движение. А реализовывать буду то что сам придумаю, над иногда мучать себя))
-
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.