Coding & Programming/C, C++, SFML

[C/C++, SFML] 8. 마우스 이벤트(Event) 및 상태(State) 처리하기

mainCodes 2021. 4. 1. 09:50

안녕하세요 JollyTree입니다 (•̀ᴗ•́)و

 

오늘 다룰 내용은 SFML에서 sf::Mouse 클래스와 마우스 이벤트 처리에 대한 내용입니다.

 

sf::Mouse 클래스는 마우스의 이동(Moved), 키눌림(Pressed), 키 떼임(Released) 등 상태에 대한 인터페이스를 제공합니다.  event.typeevent.key.code의 상태에 따라  Event::MouseButtonPressed, Event::MouseButtonReleased, Event::MouseMoved, Event::MouseWheelMoved:, Event::MouseWheelScrolled: 등에 따라 마우스의 상태를 파악할 수 있습니다. 

 

다음 실행 화면은 마우스 상태를 콘솔에 출력하고 마우스 이동과 버튼 클릭에 따라 원(Circle)의 위치와 색을 변경하는 화면입니다.

SFML 마우스 이벤트 및 상태 처리

 SFML에서 마우스 버튼은 enum sf:Mouse::Button 으로 Left, Right, Middle, XButton1, XButton2, ButtonCount로 나열 되어 있습니다. 제 마우스는 버튼이 딱 3개(Left, Right, Middle)이어서 XButton1, XButton2는 테스트하지 못했습니다. 이해 바랍니다.

 

sf::Mouse::setPosition, sf::Mouse::getPosition 메소드는 마우스 위치 변경, 그리고 마우스 포인터의 현재 위치 정보를 얻는데 사용됩니다. 

 

아래 예제는 SFML의 마우스 처리(Button Pressed, Button Released, Moved, WheelMoved, WheelScrolled 등)에 대한 내용을 포함하고 있습니다. 마우스 버튼 클릭, 릴리즈, 휠 스크롤 시에 마우스의 현재 위치를 출력하게 해놓았습니다. 그리고 마우스 이동시 화면에 있는 원이 함께 움직이는 예제를 포함하고 있으니 참고하세요.

 

특히 마우스 눌림과 떼임은 여러 프로그램에서 많이 사용되는 이벤트입니다. 개발하고자 하는 프로그램의 화면 구성과 마우스 눌림 또는 떼임 위치는 밀접하게 관련이 있습니다.

 

SFML Mouse 이벤트 및 상태 처리 예제 코드(Example): 

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
146
#include <SFML/Graphics.hpp>
#include <iostream>
 
using namespace std;
using namespace sf;
 
#define CIRCLE_RADIUS   100.f
 
int main()
{
    int x=0, y=0;
 
    //마우스 이동시 따라 움직일 Circle 객체
    CircleShape circle_shape(CIRCLE_RADIUS);
    circle_shape.setFillColor(Color::Green);
 
    circle_shape.setRadius(CIRCLE_RADIUS);
    circle_shape.setOutlineColor(sf::Color::Red);
    circle_shape.setOutlineThickness(20);
    circle_shape.setPosition(x, y);
 
    cout << "프로그램이 시작되었습니다." << endl;
 
    //화면 크기, 캡션 이름 설정
    RenderWindow app(VideoMode(504504), "https://maincodes.tistory.com/");
    app.setFramerateLimit(60);  //프레임 비율 설정
 
    //SFML 메인 루프 - 윈도우가 닫힐때 까지 반복
    while (app.isOpen())
    {
        Event event;
 
        //이벤트 처리
        while (app.pollEvent(event))
        {
            //프로그램 종료 이벤트 처리
            if (event.type == Event::EventType::Closed)
            {
                app.close();
                cout << "프로그램이 종료되었습니다." << endl;
            }
 
            //마우스 버튼 눌림(Pressed) 이벤트
            if (event.type == Event::MouseButtonPressed)
            {
                switch (event.key.code)
                {
                    case Mouse::Left:
                    {
                        circle_shape.setFillColor(Color::Yellow);
                        Vector2i pos = Mouse::getPosition(app);
                        cout << "왼쪽 버튼 눌림 : pos.x = " << pos.x << " pos.y = " << pos.y << endl;
                        break;
                    }
 
                    case Mouse::Right:
                    {
                        circle_shape.setFillColor(Color::Magenta);
                        Vector2i pos = Mouse::getPosition(app);
                        cout << "오른쪽 버튼 눌림 : pos.x = " << pos.x << " pos.y = " << pos.y << endl;
                        break;
                    }
 
                    case Mouse::Middle:
                    {
                        circle_shape.setFillColor(Color::Black);
                        Vector2i pos = Mouse::getPosition(app);
                        cout << "중간 버튼 눌림 : pos.x = " << pos.x << " pos.y = " << pos.y << endl;
                        break;
                    }
                }
 
            }
 
            //마우스 버튼 뗌(Released) 이벤트
            if (event.type == Event::MouseButtonReleased)
            {
                switch (event.key.code)
                {
                    case Mouse::Left:
                    {
                        Vector2i pos = Mouse::getPosition(app);
                        cout << "왼쪽 버튼 뗌 : pos.x = " << pos.x << " pos.y = " << pos.y << endl;
                        circle_shape.setFillColor(Color::Green);
                        break;
                    }
                    case Mouse::Right:
                    {
                        Vector2i pos = Mouse::getPosition(app);
                        cout << "오른쪽 버튼 뗌 : pos.x = " << pos.x << " pos.y = " << pos.y << endl;
                        circle_shape.setFillColor(Color::Green);
                        break;
                    }
                    case Mouse::Middle:
                    {
                        Vector2i pos = Mouse::getPosition(app);
                        cout << "중간 버튼 뗌 : pos.x = " << pos.x << " pos.y = " << pos.y << endl;
                        circle_shape.setFillColor(Color::Green);
                        break;
                    }
                }
            }
 
            //마우스 움직임 이벤트
            switch (event.type)
            {
                case Event::MouseMoved:
                {
                    Vector2i pos = Mouse::getPosition(app);
                    cout << "이동 : pos.x = " << pos.x << " pos.y = " << pos.y << endl;
                    x = pos.x;
                    y = pos.y;
                    break;
                }
 
                //마우스 휠 움직임 이벤트
                case Event::MouseWheelMoved:
                {
                    Vector2i pos = Mouse::getPosition(app);
                    cout << "휠 이동 : pos.x = " << pos.x << " pos.y = " << pos.y << endl;
                    break;
                }
 
                //마우스 휠 스크롤 이벤트
                case Event::MouseWheelScrolled:
                {
                    Vector2i pos = Mouse::getPosition(app);
                    cout << "휠 스크롤 : pos.x = " << pos.x << " pos.y = " << pos.y << endl;
                    break;
                }
            }
        }
 
        //배경화면을 흰색으로 clear
        app.clear(Color::White);
 
        //Circloe 위치 보정
        circle_shape.setPosition(Vector2f(x - 100.f, y - 100.f));
        app.draw(circle_shape);
 
        //프레임을 스크린에 출력
        app.display();
    }
 
    return 0;
}
cs

 

예제는 마우스 포인터가 SFML의 메인윈도우 밖으로 벗어날 경우 아무런 이벤트를 받지 않습니다. 따라서 버튼 눌림, 떼임, 마우스 이동 등의 마우스 상태에 대한 아무런 정보를 출력하지 않습니다.

 

실행결과(Output):

 

 

다음 포스팅은 키보드 이벤트와 상태정보를 얻는 방법에 대해 정리할 계획입니다. 이상 JollyTree였습니다 (•̀ᴗ•́)و