재미로 하는 C# - 공 튕기기

처음은 간단하게 공이 움직이고 공을 추가할 수 있는 것이었지만 이것저것 생각하다 만든 요건은 다음과 같다.

  1. Start 버튼을 클릭하면 공이 움직인다.
  2. 화면 끝까지 가면 반대쪽으로 튕긴다.
  3. 공의 버튼을 클릭하면 공이 추가된다.
  4. 공끼리 부딪히면 튕긴다.

1. 공이 움직인다.

공은 단순하게 System.Windows.Forms.PictureBox 로 구현했으며 움직임은 해당 control 의 Left, Top 속성을 변경시키는 것으로 했다.


2. 화면 끝에서 공이 튕긴다.

튕기는 각도를 계산하기 위해 몇가지 경우의 수를 가지고 산수를 해보니

  • 위쪽과 아래쪽 벽에 부딪히는 경우 : PI - 공의 각도
  • 양 옆쪽에 부딪히는 경우 : 2*PI - 공의 각도

로 정리가 되었다. 공의 각도는 공의 진행 방향의 바닥(흔히 생각하는 X축)에 대한 라디안 값이다.

따라서 각 공은 각자 각도와 속도를 가지게 되었고 폼은 각 공에 move 메세지를 주면 공은 충돌여부를 확인해서 각도를 바꾸게 되었다.


3. 공의 추가

  • 여러종류의 공 추가

여러종류의 공을 추가하기 위해 Ball 클래스를 상속받은 몇가지 클래스를 만들었다. 새로운 클래스들은 Ball 클래스가 가지고 있는System.Windows.Forms.PictureBox 에 이미지를 넣는 메소드만 각자 별도로 가지고 있다.

  • 공이 움직이는 동안 또다른 공 추가

공이 움직이는 동안에도 공이 추가되게 하기 위해 Thread 가 필요하다.

방법: 스레드 만들기 및 종료  

간단히 설명하자면 쓰레드로 실행할 메소드명을 사용해 new Thread([메소드명]) 로 쓰레드를 만들고 Thread.start() 하면 간단히 쓰레드가 실행되며 종료시에는 Thread.abort() 하면 된다. 하지만 abort 하게되면 Thread 로 실행하던 메소드가 실행 도중 중단되어 보통은 메소드 내에 종료조건을 만족하게 만들어 쓰레드를 종료시킨다.

일단은 쓰레드는 간단히 만들었지만 쓰레드 내에서 컨트롤들을 제어하려고 했더니 InvalidOperationException 이 발생했다.

방법: 스레드로부터 안전한 방식으로 Windows Forms 컨트롤 호출

delegate 를 만들어서 폼의 invoke 를 호출하라고 하는데 일단 delegate 가 뭔지 모르기에 예제소스를 참조해서 코드가 동작하도록 하는데 만족했다.

훨씬 자연스럽게 공이 움직였고 공의 추가도 잘 되었지만 오류의 여지가 많았다. 공들은 List<Ball> 로 선언한 balls 에 들어있었고 공을 움직이도록 balls 의 각 ball 에 move 메세지를 보냈고 공을 추가하는 부분에서는 balls.add(ball) 로 공을 추가했다. 따라서 balls 는 임계영역으로 설정해야 하는 부분이다.

C# 쓰레드 이야기: 9. 임계 영역

임계영역이 시작되는 부분에 System.Threading.Monitor.Enter(this) 종료되는 부분에 System.Threading.Monitor.Exit(this) 를 넣어주는 것으로 임계영역 정의는 된다. 그래서 공을 그리는 부분과 공을 추가하는 부분에 임계영역을 설정했다. 처음에 List 에서 공을 꺼내 move 메세지를 보내는 부분 전체를 설정했더니 공을 추가하는 부분에서 가끔 Deadlock 이 걸리는 상황이 발생했고 balls List 를 다른 배열에 복사하는 부분만 임계영역으로 설정하고 공에 move 메세지는 복사본 balls 에서 보내도록 수정했다.


4. 공과 공의 충돌

  • 충돌 확인

두 공 사이의 거리와 두 공의 크기를 이용해서 충돌을 확인할 수 있다.

  • 출돌 후 각도 변경

공과 공의 충돌시 충돌면의 각을 계산 후 충돌 후의 각도를 보정해야 한다. 대략적인 구현은 생각해 뒀지만 아직 미구현 부분이다.



Microsoft Visual Studio 2008 로 구현한 소스는 구글코드 에서 확인할 수있다.

이클립스 플러그인

EclEmma - http://update.eclemma.org/  - 소스코드 커버리지 계산Haskell - http://eclipsefp.sf.net/updatesMoreUnit - http://moreunit.sourceforge.net/org.moreunit.updatesite/  - 어떤 메소드에 테스트 케이스가 만들어졌는지 간단히 확인 할 수... » 내용보기

SQL Developer

작업할때 DB를 쓰는 일이 잘 없기때문에 사람들이 많이 쓰는 Toad 같은 프로그램을 가지고 있지 않았다.언젠가 DB를 열어봐야할 일이 생겨 인터넷을 뒤지다가 Oracle 에서 개발, 배포중인 SQL Developer 를 발견했다.심플한 UI무설치JAVA 만 설치되면 실행가능위 세가지의 능력(?) 너무나 만족스러워 그때 이후로 DB 작업이 필요할때마다 ... » 내용보기

할일의 미룸

하고 싶은게 너무 많아 여기저기 벌려놓은 일들 투성이다.집에 도착해서는 이것저것 집안일도 좀 하고 애기랑 놀아주다 보면 어느새 10시가 훌쩍 넘기도현재 회사업무에 여유가 있어서 그나마 그 시간을 활용 중이지만앞으론 어떻게 될지 걱정이 든다.역시 잠을 줄여하 하겠다. » 내용보기

안드로이드 스터디 시작

작년 말부터 진행했던 프로젝트가 5월까지로 끝이나고 본사로 귀환했더니할일이 없다.그래서 살짝 간만 보고 있던 안드로이드를 좀더 깊이 있게 들여다보기 시작했다.일단 개발자 사이트의 tutorial 과 sample code 등을 보면서 어렴풋하게 감을 잡아가고 있고나름 간단한 게임을 만들어 보면서 자신감도 붙었다.오늘은 쓰레드 관련된 문제를 검색하던 중 집... » 내용보기