SqueakByExample:11.5
상호 작용과 애니메이션
morph 모프를 사용해서 생동감있는 유저 인터페이스를 만들려면, 마우스와 키보드를 사용하여 인터페이스와 상호작용이 가능해야 합니다. 더군다나 morph 는 스스로의 모양새와 위치-자신에 대한 애니메이션을 사용해서-를 변경함으로서 유저로 부터의 입력에 반응할 수 있어야 합니다.
마우스 이벤트
마우스 버튼을 눌렀을때, Morphic 은 각 morph 를 대상으로 handlesMouseDown: 메시지를 전송합니다. 만약 morph 가 true 를 반환하면, Morphic 은 즉시 morph 에게 mouseDown: 메시지를 보내며, 유저가 마우스 버튼에서 손을 뗐을때는 mouseUp: 메시지를 전송합니다. 만약 모든 morph 가 false 를 반환하는경우, Morphic 은 드래그앤드롭의 동작을 시작합니다. 아래에서 알아볼 내용에도 있겠지만, mouseDown: 과 mouseUp: 메시지는, MouseEvent 객체의 인자를 포함해서 전송됩니다.
CrossMorph 를 확장해서 마우스 이벤트를 취급할 수 있도록 해보겠습니다. 일단 crossMorphs 의 모든 morph 가 handlesMouseDown: 에 true 를 반환하게 하는것부터 시작하도록 하겠습니다.
이 메서드를 CrossMorph 클래스에 추가하십시오.
메서드 11.12: CrossMorph 가 마우스 클릭에 반응하도록 선언합니다.
CrossMorph>>handlesMouseDown: anEvent
↑true
붉은 버튼을 클릭했을때 십자의 색상을 빨강으로 변경하고, 노랑 버튼이 클릭될때는 색상을 노랑으로 변경하기를 원한다고 가정해 보도록 하겠습니다. 이 작업은 메서드 11.13 을 이용해서 실행할 수 있습니다.
메서드 11.13: 마우스 클릭에 반응해서 morph 의 색상을 변경하기
CrossMorph>>mouseDown: anEvent
anEvent redButtonPressed
ifTrue: [self color: Color red].
anEvent yellowButtonPressed
ifTrue: [self color: Color yellow].
self changed
이 메서드에서 morph 의 색상을 변경한 다음 self changed 를 보낸다는것에 주의합시다. 이 self 부분 때문에 Morphic 은 즉시 drawOn: 을 보내게 됩니다. 추가로, morph 가 마우스 이벤트를 처리하면 유저는 더이상 morph 를 마우스로 잡아서 이동시킬 수 없게된다는걸 유념해 주시기 바랍니다. 이동등의 작업을 하고싶은 경우는 할로를 사용해야만 합니다: 할로를 보이게 하기 위해서 morph 를 파랑 클릭하고 morph 상단에서 morph를 파랑 클릭하고, 모프 상단에서 갈색 이동 손잡이과 검정색 픽업 손잡이 중 하나를 잡습니다.
mouseDown: 메서드의 인수인 anEvent 는 MorphicEvent 의 서브클래스인 MouseEvent 의 인스턴스 입니다. MouseEvent 에는 redButtonPressed 와 yellowButtonPressed 메서드가 정의되어 있습니다. 마우스 이벤트를 취급하는 메서드는 어떤것들이 있는지 알고싶다면, MouseEvent 클래스를 살펴보면 됩니다.
키보드 이벤트
키보드 이벤트를 얻기위해, 다음의 3 가지 단계들을 거처야 합니다.
- 특정 morph 에 "keyboard focus" 를 부여합니다: 예를 들면, 마우스가 morph 위에 있는경우 해당 morph 에 focus 를 부여할 수 있습니다.
- handleKeystroke: 메서드를 사용해서 morph 가 키보드 이벤트를 처리하게 합니다: 이 메시지는 유저가 키를 눌렀을때, 키보드 포커스를 가지고 있는 morph 에 전송됩니다.
- 마우스의 포인터가 더 이상 대상이 되는 morph 위에 위치하지 않는경우, keyboard focus 를 release 합니다.
CrossMorph 를 확장해서, 키입력에 반응하도록 만들겠습니다. 첫번째로, 마우스의 포인터가 대상이 되는 morph 위에 있는경우 알림을 받도록 해야할거같군요. 이 알림은, 만약 대상이 되는 morph 가 handlesMouseOver: 메시지에 true 를 반환할때 발생합니다.
마우스 포인터 아래에 있을 때, CrossMorph 가 반응하도록 선언하십시오.
메서드 11.14: "mouse over" 이벤트를 처리할 수 있게 합니다.
CrossMorph>>handlesMouseOver: anEvent
↑true
마우스 위치에 대한 처리는 handlesMouseDown: 과 같습니다. 마우스 포인터가 morph 에 들어가거나 바깥으로 이동할때 mouseEnter: 와 mouseLeave: 메시지가 morph 로 전달됩니다.
2 개의 메서드를 정의해서 CrossMorph 가 keyboard focus 를 붙잡거나 놓고, 세 번째 메서드가 실제로 키보드입력을 취급하도록 정의하십시오.
메서드 11.15: 마우스가 morph 에 들어갈 때, keyboard focus 얻기
CrossMorph>>mouseEnter: anEvent
anEvent hand newKeyboardFocus: self
메서드 11.16: 마우스 포인터를 바깥쪽으로 이동시키면, 초점은 원래 있던 자리로 돌아갑니다.
CrossMorph>>mouseLeave: anEvent
anEvent hand newKeyboardFocus: nil
메서드 11.17: 키보드 이벤트를 수신하고 전달하기
CrossMorph>>handleKeystroke: anEvent
| keyValue |
keyValue := anEvent keyValue.
keyValue = 30 "up arrow"
ifTrue: [self position: self position - (0 @ 1)].
keyValue = 31 "down arrow"
ifTrue: [self position: self position + (0 @ 1)].
keyValue = 29 "right arrow"
ifTrue: [self position: self position + (1 @ 0)].
keyValue = 28 "left arrow"
ifTrue: [self position: self position - (1 @ 0)]
커서 키를 이동하고 morph 를 움직일 수 있는 메서드를 작성했습니다. 마우스가 더이상 대상이 되는 morph 의 영역에 없을때, handleKeystroke: 메시지는 전송되지 않기때문에, morph 는 키보드입력에 대한 반응을 하지 않게 됩니다. 키보드 입력값을 찾기위해서, Transcript 창에 값을 출력하기 위한 Transcript show: anEvent keyValue 내용을 메서드 11.17 에 추가할 수 있습니다. handleKeystroke: 의 anEvent 인수는 KeyboardEvent 의 인스턴스이며, MorphicEvent 의 서브클래스입니다. 키보드 이벤트에 대해 좀 더 알고싶다면 이 클래스를 살펴보시기 바랍니다.
Morphic 애니메이션
Morphic 은 2 개의 메인 메서드로 구성되는 간단한 애니메이션 시스템을 제공합니다: stepTime 은 각 스텝 사이의 시간간격을 밀레세컨드단위로 지정하고, step[1]은 일정한 간격으로 morph 에 전송됩니다. 덧붙여서, startStepping 은 스태핑 메커니즘을 on 으로 전환하고, stopStepping 은 그 스태핑 메커니즘을 off 상태로 다시 전환합니다. isStepping 은 morph 가 현재 한 단계씩 진행되는지의 여부를 확인하려 할때 사용합니다.
이 메서드들을 다음과 같이 정의하여 CrossMorph 를 깜박이도록 만드십시오.
메서드 11.18: 애니메이션 시간 간격 정의하기
CrossMorph>>stepTime
↑ 100
메서드 11.19: 애니메이션에서 step 만들기
CrossMorph>>step
(self color diff: Color black) < 0.1
ifTrue: [self color: Color red]
ifFalse: [self color: self color darker]
구현한 애니메이션을 시작하기 위해서, CrossMorph 상의 Inepector 를 열어 할로(할로의 디버그 핸들을사용)아래쪽의 작은 Workspace 패널 에 self startStepping 을 입력하고 do it 을 실행합니다. 보조수단을 위해, handleKeystroke: 메서드를 수정하여, + 키와 –키 로 스테핑의 시작와 정지가 가능하게 할 수 있습니다.
다음 코드를 메서드 11.17에 추가하십시오.
keyValue = $+ asciiValue
ifTrue: [self startStepping].
keyValue = $- asciiValue
ifTrue: [self stopStepping].
Notes
- ↑ stepTime 은 실제로 각 스탭 사이의 최소 시간을 의미합니다. 만약 1ms 의 stepTime 을 요청하면, 스퀵이 너무나 바빠서 사용자의 morph 를 그 정도로 자주 한 단계씩 전환하지 못한다는 사실에 놀라지 마십시오.