pygame에서 키보드 및 마우스 처리는 기본적으로 2가지 방법이 있다.
첫번째 방법은 pygame.event.get()의 타입을 인식하는 것, 두번째는 다른 변수에 기능을 하는 함수를 할당하는 방법이다.
이 글에서는 키보드 처리에 대해 알아보겠다.
공통) 키보드 상수
키 | 상수 |
Function 키 (Fm/m=숫자) | K_F1~K_F12 |
숫자 키 (0~9) | K_0~K_9 |
알파벳 키 (A~Z && a~z) | K_a~K_z( 대소문자 판별하지 못함) |
Esc 키 (ESC) | K_ESCAPE |
` 키(백틱 키) | pygame.K_BACKQUOTE |
- 키 | pygame.K_MINUS |
+ 키 | pygame.K_PLUS |
| 키 | pygame.K_BACKSLASH |
Backspace 키 | pygame.K_BACKSPACE |
Tab 키 | pygame.K_TAB |
{ 키 | pygame.K_LEFTBRACKET |
} 키 | pygame.K_RIGHTBRACKET |
ENTER 키 | K_RETURN |
Caps Lock 키 | pygame.K_CAPSLOCK / pygame.KMOD_CAPS |
: 키 | pygame.K_COLON |
' 키 (작은따옴표) | pygame.K_QUOTE |
Shift 키 | K_RSHIFT, K_LSHIFT, KMOD_SHIFT(=KMOD_RSHIFT || KMOD_LSHIFT) |
, 키(< 키) | pygame.K_COMMA |
. 키(> 키) | pygame.K_PERIOD |
/ 키(? 키) | pygame.K_SLASH |
Ctrl 키 | pygame.K_LCTRL,pygame.K_RCTRL, pygame.KMOD_CTRL(= KMOD_LCTRL || pygame.KMOD_RCTRL ) |
Fn 키 | 없음 |
GUI 키(윈도우의 window키, 맥의 커맨드키) | GUI 키는 일반적으로 Windows 키와 Mac의 커맨드 키 모두를 포함하는 용어 pygame.K_LGUI, pygame.K_RGUI,pygame.KMOD_GUI(=pygame.KMOD_LGUI || pygame.KMOD_RGUI) |
Alt 키 | pygame.K_LALT,pygame.K_RALT, pygame.KMOD_ALT(= pygame.KMOD_LALT || pygame.KMOD_RALT ) |
한자 키 | 없음 but, pygame.key.get_mods()로 감지시 128이라는 값을 가짐(즉, pygame.K_RCTRL으로 인식됨) |
Space 키 | K_SPACE |
한/영 키 | 없음 |
Menu 키 | pygame.K_MENU |
PrtSc 키 | pygame.K_PRINTSCREEN |
Scroll Lock 키 | pygame.K_SCROLLLOCK |
Pause/Break 키 | pygame.K_PAUSE |
Insert 키 | pygame.K_INSERT |
Home 키 | pygame.K_HOME |
Page Up 키 | pygame.K_PAGEUP |
Delete 키 | pygame.K_DELETE |
End 키 | pygame.K_END |
Page Down 키 | pygame.K_PAGEDOWN |
방향 키 | K_UP, K_LEFT, K_DOWN, K_RIGHT |
숫자 키패드 0~9 | pygame.K_KP0~pygame.K_KP9 |
Num Lock 키 | pygame.K_NUMLOCK |
숫자 키패드의 나누기 | pygame.K_KP_DIVIDE |
숫자 키패드의 곱하기 | pygame.K_KP_MULTIPLY |
숫자 키패드의 빼기 | pygame.K_KP_MINUS |
숫자 키패드의 더하기 | pygame.K_KP_PLUS |
숫자 키패드의 엔터 키 | pygame.K_KP_ENTER |
숫자 키패드의 소수점 키 | pygame.K_KP_PERIOD |
------ ------ 이 외 ------ ------ | |
Application 키 | pygame.K_APPLICATION (일부 키보드에 있는 추가 메뉴 열기 키) |
알 수 없는 키 | pygame.K_UNKNOWN |
알파벳 키의 대소문자를 판별하는 방법의 경우 코드 실행 전에 Caps Lock가 켜진 상태로 실행한다면 제대로 인식이 안되기에 다른 방법을 사용해야한다. 이에 대해서는 다음 글에서 다룬다.
1) keyboard, pygame.event.get()
기본적으로 event.type가 어떤 값이냐?에 따라 판별한다.
keyboard와 관련된 event.type은 KEYUP, KEYDOWN가 있다.
import pygame,sys
LIGHT_GRAY=(200,200,200);LBLUE=(0,192,255);BLACK=(0,0,0)
screenw,screenh,FPS=700,700,80
event_key=None
def main():
global event_key
pygame.init()
screen=pygame.display.set_mode((screenw, screenh))
pygame.display.set_caption("keyboard_event")
font=pygame.font.SysFont('hy견고딕',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.KEYDOWN:
# if event.key==pygame.K_w:#1번만 실행됨
print(1)
event_key='Key Press'
if event.type==pygame.KEYUP:
if event.key==pygame.K_w:#1번만 실행됨
print(2)
event_key='Key Release'
screen.fill(LIGHT_GRAY)
keytxt=font.render(event_key,True,LBLUE)
screen.blit(keytxt,(100,100))
pygame.display.update()
clock.tick(FPS)
if __name__ == "__main__":
main()
event.type에서 KEYDOWN은 키가 눌렸을 때를, KEYUP은 키가 떼졌을 때를 판별한다.
if event.key==pygame.K_w:는 눌린 키가 w인지 확인하는 조건문이다.(이때 w는 대문자와 소문자 모두를 포함한다.)
이후에 다룰 2번 방식과 다르게 1번 방식을 써야지만 할 수 있는 것이 있는데, KEYDOWN을 감지하여 키가 눌렸을 때 이를 처리하고, KEYUP을 감지하여 키가 떼졌을 때 다른 동작을 수행하게 할 수 있는 1번의 방식은 특별한 상황을 구현할 수 있다. 이 방식으로, 키가 눌린 상태에서 다시 그 키를 떼지 못하도록 하는 조건을 구현할 수도 있다.
하지만 이 방식은 while True 바로 아래에 있는 for event in pygame.event.get()에서 사용할 경우, 한 번 더 for문을 돌리게 되므로 2번 방식과 비교하여 상대적으로 비용이 많이 들 수 있다.
예를 들어, 특정 페이지로 넘어가지 않은 상태에서는 이전 페이지와 새 페이지의 키 설정을 다르게 해야 하는데, 이때 이런 문제점이 발생할 수 있다.
2) keyboard, pygame.key.get_pressed()
다른 방법은 pygame.key.get_pressed()를 key 변수에 실시간으로 할당하여 사용하는 방식이다.
import pygame,sys
LIGHT_GRAY=(200,200,200);LBLUE=(0,192,255)
screenw,screenh,FPS=700,700,80
event_key=None
def main():
global event_key
pygame.init()
screen=pygame.display.set_mode((screenw,screenh))
pygame.display.set_caption("keyboard")
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)
key=pygame.key.get_pressed()
if key[pygame.K_q]:
print(1)
event_key='key Q'
else:
event_key='Key Q Not Pressed'
event_key_w,_=font.size(event_key)
keytxt=font.render(event_key,True,LBLUE)
screen.blit(keytxt,(screenw//2-event_key_w//2,screenh//2))
pygame.display.update()
clock.tick(FPS)
if __name__ == "__main__":
main()
key=pygame.key.get_pressed()에 현재 어떤 키가 눌리는지를 할당하고 key[K_key]로 판별하는 방법이다.
이 경우 변수(key와 같은)를 쓰긴 하지만 이전 방법과 달리 for문에서 벗어난다는 점, 또한 나중에 따로 써야할 때에 1번 방법에 비해 상대적으로 적은 비용을 쓸 수 있다는 점에서 장점이라고 할 수 있다.
3) keyboard, pygame.event.get() VS pygame.key.get_pressed()
앞에서 추가로 말했던 두가지 방법의 특성에 대해 이야기 했는데 또 다른 차이가 있다.
import pygame,sys
LIGHT_GRAY=(200,200,200);LBLUE=(0,192,255);BLACK=(0,0,0)
screenw,screenh,FPS=700,700,80
event_key=None
def main():
global event_key
pygame.init()
screen=pygame.display.set_mode((screenw,screenh))
pygame.display.set_caption("keyboard_all_alphabet_keys")
font=pygame.font.SysFont('arial',30,True)
clock=pygame.time.Clock()
key_map={
pygame.K_a:"Key A Pressed",pygame.K_b:"Key B Pressed",pygame.K_c:"Key C Pressed",pygame.K_d:"Key D Pressed",
pygame.K_e:"Key E Pressed",pygame.K_f:"Key F Pressed",pygame.K_g:"Key G Pressed",pygame.K_h:"Key H Pressed",
pygame.K_i:"Key I Pressed",pygame.K_j:"Key J Pressed",pygame.K_k:"Key K Pressed",pygame.K_l:"Key L Pressed",
pygame.K_m:"Key M Pressed",pygame.K_n:"Key N Pressed",pygame.K_o:"Key O Pressed",pygame.K_p:"Key P Pressed",
pygame.K_q:"Key Q Pressed",pygame.K_r:"Key R Pressed",pygame.K_s:"Key S Pressed",pygame.K_t:"Key T Pressed",
pygame.K_u:"Key U Pressed",pygame.K_v:"Key V Pressed",pygame.K_w:"Key W Pressed",pygame.K_x:"Key X Pressed",
pygame.K_y:"Key Y Pressed",pygame.K_z:"Key Z Pressed"
}
while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
sys.exit()
if event.type==pygame.KEYUP:
print("No Key Pressed")
screen.fill(LIGHT_GRAY)
key=pygame.key.get_pressed()
event_key="No Key Pressed"
for k,text in key_map.items():
if key[k]:
event_key=text
print("Key Pressed")
break
event_key_w,_=font.size(event_key)
keytxt=font.render(event_key,True,LBLUE)
screen.blit(keytxt,(screenw//2-event_key_w//2,screenh//2))
pygame.display.update()
clock.tick(FPS)
if __name__ == "__main__":
main()
이 코드를 실행해보면 알 수 있는 점이 항상 키를 누른 후 때면 cmd창의 print함수의 경우 No Key Pressed가 1번만 가장 뒤에 찍혀 있는 것을 알 수 있다.
이는 pygame.event.get() 방법의 경우 특정 키를 누르거나 땠을때에 그 순간만 1번만 True가 되기에 while True에 대한 영향을 받지 않는다는 사실을 알 수 있다.
pygame.key.get_pressed() 방법의 경우 특정 키가 True이면 그 가정문에 영향 받는 코드문이 while True에 대한 영향을 받는다.
pygame의 함수들은 기본적으로 while True에 최적화되어서 O(n)인 체제에서 O(1)이 구현되어있지만 이 외의 함수나 연산자 등은 O(n)으로 영향을 받기에 이 차이를 아는 것이 중요하다고 할 수 있다.
이 외의 함수나 연산자 등을 pygame의 while True 안에서 O(1)을 구현할 수 있는 방법에 대해서는 나중에 따로 다루겠다.
'python study > import pygame' 카테고리의 다른 글
python)pygame, 마우스 처리, 클릭과 움직임 감지 및 좌표 얻어오기 (0) | 2025.01.02 |
---|---|
python) pygame,키보드 처리(대소문자 처리) (2) (0) | 2024.12.28 |
python)pygame, font(+개행문자 문제 해결 방법) 텍스트 띄우기(2) (0) | 2024.12.27 |
python)pygame, font(+한글 띄우기) 텍스트 띄우기(1) (0) | 2024.12.26 |
python)pygame에서 동적 그림 처리, 제대로 이해하기 (0) | 2024.12.25 |