СПРОСИ ПРОФИ
👍
0
👎 01

При создании графического приложения на C++ с использованием библиотеки SFML не выводится консоль, необходимая для ввода значений

1. Задание1.
1.Выбрать объект, в соответствие с вариантом:

1) Цветок.
2) Дом.
3) Машина.
4) Телефон.
5) Компьютер.
6) Собака.
7) Человек.
8) Телевизор.
9) Книга.
10) Дерево.
11) Кошка.
12) Птица.
13) Звездное небо.
14) Планета Земля.
15) Часы.
16) Окно.
17) Тетрадь.
18) Клавиатура.
19) Первый корпус УГНТУ.
20) Общежитие №6
21) Стол
22) Кресло.
23) Принтер.
24) Стул.
25) План помещения.
26) Озеро с рыбой.

2. Изобразить объект произвольного размера и цвета.
3. Общие требования к изображению:
1) Использование более пяти различных цветов.
2) Использовать более трех функций изображения графических элементов в Си.
4. Организовать движение рисунка (или части рисунка) в произвольном направлении, используя работу с буфером обмена.
5. Вывести текст на экране (по заданной теме).
6. Реализовать возможность рекурсивного повторения рисунка n-раз (n вводится с клавиатуры).
Мой код: #include <SFML/Graphics.hpp> //подключение графической библиотеки

void drawTree(sf::RenderWindow& window, int depth, const sf::Vector2f& position, float scale) {
//& — для работы с оригинальной переменной, а не с копией
// const — гарантирует, что оригинальная переменная не изменится

if (depth ⇐ 0) return;

sf::Texture tree1_texture;
tree1_texture.loadFromFile(«tree1.png»);
sf::Sprite tree1_sprite;
tree1_sprite.setTexture(tree1_texture);
tree1_sprite.setPosition(position);
tree1_sprite.setScale(scale, scale);
tree1_sprite.setOrigin(tree1_texture.getSize().x / 2.f, tree1_texture.getSize().y / 2.f);
window.draw(tree1_sprite);

drawTree(window, depth — 1, sf::Vector2f(position.x + 250.f, position.y + 0.f), scale * 0.9999f); //рекурсивный вызов

}

int main() {
sf::RenderWindow window(sf::VideoMode(1000, 750), «Graphics»); //создание объекта — главного окна
//sf:: — указание на пространоство имён SFML
//RenderWindow — класс, являющийся окном для отрисовки графики
//window — имя объекта, которого мы создаём
//VideoMode(1660, 1000) — создание объекта, который задаёт разрешение окна
//«Graphics» — заголовок окна

window.setFramerateLimit(60);

sf::RectangleShape rectangle(sf::Vector2f(300.f, 250.f)); //создание прямоугольника
//sf::RectangleShape — класс прямоугольника
//sf::Vector2f — класс, представляющий вектор из двух чисел с плавающей точкой. Здесь задаётся размер прямоугольника
rectangle.setFillColor(sf::Color(165, 42, 42)); //заливка
rectangle.setPosition(300.f, 380.f); //устанавливаем позицию для левого верхнего угла

sf::ConvexShape triangle; //создаём фигуру из нескольких точек
triangle.setPointCount(3); //задаём количество вершин
triangle.setPoint(0, sf::Vector2f(0.f, -40.f)); //положение первой вершины относительно ЦЕНТРА ФИГУРЫ и т.д.
triangle.setPoint(1, sf::Vector2f(-150.f, 150.f));
triangle.setPoint(2, sf::Vector2f(150.f, 150.f));
triangle.setFillColor(sf::Color::Red);
triangle.setPosition(450, 230); //положение центра треугольника

sf::CircleShape circle_window(30.f);
circle_window.setFillColor(sf::Color(95, 199, 242));
circle_window.setPosition(420.f, 250.f);

sf::RectangleShape central_window(sf::Vector2f(150.f, 130.f));
central_window.setFillColor(sf::Color(95, 199, 242));
central_window.setPosition(375.f, 445.f);

sf::RectangleShape frame_element1(sf::Vector2f(20.f, 130.f));
frame_element1.setFillColor(sf::Color::White);
frame_element1.setPosition(440.f, 445.f);

sf::RectangleShape frame_element2(sf::Vector2f(150.f, 20.f));
frame_element2.setFillColor(sf::Color::White);
frame_element2.setPosition(375.f, 500.f);

sf::RectangleShape frame_element3(sf::Vector2f(10.f, 60.f));
frame_element3.setFillColor(sf::Color::White);
frame_element3.setPosition(445.f, 250.f);

sf::RectangleShape frame_element4(sf::Vector2f(60.f, 10.f));
frame_element4.setFillColor(sf::Color::White);
frame_element4.setPosition(420.f, 275.f);

sf::RectangleShape sky(sf::Vector2f(1000.f, 630.f));
sky.setFillColor(sf::Color::Blue);
sky.setPosition(0.f, 0.f);

sf::RectangleShape grass(sf::Vector2f(1000.f, 120.f));
grass.setFillColor(sf::Color(12, 143, 28));
grass.setPosition(0.f, 630.f);

sf::ConvexShape pipe;
pipe.setPointCount(4);
pipe.setPoint(0, sf::Vector2f(-15.f, -60.f));
pipe.setPoint(1, sf::Vector2f(15.f, -60.f));
pipe.setPoint(2, sf::Vector2f(15.f, 65.f));
pipe.setPoint(3, sf::Vector2f(-15.f, 25.f));
pipe.setFillColor(sf::Color(95, 100, 105));
pipe.setPosition(500.f, 210.f);

sf::Texture cloud1_texture; //Создаётся объект cloud1_texture класса sf::Texture
cloud1_texture.loadFromFile(«cloud1.png»); //Загрузка изображения из файла в объект текстуры
sf::Sprite cloud1_sprite; //Создаётся объект cloud1_sprite класса sf::Sprite
cloud1_sprite.setTexture(cloud1_texture); //Наложение текстуры на спрайт
cloud1_sprite.setPosition(150.f, 150.f); //Установка позиции спрайта
cloud1_sprite.setScale(5.f, 5.f); //Масштабирование изображения в 5 раз по обеим осям
cloud1_sprite.setOrigin(cloud1_texture.getSize().x / 2.f, cloud1_texture.getSize().y / 2.f); //Установка «точки отсчёта» в центр спрайта
//cloud1_texture.getSize().x — возвращает размер текстуры по оси x
//делим на 2, чтобы найти центр

sf::Texture cloud2_texture;
cloud2_texture.loadFromFile(«cloud2.png»);
sf::Sprite cloud2_sprite;
cloud2_sprite.setTexture(cloud2_texture);
cloud2_sprite.setPosition(500.f, 120.f);
cloud2_sprite.setScale(5.f, 5.f);
cloud2_sprite.setOrigin(cloud2_texture.getSize().x / 2.f, cloud2_texture.getSize().y / 2.f);

sf::Texture cloud3_texture;
cloud3_texture.loadFromFile(«cloud3.png»);
sf::Sprite cloud3_sprite;
cloud3_sprite.setTexture(cloud3_texture);
cloud3_sprite.setPosition(800.f, 130.f);
cloud3_sprite.setScale(5.f, 5.f);
cloud3_sprite.setOrigin(cloud3_texture.getSize().x / 2.f, cloud3_texture.getSize().y / 2.f);

sf::Texture tree1_texture;
tree1_texture.loadFromFile(«tree1.png»);
sf::Sprite tree1_sprite;
tree1_sprite.setTexture(tree1_texture);
tree1_sprite.setPosition(150.f, 450.f);
tree1_sprite.setScale(7.5f, 7.5f);
tree1_sprite.setOrigin(tree1_texture.getSize().x / 2.f, tree1_texture.getSize().y / 2.f);

sf::Texture bird_sheet; //создание текстуры bird_sheet
bird_sheet.loadFromFile(«birdSheet.png»); //загрузка картинки в текстуру
sf::RenderTexture birdBuffer; //создание буфера («вирутального» холста)
birdBuffer.create(64.f, 64.f); //установка размеров буфера
sf::Sprite bird_sprite;
bird_sprite.setTexture(birdBuffer.getTexture()); //загружаем текстуру для спрайта из буфера
bird_sprite.setPosition(200.f, 300.f);
bird_sprite.setScale(3.f, 3.f);

int current_frame = 0; //номер текущего кадра
int total_frames = 3; //всего кадров
float frame_time = 0.1f; //время между кадрами
float elapsed_time = 0.f; //сколько прошло с последнего кадра
float rest_time = 0.f; //время «отдыха» птицы

float cloud_speed = 1.f;
float bird_speed = 2.5f;
bool fly = false;

sf::RenderTexture movement_buffer; //создание буфера для движения
movement_buffer.create(1000.f, 750.f); //задание ему размеров как у окна
sf::Sprite movement_sprite; //создание спрайта для отображения буфера

sf::Clock clock; //создание таймера для того, чтобы измерять время между кадрами

int n = 1;

sf::Font font;
font.loadFromFile(«Papyrus-02.otf»);
sf::Text text(«A house with trees and crow», font, 25);
text.setPosition(600.f, 200.f);
text.setFillColor(sf::Color::White);

while (window.isOpen()) { //Цикл, который выполняется до тех пор, пока открыто окно приложения
float delta_time = clock.restart().asSeconds(); //время между кадрами
//restart() — счёт времени с нуля, asSeconds() — перевод в секунды
elapsed_time += delta_time;
rest_time += 0.1f;
sf::Event event; //Создание переменной для хранения события
//sf::Event — класс(структура), который представляет собой какое-либо событие
//event — объект, в который мы будем помещать информацию о событии
while (window.pollEvent(event)) { //Цикл обработки событий
//pollEvent(event) — обрабатывает по очереди по одному событию за раз
if (event.type == sf::Event::Closed) { //обработка события «закрыть окно»
window.close(); //установка флага о закрытии окна
}
//event.type — это поле структуры Event, которое говорит нам, какого типа это событие
//sf::Event::Closed — это константа (значение), которая соответствует событию «пользователь нажал на крестик окна»
if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::Right) n++;
else if (event.key.code == sf::Keyboard::Left) n = std::max(1, n — 1);
}
}
movement_buffer.clear(sf::Color::Transparent); //очищаем буфер
sf::Sprite Bird = bird_sprite; //создаём копию спрайта птицы
Bird.setPosition(Bird.getPosition().x + bird_speed, Bird.getPosition().y); //задаём новое положение птице
movement_buffer.draw(Bird); //рисуем птицу в буфер

if (rest_time >= 5.f) fly = true;
if (fly) {
bird_sprite.setPosition(Bird.getPosition()); //задаём новое положение птице
}

sf::Sprite Cloud1 = cloud1_sprite;
Cloud1.setPosition(Cloud1.getPosition().x + cloud_speed, Cloud1.getPosition().y);
movement_buffer.draw(Cloud1);

sf::Sprite Cloud2 = cloud2_sprite;
Cloud2.setPosition(Cloud2.getPosition().x + cloud_speed, Cloud2.getPosition().y);
movement_buffer.draw(Cloud2);

sf::Sprite Cloud3 = cloud3_sprite;
Cloud3.setPosition(Cloud3.getPosition().x + cloud_speed, Cloud3.getPosition().y);
movement_buffer.draw(Cloud3);

movement_buffer.display(); //отображаем рисунок
movement_sprite.setTexture(movement_buffer.getTexture()); //накладываем текстуру на спрайт


cloud1_sprite.setPosition(Cloud1.getPosition());
cloud2_sprite.setPosition(Cloud2.getPosition());
cloud3_sprite.setPosition(Cloud3.getPosition());

if (bird_sprite.getPosition().x > 1100) {
bird_sprite.setPosition(-100.f, bird_sprite.getPosition().y);
}

if (cloud1_sprite.getPosition().x > 1100) {
cloud1_sprite.setPosition(-100.f, cloud1_sprite.getPosition().y);
}
if (cloud2_sprite.getPosition().x > 1100) {
cloud2_sprite.setPosition(-100.f, cloud2_sprite.getPosition().y);
}
if (cloud3_sprite.getPosition().x > 1100) {
cloud3_sprite.setPosition(-100.f, cloud3_sprite.getPosition().y);
}
if (fly) {
if (elapsed_time >= frame_time) {
elapsed_time = 0.f;
current_frame = (current_frame + 1) % total_frames;
}
birdBuffer.clear(sf::Color::Transparent);
}

sf::Sprite frame; //создание спрайта текущего кадра
frame.setTexture(bird_sheet); //«заливаем» спрайтшит в спрайт
frame.setTextureRect(sf::IntRect(current_frame * 64, 0, 64, 64));
// setTextureRect(/что вырезаем/) — вырезает часть текстуры
// sf::IntRect(x, y, width, height) — класс для создания прямоугольной области
birdBuffer.draw(frame);
birdBuffer.display();

window.clear(); //очистка кадра
window.draw(sky);
window.draw(grass);
window.draw(rectangle); //рисуем прямоугольник
window.draw(triangle);
window.draw(circle_window);
window.draw(central_window);
window.draw(frame_element1);
window.draw(frame_element2);
window.draw(frame_element3);
window.draw(frame_element4);
window.draw(pipe);
drawTree(window, n, sf::Vector2f(150.f, 450.f), 7.5f);
window.draw(movement_sprite);
window.draw(text);
window.display();
}
return 0;
}
По заданию глубина рекурсии (то есть количество раз того, сколько мы рисуем дерево) должно вводиться с клавиатуры. Пока что я реализовал изменение значения глубины рекурсии при помощи стрелочек. Но по идее нужно, чтобы значение могло вводиться с клавы. Но при запуске программы консоли никакой нет, куда вводить n непонятно.

👍
0
👎 0

Ответ chatgpt:

Ага, понял проблему 👍

Когда ты используешь SFML и создаёшь sf::RenderWindow, это графическое приложение. В таком режиме по умолчанию консоль скрывается (особенно если ты собираешь проект в Visual Studio как Windows Application). Поэтому обычный cin >> n; работать негде — консоли просто нет.

---

Есть несколько решений:


🔹 Вариант 1. Сделать проект консольным

  • В Visual Studio зайди в свойства проекта → Linker → System → Subsystem
  • Поставь Console (/SUBSYSTEM:CONSOLE) вместо Windows (/SUBSYSTEM:WINDOWS).
  • Тогда у тебя будет и графическое окно и чёрная консолька, куда можно ввести n.


Минус: всегда будет висеть консолька.

---

🔹 Вариант 2. Создать консоль вручную в коде


Если хочешь, чтобы по умолчанию был только SFML, но при этом иногда появлялась консоль для ввода — можно подключить:

cpp
#include <windows.h>
#include <iostream>

void createConsole() {
    AllocConsole();
    FILE* fp;
    freopen_s(&fp, "CONIN$", "r", stdin);
    freopen_s(&fp, "CONOUT$", "w", stdout);
    freopen_s(&fp, "CONOUT$", "w", stderr);
}


И вызвать createConsole(); в main(). Тогда выскочит консольное окно, куда можно писать числа.

---

🔹 Вариант 3. Ввод прямо в графическом окне


Можно вместо консоли сделать ввод через клавиатуру в SFML:

  • перехватывать нажатия клавиш sf::Event::TextEntered
  • собирать строку (std::string input)
  • по Enter превращать её в число n = std::stoi(input);


Так у тебя получится «поле ввода» прямо в графическом приложении (как в играх чат).

---

👉 Если по заданию строго сказано «ввод с клавиатуры», то скорее всего преподаватель ждёт вариант 1: просто сделать проект консольным и использовать cin.

---

Хочешь, я накину пример кода, как именно прикрутить ввод n через SFML-события (вариант 3)?

Задайте свой вопрос по обучению программированию
профессионалам

Сейчас онлайн 75 репетиторов по обучению программированию
Получите ответ профи быстро и бесплатно
ASK.PROFI.RU © 2020-2025