pygame에서 키보드 및 마우스 처리는 기본적으로 2가지 방법이 있다.
첫번째 방법은 pygame.event.get()의 타입을 인식하는 것, 두번째는 다른 변수에 기능을 하는 함수를 할당하는 방법이다.
이 글에서는 마우스 처리에 대해 알아보자.
이벤트 | 상세 |
pygame.MOUSEBUTTONUP | 마우스 버튼을 누름 |
pygame.MOUSEBUTTONDOWN | 마우스 버튼을 땜 |
pygame.MOUSEWHEEL | 마우스 휠 감지 |
pygame.MOUSEMOTION | 마우스 움직임 감지 |
1) pygame.event.get()
import pygame,sys
LIGHT_GRAY=(200,200,200);LBLUE=(0,192,255)
BLUE=(0,0,255);RED=(255,0,0)
BLACK=(0,0,0);GREEN=(0,255,0)
screenw,screenh,FPS=400,300,80
mouse_click=None;mouse_move=None
scroll_x,scroll_y=0,0
def main():
global mouse_click,mouse_move,scroll_x,scroll_y
pygame.init()
screen=pygame.display.set_mode((screenw, screenh))
pygame.display.set_caption("mouse_event")
font=pygame.font.SysFont('arial',30,True)
clock=pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
sys.exit()
if event.type==pygame.MOUSEBUTTONUP:
mouse_click=False
elif event.type==pygame.MOUSEBUTTONDOWN:
mouse_click=True
if event.button==1:
print('clicked the left button')
elif event.button==2:
print('clicked the middle button')
elif event.button==3:
print('clicked the right button')
elif event.button==4:
print('Scroll mouse up')
elif event.button==5:
print('Scroll the mouse down')
elif event.type==pygame.MOUSEWHEEL:
print('scroll the mouse')
scroll_x,scroll_y=event.x,event.y
elif event.type==pygame.MOUSEMOTION:
mouse_move=True
print('Mouse is moving')
screen.fill(LIGHT_GRAY)
if mouse_move:
move_text=f"mouse move: {str(mouse_move)}";MOUSE_COLOR=BLUE
mouse_move=False
else:
move_text=f"mouse move: {str(mouse_move)}";MOUSE_COLOR=RED
movetxt=font.render(move_text,True,MOUSE_COLOR)
move_w,_=font.size(move_text)
screen.blit(movetxt,((screenw-move_w)//2,(screenh-_)//2))
click_text=f"mouse click: {str(mouse_click)}"
clicktxt=font.render(click_text,True,GREEN if mouse_click else BLACK)
click_w,_=font.size(click_text)
screen.blit(clicktxt,((screenw-click_w)//2,(screenh-_*3)//2))
scroll_text=f"scroll X: {scroll_x}, scroll Y: {scroll_y}"
scrolltxt=font.render(scroll_text,True,LBLUE)
scroll_w,_=font.size(scroll_text)
screen.blit(scrolltxt,((screenw-scroll_w)//2,(screenh-_*5)//2))
pygame.display.update()
clock.tick(FPS)
if __name__=="__main__":
main()
마우스 버튼을 누르면 pygame.MOUSEBUTTONDOWN가 감지되고 마우스 버튼에서 손을 때면 pygame.MOUSEBUTTONUP가 감지된다. 그래서 이에 맞게 mouse_click의 bool 여부를 두어서 마우스 버튼을 클릭 했는지를 판단이 가능하다.
마우스 휠의 경우 pygame.MOUSEWHEEL와 event.button==4 or 5인지로 판단할 수 있다.분류 측면에서 event.button가 마우스 스크롤을 위로 하는지와 아래로 하는지를 구분한다는 점이 장점이고, pygame.MOUSEWHEEL의 경우 그 이벤트가 발생했을때 유요한 event.x,event.y으로 마우스 휠의 강도를 알 수 있다.기본적으로는 두 값 모두 0이다. event.x이 음수이면 휠을 왼쪽으로, 양수이면 오른쪽으로 스크롤 한 것이고 event.y가 양수이면 휠을 위로, 음수이면 아래로 스크롤 한 것으로, ±1이 나오는 것을 알 수 있는데 스크롤시 강도가 강하면 막 ±6정도까지도 나오는 것을 알 수 있다.
event.button | 상세 |
1 | 마우스 왼쪽 버튼 |
2 | 마우스 가운데 버튼 |
3 | 마우스 오른쪽 버튼 |
4 | 마우스 스크롤 위로 |
5 | 마우스 스크롤 아래로 |
event.button의 경우 pygame.MOUSEBUTTONDOWN이나 pygame.MOUSEBUTTONUP 이벤트가 발생했을때 그 조건문 안에서 사용 가능하다.
( event.button가 6이거나 7일때도 있다고는 하는듯한데 조건은 잘은 모르겠다.)
마우스를 스크롤하거나 마우스 버튼을 눌러보면 CMD창에서 이에 대한 반응을 감지한 것을 확인할 수 있다.
pygame.MOUSEMOTION의 경우 마우스의 움직임을 감지한다. 실행한 screen에서 마우스를 움직여보면 Mouse is moving이라고 cmd창에 뜨는 것을 알 수 있는데, 멈추면 안뜬다. 즉, 움직일때에만 감지한다. 하지만 pygame.MOUSEMOTION에 대해 반대되는 조건문이 없기 때문에 mouse_move를 하면에 표시하려면 좀 코드를 꼬아야한다. pygame.MOUSEMOTION가 감지되면 mouse_move를 True로 변경하고 이에 대한 조건문으로 mouse_move==True일때에 대한 조건문으로 mouse_move=False가 있는 것에 의문을 가질 수 있는데, 마우스를 움직일때마다 pygame.MOUSEMOTION가 감지되어 mouse_move가 계속 True가 되며 이에 대한 반대 조건문이 없기에 한 번의 이동에 대해 'mouse move: True' 텍스트가 한 번만 화면에 표시되도록 하기 위한 것
으로 만약 mouse_move=False가 없다면 화면에는 계속 'mouse move: True'만이 뜰 것이다.
2)pygame.mouse.get_pos()
마우스의 위치를 가져오는 함수이다.
mouse_x,mouse_y=pygame.mouse.get_pos()
mouse_x: screen 기준 마우스 포인터의 x좌표
mouse_y: screen 기준 마우스 포인터의 y좌표
특정 위치에 어떤 객체라던지 뭐 버튼이라던지를 넣고 싶을 때에 위치를 모르겠으면 이 함수를 화면에 txt로 0,0과 같은 곳에 띄어두고 확인해보면 좌표를 알아내는 것이 도움이 될 수 있다.
import pygame,sys
LIGHT_GRAY=(200,200,200)
LIGHT_MOSS_GREEN=(143,188,143)
LBLUE=(0,192,255)
screenw,screenh,FPS=700,700,80
def main():
pygame.init()
screen=pygame.display.set_mode((screenw,screenh))
pygame.display.set_caption("mouse_pos")
font=pygame.font.SysFont('arial',30,True)
clock=pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill(LIGHT_GRAY)
mouse_x,mouse_y=pygame.mouse.get_pos()
mouse_pos_text=f"mouse pos: {mouse_x}, {mouse_y}"
font_w,font_h=font.size(mouse_pos_text)
mousetxt=font.render(mouse_pos_text,True,LBLUE)
screen.blit(mousetxt,((screenw-font_w)//2,(screenh-font_h)//2))
pygame.draw.circle(screen,LIGHT_MOSS_GREEN,(mouse_x,mouse_y),10)#24줄
pygame.display.update()
clock.tick(FPS)
if __name__=="__main__":
main()
24줄을 보면 pygame.draw.circle을 통해 마우스의 위치를 가져와서 마우스 포인터를 다르게 꾸며줄 수도 있다.
3)pygame.mouse.set_visible(bool)
screen에 마우스 포인터를 표시할지 여부이다.
기본적으로는 True이며, False일때는 screen안에 마우스 포인터가 있을때 안보인다.
pygame.mouse.set_visible(False)를 바로 위 코드에 넣어보면 포인터가 안보이는 것을 알 수 있다.
4)pygame.mouse.get_focused()
screen 안에 마우스 포인터가 있는지 여부이다.
값이 1이면 screen 안에 마우스 포인터가 있는 것이고, 값이 0이면 screen 밖에 있는 것이다.
응용해보기)
import pygame,sys
LIGHT_GRAY=(200,200,200);LBLUE=(0,192,255)
BLUE=(0,0,255);RED=(255,0,0);LIGHT_GREEN=(195,255,100)
GREEN=(0,255,0)
BLACK=(0,0,0);WHITE=(255,255,255)
screenw,screenh,FPS=700,700,80
mouse_click=None;mouse_move=None;mouse_lclick=None
start_pos=None;scroll_x,scroll_y=0,0
def main():
global mouse_click,mouse_lclick,mouse_move,start_pos,scroll_x,scroll_y
pygame.init()
screen=pygame.display.set_mode((screenw,screenh))
pygame.display.set_caption("mouse_utilize")
font=pygame.font.SysFont('arial',30,True)
clock=pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
sys.exit()
if event.type==pygame.MOUSEBUTTONUP:
mouse_click=False
mouse_lclick=False
elif event.type==pygame.MOUSEBUTTONDOWN:
mouse_click=True
if event.button==1:
print('clicked the left button')
start_pos=pygame.mouse.get_pos()
mouse_lclick=True
elif event.button==2:
print('clicked the middle button')
elif event.button==3:
print('clicked the right button')
elif event.button==4:
print('Scroll mouse up')
elif event.button==5:
print('Scroll the mouse down')
elif event.type==pygame.MOUSEWHEEL:
scroll_x,scroll_y=event.x,event.y
elif event.type==pygame.MOUSEMOTION:
mouse_move=True
print('Mouse is moving')
screen.fill(LIGHT_GRAY)
mouse_x,mouse_y=pygame.mouse.get_pos()
mouse_pos_text = f"mouse pos: {mouse_x}, {mouse_y}"
mousetxt=font.render(mouse_pos_text,True,LBLUE)
screen.blit(mousetxt,(0,0))
if mouse_move:
move_text=f"mouse move: {str(mouse_move)}";MOUSE_COLOR=BLUE
mouse_move=False
else:
move_text=f"mouse move: {str(mouse_move)}";MOUSE_COLOR=RED
if start_pos and mouse_lclick:
end_pos=pygame.mouse.get_pos()
pygame.draw.line(screen,LIGHT_GREEN,start_pos,end_pos,1)
movetxt=font.render(move_text,True,MOUSE_COLOR)
move_w,move_h=font.size(move_text)
screen.blit(movetxt,((screenw-move_w)//2,(screenh-move_h)//2))
click_text=f"mouse click: {str(mouse_click)}"
clicktxt=font.render(click_text,True,GREEN if mouse_click else WHITE)
click_w,click_h=font.size(click_text)
screen.blit(clicktxt,((screenw-click_w)//2,(screenh-click_h*3)//2))
pygame.mouse.set_visible(False)
pygame.draw.circle(screen,BLUE,(mouse_x,mouse_y),10)
pygame.draw.circle(screen,LBLUE,(mouse_x,mouse_y),6)
pygame.display.update()
clock.tick(FPS)
if __name__=="__main__":
main()
이를 실행하면 마우스를 좌클릭을 하면 시작점이 좌클릭한 위치, 끝점이 마우스 포인터가 되는 선이 그려지는 것을 알 수 있다.
pygame.MOUSEBUTTONDOWN에서 event.button==1을 통해 마우스를 누른 당시의 위치를 start_pos에 대입하고 mouse_lclick 즉, 좌클릭 유무를 True로 설정한다.
pygame.event.get()의 경우 True가 되면 이에 묶인 if문을 1번만 실행하기에 이런 접근법이 가능하다.
if start_pos and mouse_lclick:의 경우 마우스를 클릭한 후에만 start_pos에 유효한 좌표 값이 할당되기에 start_pos가 None이 아닌지 확인하는 것이다. 이 조건문이 True일때에 좌클릭을 한 상태라는 것이기에 이때 end_pos를 계속적으로 업데이트하면서 pygame.draw.line을 통해 선을 화면에 그리는 것이다.
pygame.draw.circle을 이용해 마우스 포인터의 위치를 원으로 그릴 때, 후속으로 그려지는 도형이 앞서 그려진 도형을 덮어쓰게 된다. 하지만 후속으로 그린 도형의 크기를 앞선 도형보다 작게 설정했기 때문에 하늘색 원이 파란색 원 위에 덮어지며 원 안에 작은 원이 그려지는 형태로 그려지게 된다.
'python study > import pygame' 카테고리의 다른 글
python) pygame,키보드 처리(대소문자 처리) (2) (0) | 2024.12.28 |
---|---|
python) pygame,키보드 처리 (1) (0) | 2024.12.27 |
python)pygame, font(+개행문자 문제 해결 방법) 텍스트 띄우기(2) (0) | 2024.12.27 |
python)pygame, font(+한글 띄우기) 텍스트 띄우기(1) (0) | 2024.12.26 |
python)pygame에서 동적 그림 처리, 제대로 이해하기 (0) | 2024.12.25 |