Форум программистов, компьютерный форум, киберфорум
SFML
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
0 / 0 / 0
Регистрация: 27.09.2019
Сообщений: 29
1

По щелчку мыши добавить один объект к другому

27.09.2019, 17:47. Показов 1718. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть вот такая штука, написанная на Флаше : http://igroflot.ru/shot/flash_game_50/

Требуется сделать что-то подобное при помощи С++ и SFML (имею Code Blocks с библиотеками SFML).

Никакой руки с пистолетом не нужно.
Т.е. требуется щелчком мыши по одному объекту (мишень) в локальные координаты курсора на мишени помещать другой объект (изображение пробоины) и в зависимости от этих локальных координат на мишени возвращать какое-то количество очков. Т.е. объект пробоина становится дочкой объекта мишень.

Во Флаше это достигается просто при помощи события onPress(), вызываемого щелчком левой кнопки мыши по какому-то объекту на экране. А мишень набирается из концентрический кругов, каждый из которых является объектом с аттрибутом количества очков. Во Флаше, если onPress() зарегистрирован на нескольких объектах, расположенных друг на друге, то откликается только верхний объект.

Перелопатил много учебных роликов С++ & SFML, но ничего подобного не нашел. Это можно подобным образом воспроизвести на С++ & SFML, или требуется другой подход?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.09.2019, 17:47
Ответы с готовыми решениями:

Добавить текст на Image по щелчку мыши
Делаю курсовую работу, программу, которая помогает создавать кроссворды. осталось совсем немного :...

По щелчку левой кнопки мыши должен меняться цвет формы, а по щелчку правой кнопки мыши – восстанавливаться предыдущий
Добрый день) Пишу одну программку, которая позволяла бы при перемещении курсора мыши менять его...

Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту?
Это можно : Array a(10); a.set(0,5); Array b(a); А это нельзя : Array a(10); Array b(20);...

выделить место для объекта с помощью new или создать указатель, объект и присвоить один другому. какая разница?
кроме того что к объекту созданному с помощью new можно будет обращаться только через указатель.

7
1291 / 908 / 479
Регистрация: 05.12.2013
Сообщений: 3,073
27.09.2019, 22:23 2
Цитата Сообщение от andrei186 Посмотреть сообщение
Т.е. требуется щелчком мыши по одному объекту (мишень) в локальные координаты курсора на мишени помещать другой объект (изображение пробоины) и в зависимости от этих локальных координат на мишени возвращать какое-то количество очков. Т.е. объект пробоина становится дочкой объекта мишень.
Во Флаше это достигается просто при помощи события onPress(), вызываемого щелчком левой кнопки мыши по какому-то объекту на экране. А мишень набирается из концентрический кругов, каждый из которых является объектом с аттрибутом количества очков. Во Флаше, если onPress() зарегистрирован на нескольких объектах, расположенных друг на друге, то откликается только верхний объект.
Координаты мыши можно отлавливать так

C++
1
2
3
4
5
6
if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
    // left click...
}
// get global mouse position
sf::Vector2i position = sf::Mouse::getPosition();
а потом просто отрисовывается пробоина в этих координатах
0
0 / 0 / 0
Регистрация: 27.09.2019
Сообщений: 29
28.09.2019, 13:51  [ТС] 3
Спасибо. Это получилось и пробоина нарисовалась, где надо. Однако, если мишень движется, то пробоина остается висеть на месте.
Судя по комменту // get global mouse position возможно добраться до локальной позиции курсора в координатах мишени. Как это сделать?
И как сделать пробоину дочкой мишени, чтобы она двигвлвсь и масштабировалась вместе с мишенью?
0
1291 / 908 / 479
Регистрация: 05.12.2013
Сообщений: 3,073
04.10.2019, 18:59 4
Цитата Сообщение от andrei186 Посмотреть сообщение
И как сделать пробоину дочкой мишени, чтобы она двигвлвсь и масштабировалась вместе с мишенью?
добавить в класс пробоины поле parents и присвоить этому полю значение мишени и пересчитывать положение пробоины на основании данных мишени
0
0 / 0 / 0
Регистрация: 27.09.2019
Сообщений: 29
04.10.2019, 19:29  [ТС] 5
Спасибо.
Если я правильно представляю то, что мне нужно, экземпляр пробоины должен создаваться при обработке sf::Mouse::isButtonPressed(sf::Mouse::Left)).
Мишеней несколько и они двигаются. А количество выстрелов неограничено.
В этом случае нужно сначала определить, если курсор попал по какой-то из мишеней, извлечь из этой мишени ее значение и присвоить его полю parents?
Если так, то есть какой-то более эффективный способ определять, щелкнул ли курсов по мишени, чем определять координаты мишени в момент щелчка и решать, находится ли курсов внутри габаритов мишени?

Нельзя ли в классе Мишень определить метод, который при щелчке по ней добавляет к ней child?
Или сформулировав проще, как сделать объект Мишень кликабельным? Например, чтобы по щелчку по нему он исчезал
0
1291 / 908 / 479
Регистрация: 05.12.2013
Сообщений: 3,073
04.10.2019, 23:56 6
что-то такое

C++
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
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
using namespace std;
 
class BulletHole
{
public:
    BulletHole(sf::RenderWindow* win, sf::Vector2f p)
    {
        ball = sf::CircleShape(5.f);
        ball.setFillColor(sf::Color::Red);
        ball.setPosition(p);
        pos = p;
        window = win;
    }
 
    void update(sf::Vector2f parent)
    {
        sf::Vector2f p;
        p.x = parent.x - pos.x;
        p.y = parent.y - pos.y;
        ball.setPosition(p);
    }
 
    void draw()
    {
        window->draw(ball);
    }
 
private:
    sf::CircleShape ball;
    sf::RenderWindow* window;
    sf::Vector2f pos;
};
 
class Target
{
public:
    Target(sf::RenderWindow* win, float x, float y, float sz, sf::Color c)
    {
        size = sz;
        rectangle = sf::RectangleShape(sf::Vector2f(size, size));
        pos = sf::Vector2f(x, y);
        rectangle.setPosition(pos);
        rectangle.setFillColor(c);
        window = win;
    }
 
    void update(sf::Time dt)
    {
        pos.x += speed * dt.asSeconds();
        rectangle.setPosition(pos);
 
        if (pos.x > window->getSize().x - size || pos.x < 0)
            speed *= -1;
 
        if (pointInRect(pos.x, pos.y, pos.x + size, pos.y + size, (float)mousePos.x, (float)mousePos.y))
        {
            trails.push_back(new BulletHole(window,
                sf::Vector2f(pos.x - mousePos.x, pos.y - mousePos.y)));
            mousePos = sf::Vector2i(-1, -1);
        }
 
        for(auto trail : trails)
        {
            trail->update(pos);
        }
    }
 
    void draw()
    {
        window->draw(rectangle);
        for (auto trail : trails)
        {
            trail->draw();
        }
    }
 
    void eventHandler(sf::Event event)
    {
        if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
        {
            mousePos = sf::Mouse::getPosition(*window);
        }
    }
 
    sf::Vector2f getPosition()
    {
        return pos;
    }
 
private:
    sf::RectangleShape rectangle;
    sf::RenderWindow* window;
    sf::Vector2f pos;
    sf::Vector2i mousePos = sf::Vector2i(-1, -1);
    int speed = 100;
    float size;
    vector<BulletHole*> trails;
 
    bool pointInRect(float x1, float y1, float x2, float y2, float x, float y)
    {
        if (x > x1 and x < x2 and y > y1 and y < y2)
            return true;
        return false;
    }
};
 
int main()
{
    sf::RenderWindow* window = new sf::RenderWindow(sf::VideoMode(800, 600), "SFML works!");
    
    Target targ = Target(window, 100.f, 100.f, 100.f, sf::Color::Green);
 
    sf::Clock deltaClock;
 
    while (window->isOpen())
    {
        sf::Event event;
        while (window->pollEvent(event))
        {
            targ.eventHandler(event);
 
            if (event.type == sf::Event::Closed)
                window->close();
 
            if (event.key.code == sf::Keyboard::Escape)
            {
                window->close();
            }
        }
 
        sf::Time dt = deltaClock.restart();
 
        window->clear();
        targ.update(dt);
        targ.draw();
        window->display();
    }
 
    delete window;
 
    return 0;
}
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
05.10.2019, 12:37 7
Цитата Сообщение от andrei186 Посмотреть сообщение
Перелопатил много учебных роликов С++ & SFML, но ничего подобного не нашел.
Взял бы книгу, давно бы умел.
0
0 / 0 / 0
Регистрация: 27.09.2019
Сообщений: 29
05.10.2019, 16:38  [ТС] 8
Спасибо, ТабуретY, за готовое решение и за Ваше время.
Работает точно как я хотел. Теперь буду разбираться, как Вы это сделали
0
05.10.2019, 16:38
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.10.2019, 16:38
Помогаю со студенческими работами здесь

Модифицировать разработанное приложение: добавить еще один «летательный» объект
Модифицировать разработанное приложение: добавить еще один «летательный» объект, скорость и...

Линия по щелчку мыши
Здравствуйте! У меня на сцене нарисованы точки, как сделать чтобы рисовалась линия соединяющая...

Заливка по щелчку мыши
Делаю простой пеинт. Создал класс наследник QWidget, в нем переопределил mouseeventы. Хочу сделать...

Пункт меню по щелчку мыши
Пишу будильник. Мне необходимо, чтобы по щелчку на кнопку на панели появлялось два поля (имя, время...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru