F#7 Layer.stateCycle()로 두더지 잡기

 

F#6을 포스팅하면서 머릿속을 스쳐간 ‘두더지 잡기 게임’을 간단하게 만들어 보았다.

이번에 유용하게 쓴 코드를 세 가지 추려 본다면 이것이다.

Utils.randomNumber()

Utils.delay 숫자, ->

Layer.stateCycle()

#LAYER

레이어는 가로로 3개를 먼저 반복시켜주고, 3개 묶음을 다시 세로로 3회 반복시켜 총 9개의 홀에서 두더지가 튀어나오도록 했다.

for i in [0…3]
gameBox = new Layer
width: 280
height: 100
backgroundColor: “”
y: i * 100
parent: gameArea
for i in [0…3]
realHole = new Layer
width: 60
height: 80
borderRadius: 80
backgroundColor: “”
clip: true
parent: gameBox
x: i * 100 + 10
#hole의 maxY값을 realHome의 높이값으로 지정했다. 이것은 눈속임
hole = new Layer
width: 60
height: 60
borderRadius: 60
backgroundColor: “#AED4CD”
maxY: realHole.height
parent: gameBox
x: i * 100 + 10
hole.sendToBack()
#두더지 얼굴 만들기
moleBody = new Layer
width: 50
height: 100
borderRadius: 65
parent: realHole
x: Align.center
y: Align.bottom(+72)
backgroundColor: “#D56829”
clip: true

 

두더지의 생김새가 매우 간단하기 때문에 프레이머의 코드 탭에서 얼굴을 표현해보기로 했다. 얼굴에는 약간의 하이라이트를 주고 눈썹, 눈, 입 레이어를 추가해 반복시켜주었다. 이때 양쪽 눈썹의 각도와 입의 크기는 Utils.randomNumber() 를 이용해 다양한 표정을 레이어링 해 보았다.

다음은 점수를 표시할 텍스트레이어. F#5에서 공부했던, 클릭 시 증가하는 카운트를 위한 레이어 세팅이다.

count = 0
score = new TextLayer
text: count + ” 마리 잡았다!”
x: Align.center()
y: gameArea.maxY + 40
color: “lightgray”
fontSize: 20
fontWeight: 700
textAlign: “center”

 

#STATES

두더지가 랜덤하게 튀어나오려면 애니메이션에 대한 코드를 어떤 식으로 작성해야 하는 것일까. 반복문은 나의 취약점이다. 반복해 준 레이어를 통에 넣는 순간 어찌할 바를 모르게 된다. 레이어링까지는 간단히 해결 하였는데…그 다음부터 스멀스멀 멘붕이 오기 시작함.

이 9마리 두더지들에게 각각 인덱스 번호를 매겨주어야 하는 게 아닐까? 그리고 튀어오르는 애니메이션 하나를 정의한 다음, 두더지 번호들을 랜덤하게 호출하면 랜덤하게 튀어나오려나? 그럴싸하다고 생각했는데, 그래서 이걸 코드로 어떻게 짜야 하는 것일까?

머리를 굴려보고 굴려보다 우연히 유튜브 강의를 보게 되었다. 강의는 이것 https://youtu.be/hSIdPgCkEBw

stateCycle()이 이렇게 유용하게 쓰이는구나! 그렇다면 지금까지 생각했던 애니메이션 구조를 버리고 이걸 이용해 보도록 하겠다. 두더지가 들어가 있을 때의 상태를 기본으로 하고, 튀어오르는 state를 설정한다. stateCycle()의 기본 사이클은 ‘디폴트와 설정한 값’이다. state의 세팅이 끝났으면, 바로 애니메이트 시켜 준다. 이때 delay값을 1초부터 3초까지 랜덤으로 지정해 놓았으므로, 두더지들이 제각각 튀어오르는 동작은 성공했다.

for i in [0…9]
moleBody_array[i].states.pop =
y: 10
opacity: 1
options:
time: 0.4
curve: Spring(damping: 0.3)
delay: Utils.randomNumber(1,3)
moleBody_array[i].animate(“pop”)

두더지 게임에서는 때리기 전에 숨기도 한다. 그래서 다시 들어가도록 Utils.delay를 이용해 두더지들이 아무 때나 숨도록 하였다. 이때 digtime은 랜덤하게 지정했는데, 그랬더니 희한한 눈속임 기능이 구현되었다. 이미 랜덤한 시간에 튀어오르고 숨고를 반복하고 있는 와중에 또다시 digtime이라는 변수를 설정해 주었기 때문에, 어떤 때는 두더지가 한번에 숨기도 했다. 스터디 시간에는 digtime을 고정값으로 변경해 보았는데, 그때 나오는 결과도 흥미로웠다.

Utils.delay digtime, ->
for i in [0…9]
moleBody_array[i].stateCycle()

#EVENTS

사용한 이벤트는 아래의 한가지다. 간단하게 요약해 보면, 클릭했을 때 state가 바뀌는 것이다. 카운트는 1씩 증가하는데, 두더지가 튀어올랐을 때 때리는 경우에만 카운트가 증가하도록 설정했다. 두더지가 튀어오르는 state를 보면 y값이 10이므로, y가 10이면 카운트를 증가시키는 코드를 넣어 주었다. 그리고 두더지를 때리면 숨어야 하므로, click했을 때 state가 바뀌도록 설정했다. 그리고 애니메이션이 끝나도 다시 튀어올라야 하므로, onAnimationEnd 이벤트를 주고 pop이라는 state로 다시 애니메이트 시켜줬다.

moleBody_array[i].onClick ->
hammer.play()
if this.y == 10
count += 1
score.text = count + ” 마리 잡았다!”
score.color = “black”
this.stateCycle(time: 0.4, curve: Spring(damping: 0.4))
#stateCycle이 끝나면 다시 애니메이션을 시작해줌.
moleBody_array[i].onAnimationEnd ->
this.animate(“pop”)

 

그래서….이 게임은 무한대다. ㅋㅋㅋ

재미있는 요소로 공부하는 것도 좋은 방법이라 생각한다. 하고싶은 걸 만들면서 공부할 수 있으니까 그만큼 성취감도 높아지는 듯.
나의 튜토리얼은 계속 된다. 진정한 GUI 인터랙션을 만들기 전까지는 일단.

구현 화면 보러 가기 >

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다