티스토리 뷰

WindowsPhone

WP7 앱 개발하기 - 비눗방울 수평기 만들기..

생각많은 소심남 2011. 11. 13. 01:46
오랜만에 포스팅하네요. 하도 과제가 밀려서 포스팅할 기회도 없고...

아무튼 틈틈히 해보고자 합니다.

이번에는 어떤 물체가 지구에 대해서 평평한지에 대한 정보를 알 수 있는 수평기에 대해 다뤄보고자 합니다.

일단 XnaAccelorometer 라는 이름으로 프로젝트를 생성합니다.


그리고 이미지가 필요합니다. 48x48픽셀의 빨간 원이 필요합니다. 저는 content에 삽입하는 형식으로 만들었습니다. 


 
만드는 방법이야 그냥 해당 색깔 지정후 Ellipse로 그리시면 됩니다..
참 그릴때 유의해야 될 사항이 있다면 화면에서 원을 제외한 부분을 투명하게 처리하고 싶으면 magenta(자홍색)을 위의 사진처럼 해주셔야합니다.

그리고 Accelerometer로 쓸것이기에 전체적인 디바이스로 보자면 sensor를 reference로 삽입해야 되겠지요.

 
물론 using 지시자로도 삽입해줘야 됩니다.

 
다음과 같이 코드를 구성합니다.



 물론 각각에 대한 변수명을 지정해준 겁니다.  특이한 것이 있다면 Accelerometer이기에 3차원 벡터를 할당해주고 이값은 아마 이전 포스팅에서 잠깐 다뤘던  OnAccelerometerReadingChanged와 연계되서 사용됩니다.

그런데 여기서 자료형에 대한 고려를 해보아야 합니다. 앞의 이벤트 핸들러와 Update는 독립된 스레드이기에 이벤트핸들러가 값을 받아오면 update가 그 값을 이용하는 식으로 구성됩니다. 그런데 이런게 보통 한번의 기계어로 연산이 처리가 가능하면 좋은데, Vector3 자료형은 float형 속성을 3개 가진 구조체입니다. 구조체의 특성상 그 내부는 4바이트로 구성되고 계산해보면 Vector 자료형 하나당 12바이트라는 결과가 나옵니다. 그런데 윈폰이 올라가는 디바이스의 경우는  32bit arm 프로세서를 이용하는데, 이 Vector3는 물론 큰 메모리를 한번에 옮길 수 있는 코드가 없습니다. 컴퓨터 원리에 대해서 잘 아시는 분이라면 아시겠지만 컴퓨터가 어떤 동작을 함에 있어서 순간 순간에 인터럽트라는 것이 걸립니다. 보통 한 동작당 인터럽트가 한번씩 걸리게 되는데 위와 같은 경우처럼 한번에 못 옮긴다면 그걸 옮기는 순간에도 인터럽트가 발생할 여지가 생기게 됩니다.

결론적으로 중간에 값이 변하게 되면 이는 값이 바뀔 수도 있다는 겁니다. 이는 우리가 수평기를 만들어 나감에 있어서 피해야 할 사항이기도 하고요..

이를 위해서 기존에 받은 값을 고정해주는 변수가 필요합니다. 책에서는 이를 accelerometerVectorLock이라고 지정했습니다. 다음과 같이 Initial 메서드 안에 삽입해주면 됩니다.


물론 이에 해당하는 메서드또한 형성해줘야 되겠지요.


즉 lock이 돌아가고 있는 순간에는 외부에서 어떤 값이 들어온다 할지라도 accelerometer에 접근하지 못하게 됩니다.

LoadContent에서는 아까 만든 원형 그림을 로드하고 그 위치를 설정하는 걸 다루게 됩니다. 보통 초기화를 하게 되지요.


viewport를 쓴 후 현재 나타나는 화면의 중심과 그 거리를 표현해줍니다. 그러고 나서 아까 그린 bubble.bmp파일을 불러오게 되는 것이지요. 

Update 메서드에서는 앞에서 언급했던 것처럼 중간에 값이 들어오는 것에 대한 고려가 lock을 써줌으로써 더이상 고려하지 않아도 됩니다. 여기서는 이제 위치에 따른 원의 위치 즉 bubblePosition을 계산해서 loadContent에 넘겨줘야 하겠지요.
사전에 고려해야될 사항이라면 지금은 XNA로 구현하는 것이기 때문에 기본적인 화면 방향이 세로 모드입니다. 이때는 우리가 알고있는 좌표 X,Y 가 바뀌겠지요. 그래서 이렇게 Orientation이 바뀔때는 가속도계 벡터값에 -1을 곱하는 것으로 처리하게 됩니다.


기존에 언급된거와는 별개로 bubbleScale이라는 식이 들어갔는데 이 식을 잘 따라가다 보면 결과적으로 벡터중 Z값이 영향을 미친다는 것을 확인할 수 있을겁니다. 왜 이렇게 들어갔을까요?

사실상 우리가 보고 잇는 폰은 이차원상에 이미지로 표시를 하게 됩니다. 그럼 depth를 표현할 때는 어떻게 하는게 좋을까요?
여기서는 높이에 따라서 Scale이 변하게끔 하는 것으로 처리했습니다. 그래서 기준에서 Z방향으로 얼마나 떨어져 있는가를 표현해주게 되는 것이지요.

마지막으로 Draw입니다. 여기서는 다음과 같이 처리해주시면 됩니다.


 실행결과는 다음과 같습니다.

 



여기까지가 비누방울 수평계였습니다. 동영상에서 보시는 것처럼 Orientation을 어떻게 주느냐에 따라서 원의 위치와 크기가 변하는 것을 확인할 수 있었습니다. 물론 실제 폰에서 디버깅해본다면 정말로 신기한 현상이 관찰할 수 있을 듯하네요.

요즘 Microsoft Student Korea에서 앱을 일정 갯수이상 개발하면 윈도우 폰을 준다고 하니 저런 기회를 노려봐도 좋을 것 같습니다. 다음 포스팅에서는 아마 GPS와 Bing map을 불러오는 것에 대해서 다뤄보고자 합니다.

*참 혹시 snapshot is out of date라는 오류 메세지를 접하신 분은 없으신지요?
저같은 경우는 편의상 Productivity Power Tools라는 확장팩을 사용하고 있는데 아마 default 세팅으로 이 확장팩을 쓰시는 분이라면 100% 이 에러를 접하실 수 있을겁니다. 이는 App hub에서도 언급된 사항이고 해결책이 있습니다.

 http://forums.create.msdn.com/forums/p/62592/420926.aspx


우선 VS2010에서 Tools-Option으로 들어갑니다. 거기서

 
해당그림처럼 Automatic Brace Completion 부분을 꺼줘야 합니다. 이러고 VS2010을 다시 켜주면 아마 발생하는 오류는 해결되리라 생각됩니다. 참고하세요~! 
댓글