오늘은 RSS 리더 만들기 두번째 시간입니다.
어제는 RSS가 무엇인지에 대해서 간단히 알아봤는데요..

오늘은 XML을 파싱하는 법에 대해서 알아보겠습니다.

"엥? XML을 파싱하더라도 RSS의 구조를 아는게 먼저가 되지 않나?"
하시는 분들도 있을 테지만
RSS도 XML로 만들어 졌으므로 일단 임의의 XML을 파싱해놓은 후, 
RSS의 구조에 맞게 해당 태그를 찾아 읽기만 하면 되는 것이겠죠.

그럼 XML을 어떻게 파싱을 하느냐?
많은 프로그래밍 랭귀지에서 XML을 파싱하기 쉽게 도와주고 있습니다.
여기서는 PHP의 XML Parser를 이용해서 구현해 보도록 하겠습니다.
이 XML Parser가 하는 일은 저도 완벽하게는 모르지만 제가 아는 정도만 이해 하셔도 xml을 파싱하는데는 무리가 없을 것입니다.

PHP의 XML Parser는 많은 함수를 제공하고 있는데요,
이 parser의 동작 원리는 "콜백함수"를 이용하고 있는 것입니다.
즉, 시작 태그를 만났을때, 태그 사이의 값을 만났을때, 종료 태그를 만났을때 이를 처리 하는 콜백 함수를 등록하는 것이 주요 원리 입니다.

xml_set_element_handler
xml_set_character_data_handler 

이 함수가 콜백 함수를 등록하는  함수들입니다.

xml_set_element_handler( $parser, startHandler, endHandler);
xml_set_character_data_handler( $parser, cdataHandler);

여기에 나오는 parser라는 변수는 무었일까요? 
파싱을 수행할 자원이라고 생각 하시면 됩니다.  이 자원을 얻기 위해서는

xml_parser_create 함수를 사용하시면 되구요, 그 예로는 

$parser = @xml_parser_create();

간단하죠?


이 함수들에 대한 구체 적인 예와, prototype은 
www.php.net 에서 보시면 됩니다. (메뉴얼 보는 것이 가장 중요하죠.ㅋ)

전체적인 흐름이 안들어오시나요? 그러면 이 함수들을 이용한 예를 보여 드리겠습니다.
$parser = @xml_parser_create();

if (is_resource($parser)){

   xml_set_object($this->parser, $this);
   xml_set_element_handler(
$parser,
"startHandler",
"endHandler");
   xml_set_character_data_handler(
$parser,
"cdataHandler");

}


function statHandler($parser, $element, $attr){
// 시작 태그 만났을때 여기서 처리
}


function endHandler($parser, $element){
// 종료 태그 만났을때 여기서 처리
}


function cdataHandler($parser, $cdata){
// 태그 사이 값을 만났을때 여기서 처리
}


xml_parse($parser, $data);  // $data <= xml file

// parser객체 해제
xml_parser_free($parser);
unset($parser);


이해가 가시나요? 

다음 시간에는 이 함수들을 이용하여 실제로 rss파일을 파싱해 보도록 하겠습니다.







신고
by danguria 2010.04.14 21:50
오랜만입니다~~  (__
프로젝트가 한달 늦어지고 면접일정도 오락가락 한다고 포스팅이 뜸했네요..
이번 프로젝트는 멤버십과 연관이 있어서 포스팅하기가 그래서 개발 과정에서 공부하는 것들을 정리 해 볼까 합니다.

제가 개발하게 된 부분중 하나가 웹에서 동작하는 RSS리더기를 만드는 것입니다. 요즘은 조금 뜸하지만 한 5년 전까지만 해도 활발하게 개발 되었는데 좀 늦은 감이 있군요.. 그래도 제가 웹 프로그래밍관련해서 처음 해보는 것이기 때문에 충분히 개발능력에 향상이 될 거라는 것에는 믿어 의심치 않습니다.

자~ 잡담은 그만 하고 본론으로 들어가도록 하겠습니다.

[RSS리더가 무엇인가?]

RSS리더를 만들어야 하는데 RSS가 무엇인지 모르는 사람은 없을 거라 믿고 과감히 스킵하도록 하겠습니다. 그래도 궁금해 하시는 분들을 위해서 RSS를 잘 설명하고 있는 사이트를 링크하겠습니다.


[RSS의 종류는 어떤 것이 있는가?]

RSS는 버전이 많지만 크게 나누면 세가지로 분류 할 수 있습니다.

RSS 2.* 계열
RSS 1.* 계열
ATOM

각각은 특색이 있는데 RSS리더를 구현할때는 크게 의미는 없을 것 같습니다.
좀더 자세한 설명은 다르 사이트를 참고 하세요. 제가 참고 했던 사이트를 링크하겠습니다.

모질라 개발자 센터 - https://developer.mozilla.org/Ko/RSS/Version

다음 포스팅에서는 RSS 2.0버전을 토대로 실제로 RSS를 읽어 보도록 하겠습니다.


신고
by danguria 2010.04.13 21:52
오랜만입니다.ㅋ
제가 면접을 준비한다고 포스팅이 조금 뜸했군요..

아무튼!!
POAD과제가 바뀌게 되었습니다. 과제 프로토타입을 계속 만들면서 왠지 썩 내키지가 않았었습니다.
아이디어 자체는 나쁘지 않은것 같지만, 결국 만들어 놓고 보면 기존의 CASE툴과 크게 차별화 할 수 있을까 하는 의구심이 들었습니다. MDA(Model Driven Architecture)에 대한관심이 많지만 자신이 없었습니다. 그러던 그때, 운영자께서 멤버십 내에서 쓸 지식 공유 시스템을 구축할 팀을 구하더군요, 이때다 싶어서 팀원들과 상의를 한뒤 프로젝트를 변경했습니다.

멤버십 지식공유 시스템은 다음과 같습니다.
평소 멤버십 회원간의 지식 공유가 적다. 회원 개개인은 자신의 블로그를 통해 글을 포스팅 하고 있지만, 그것이 멤버십 내에서 유용하게 쓰이지 못한다. 또한, 멤버십 공유 폴더의 정보가 많아지고 있는 상황에서 그것을 효과적으로 검색할 무언가가 필요한다..

이런정도의 필요성이 있었기에 저희 팀이 "지식공유 시스템"이라는 임시 이름을 붙여 제안서를 쓰고 있습니다. 아마도 웹사이트를 구축하게 될텐데요..

웹프로그래밍을 해본적이 없어서 공부하고 있습니다. 실버라이트, WCF , DB등을 공부하고 있는데 면접때문에 조금 진도가 잘 나가지 않고 있군요..

이번 과제는 외부에서 의뢰를 한점이라는 것이 특이하고, 이 점으로 부터 얻을 수 있는 경험이 많을 듯 합니다.

열심해 해봐야 겠습니다.


신고
by danguria 2010.03.26 13:18
멤버십에서 새로운 프로젝트를 진행하기 위해서 아이템과 팀을 꾸린지 한달 가량 

되어가는 군요..

일단 과제 제안서를 작성하고 소프투웨어 분과장의 응답을 기다리는 중이지만 미리 

시작 세미나와 프로토 타입을 준비하고 있습니다.

이번에 프로젝트 진행하는 절차가 조금 바뀌어서 좀 걱정되기는 하지만 준비하는 만큼 

결과가 돌아 오겠죠.ㅋ

우선 PL로서 평소 팀 프로젝트를 하면서 하고자 했던 것들을 하나하나 해보려고 합니다.

프로젝트 결과도 중요하지만 과정 역시 중요하다고 생각하기 때문이죠..

프로젝트 일정이에 대해서 궁금하시다면, 

http://poad.springnote.com로 들러 주세요~
신고
by danguria 2010.02.19 13:28
다음 프로젝트를 MFC를 조금 할 줄 알아야 해서 짬이 있는 틈을 타서 시작 해 버렸
습니다. 원래는 기존에 자바로 구현한 Flower를 그대로 리펙토링 할 예정이었는데, 
C++코딩을 너무 안해서 공부를 다시 해야 하고 MFC프레임웍에 익숙해져야 하기 때문에 Flower를 아주 MFC로 구현 해보려고 합니다.

코드가 나름 커졌기 때문에 한번에 똑같이 구현 할 수는 없으니까 작은 단위로 잘라서 구현해 나갈 생각입니다. 이미 구현을 한 것을 다른 언어와 GUI를 이용하는 거라서 크게 어렵지는 않을 것으로 예상합니다.

아자아자~~ 화이팅!!

일단 MFC의 컨트롤들을 잘 못쓰기 때문에 GUI쪽 말고 로직과 자료구조를 구현하는 것에 일단 초점을 맞추고 있습니다.

오늘은 MFC패턴을 적용하여 큰 틀을 잡는 것만 구현 했습니다.

스윙에서는 controller클래스인 DPainter가 있었지만 MFC자체가 controller가 OS가 담당한다고 해서 위와 같은 모양이 되었습니다.DCanvas가 view에 해당되고(실제 MFC의 뷰클래스입니다.) DSymbolManager가 Model이 됩니다. DSymbol은 도형의 최상위 객체이구요.(DFigure와 DProcedure의 틀만 만들었습니다.) DCanvas와 DSymbolManager가 옵저버패턴이 적용되어야 하는데 그건 내일 해야 겠습니다.

마지막으로 오늘 한 코드의 시퀀스 다이어그램을 올립니다.

신고
by danguria 2010.01.21 18:55
도형 객체를 복사하는 루틴을 "prototype pattern"을 적용하고 있는데,

원래 복사 하는 코드에 비효율적인 부분이 있었습니다.

DFigure라고 하는 추상 클래스는 화살표가 아닌 도형을 나타내는데요..

(단말, 처리, 분기도형 등등이 이에 해당합니다.)

여기에는 이 도형이 화살표로 연결되었을 경우 연결된 도형을 알고 있습니다.

또한, 자신에게 들어오거나, 자신으로 부터 나가는 화살표도 알고 있습니다.(알고 있

다는 표현을 한 이유는 정확하게 composition인지, aggregation인지하는 개념에 아

직 익숙하지 않아서 입니다.)

그런데 복사를 할때 자신 도형에 연결된 도형은 복사 하지 않아야 합니다.

그 이유는 그렇게 하기로 정했기 때문이죠..(다른 비슷한 프로그램들도 그렇게 하더

군요..)

하지만 코드에는 이것 들 마져 모두 복사 하고 있었습니다. 그나마 다행? 인것은 그

렇게 복사된 도형들은 도형 꾸러미에 들어가지 않아서 실제로 보여지지는 않았던 것

입니다. 그래서 제가 이런 현상을 눈치채지 못한 것이구요..

가장 비 효율적인 부분은 Procedure도형이 자신과 연결된 procedure 도형 꾸러미

를 모두 복사 하는 것이었습니다. 이것 역시 화면에 보지 지 않습니다만.. 

만일 원래 procedure코드를 변경하더라고 이것이 반영되지 않을 것이라는 버그를 

안고 있더라구요...

어쨌든 다행이 문제를 파악했고, 그에 대한 해답은 간단하기 때문에 룰루랄라 하면

서 고치고 있습니다^^;
신고
by danguria 2010.01.19 11:11
This is demo videos. If you cannot watch the video clearly, please download the demo files and play it.
< Run the program and debug it>



< Create Figure and change its attributes>



< Copy, paste and cut the figures>




< Change figures' level of layer>



< Procedure>



신고
by danguria 2010.01.04 16:03
어찌 어찌 해서 무적의 솔로부대를 완료 했습니다.

총 2개의 스테이지가 제공 되고 있습니다.



< 게임 초기 화면>



<게임 화면>



신고
by danguria 2009.12.31 22:50
코드리뷰를 오늘 했네요..

운영자형에게 시연을 하는데 사소한 버그가 있어서 부끄러웠지만

큰 문제 없이 코드리뷰는 진행되었고, 나름 잘된 것 같습니다.

원래는 팀원 각자가 자신의 코드를 보여주고 시연을 해야 하는데,

GUI파트를 담당한 제가 어찌하다보니까 다 해버리게 되었네요..ㅋㅋ

과제 완료는 계획보다 늦어졌지만, 프로젝트 일정 자체는 일정되로 진행 되어서 

만족하고 있습니다.

마무리하는 차원에서 완료 세미나와 보고서를 써야 하는데 귀차니즘이 또 다가 오고 있네요~~

도와주세요~~~
신고
by danguria 2009.12.28 18:05
너무 오랫만입니다. 한달만이네요. 

시험 기간 전에 과제를 어느정도 마무리 하느라고 정신없이 코딩하고, 

시험치고나서 게을러지는 바람에 늦어 졌습니다.

바로 직전에 제가 썻던 내용을 보니까 프로시저를 구현 하기 직전 까지군요..

프로시저는 현제 잘 동작하고 있습니다. 

이미 컴파일러와 디버거와도 연동되어서 테스트 중에 있습니다.

와~~ 많은 일이 있었군요...

그동안을 간략하게 정리해보아야 겠군요..

1. 프로시저를 구현했습니다.

프로시저로 쓸 InnerFrame을 JFrame을 수정하여서 새로운 InnterFrame을 만들었습니다.

기존의 JInternalFrame은 internalframe을 붙인 패널에는 다른 것이 붙이안아서 직접 서적을 참고하여 

구현하였습니다.

프로시저의 생성은 툴바에 버튼을 통해 생성할 수 있고 삭제는 프레임의 타이틀바에서 삭제 할 수 있습

니다.

타이틀바에 적혀 지는 이름이 곧 프로시저의 이름이 되며, 메뉴바를 통해 변경할 수 잇습니다. 

프로시저 창위에서 만들어지는 도형들은 내부적으로 메인 패널에 있는 것과는 따로 관리 됩니다.

2. 메뉴바의 나머지 이벤트를 구현했습니다.

새로만들기, 열기, 저장, 다른이름으로 저장, 잘라내기, 붙여넣기, 복사등 기본적인 응용 프로그램에서 

제공하는 기능을 구현하였습니다.

저장과 열기는 프로그램에 변경됨에 따라 계속 바뀌고 있는 중인데 

아마 , 앞으로 변경은 되지 않을듯 합니다.

3. Undo, Redo의 대대적인 수정이 있었습니다.

저장과, 불러오기 기능을 구현하면서, 언두, 리두 알고리즘의 문제를 찾았습니다.

연결성을 모두 잃게 되는 문제였습니다.

그래서 다시 구현하였고, 지금은 아무 문제 없이(??) 동작하고 있습니다.

4. Comment 도형을 구현하였습니다.

Comment를 구현하였는데요.. Comment자체는 도형에 화살표가 붙어 있는 모양이기 때문에,

새로운 상속 구조를 만들어야 했습니다. 심볼 의 하위 클래스에 Line과 Figure외에 Comment를 두어 

구현하였습니다.

5. 브레이크 포인트 및 인터프리터, 컴파일러와 연동을 하였습니다.

도형을 우클릭하여 나오는 팝업 메뉴를 이용하여 브레이크 포인트 지정을 구현하였고, 

컴파일러, 인터프리터와의 연동을 위한 작업을 구현 하였습니다. 

현재 컴파일러와 인터프리터와의 연동자체는 잘 작동하고 있지만 

언어 설계와 구현에 대해서는 아직 작업이 남아 있습니다.




기억을 더듬어서 적어봤는데 아쉽군요.. 

마무리로 멋진 UI화면을 보내 드립니다~~
신고
by danguria 2009.12.22 23:01
오늘까지 속성창에 대해서 이벤트 처리를 완료 했습니다.

기본적으로 도형을 클릭하면 속성창에 그 값이 바로 반영되고 속성창의 값을 변경시키면 선택된 모든 도형의 

값을 모두 변경 시키게 했습니다.

여러개를 선택하게 되면 같은 값을 가질 경우만 값을 나타내고 다른 경우는 초기 값을 넣어 주었습니다.

이때 조금 문제가 있었는데요..

두 도형의 값이 다르면, 속성창에 초기 값을 넣어 주는데, 이것 또한 이벤트가 발행해서 두 도형 모두 초기 값으

로 값이 변경 되는 것이 었습니다.

그래서 생각한 방법이 도형을 선택하게 되면 일단 이벤트 리스너를 제거 했다가 초기화 후 다시 이벤트 리스너

를 동작 하도록 하였습니다.

추가 적으로 한 것이 있는데요.. 프로시저를 구현할 내부 창이 기존 창과 동작 모습이 어색했는데,

이를 해결했습니다.

결과만 간단히 말하자면, JLayeredPane을 잘 이용하니까 되더군요...

내일 드디더 프로시저를 구현할 것 입니다. 내일 아무일도 하지 않기 때문에 풀로 작업 할 수 있어서 내일 마지

는 것이 목표 입니다.


신고
by danguria 2009.11.20 01:51

오늘 회의에서는 게임 전체 스테이트 다이어그램에서 play 부분에 대해서 상세 설계를 하였습니다.

 

그전에 저희는 게임이 3교시가 목표인데 일단 1교시를 구현하고 추가로 구현 하는 것을 계획으로 잡았습니다.

 

아래는 play 단계에서의 스테이트 다이어 그램입니다.

 


 

 

그리고 메인 함수에 대한 의사 코드도 구현 해 봤습니다.

 While keepGoing:

           isPlay = intro()

           if isPlay:

                     opening()

                     isWin = play()

                     ending(isWin)

           else:

                     keepGoing = false


그리고 이번 주 작업 내용입니다.

 

이번주 작업은 오프닝과 앤딩, 그리고 각종 효과음 녹음작업입니다.

 

아래는 각 소스의 맨트들 입니다.

 


[오프닝 ]

공대남자의 탐구생활이예요.

남자는 해가 뜬지 한참이나 지났지만, 이제서야 실습실에서 간지 폭풍 FILA 슬리퍼를 끌고 밖으로 나와요. 데이터 베이스 숙제에 오늘도 실습실에서 밤을 지새웠기 때문 이예요. 울트라 캡숑 짱 어려운 숙제는 해도 해도 끝이 없어요. 교수님이 블랙홀을 구현하라고 숙제를 내신 것 같아요.

 

배낭 여행 나왔다고 생각하기로 하지만 A형인 남자에게 이러한 고귀한 발상은 택도 없어요.

남자는 주머니속 담배 갑을 만지작 거리면서 옥상으로 올라가요. 하지만 담배갑이 비어 있어요. 아놔~~, 돗대를 새벽 4시에 선배에게 뺏긴 것이 기억 났어요.

 

쓸쓸한 마음에 밖을 내다봐요. 슬리퍼를 맨발에 신은 탓에 발가락이 조금씩 시려와요.

커플들이 지나가요. 커플들은 솔로 주제에 삽질이나 해!라는 건방진 오로라를 풍기는 것 같아요.

남자는 손에 든 빈 담배갑을 구겨 힘껏 커플 남자의 뒤통수를 향해 던졌어요.

정통으로 맞은 담뱃값에 당황해 하며 어쩔 줄 몰라 하는 커플을 보며 디비 프로젝트를 완성한 만큼 기뻤어요. 하지만, “오빠! 괜찮아?라는 소리가 희미하게 들려와요. 어제 새벽 야식으로 먹은 파닭이 목구멍으로 역류하는 것 같아요. 화가 나요. 삐리리 같은 커플들 내가 다 무찔러 주마 라는 비장한 각오를 다져요.

 

[투척 효과음]

, 피슝

[말 효과음]

꺕삿, 아싸라삐야 깐따삐야

[실패시나리오]

언젠가 때놓고 말꺼야

[성공시나리오]

웃음소리



신고
by danguria 2009.11.18 01:11
드디어 올것이 왔군요..

지금까지 프로시저를 생각하지 않고 구현하고 있었습니다. 큰 문제가 없을 것이라고 생각 했지만

문제가 있긴하군요..

현재는 심볼 매니저와 캔버스가 하나의 쌍으로 있어서 그것이 뷰와 모델의 관계를 했었는데

이제 함수가 들어오면서 부터 여러개의 심볼 매니저와 캔버스가 있어야 합니다.

먼저 painter(controller)는 심볼매니져와 캔버스의 쌍을 관리 하고 있어야 합니다.

즉, 사용자가 활성화 한 캔버스에 대한 심볼 매니저가 적정하게 동작 해야 합니다.

그리고, 프로시저 심볼을 디자인 해야 합니다.

프로시저라는 심볼은 내부적으로 나의 심볼 매니저를 알고 있어야 합니다. 왜냐하면 심볼 매니저로 부터 해당 

프로시저의 시작 심볼을 가져 와야 하니까요(컴파일러가 추적할 수 있어야 함니다.)

일단 설계를 해보았습니다.

기본적으로 MVC패턴입니다.

symMng가 모델, canva가 뷰, painter가 컨트롤러 입니다.

각각의 참조가 MVC과 약간 달르고 아직 변경의 여지가 있기 때문에 association로 표현 했습니다.

페인터와 캔버스가 symMng의 데이터, 즉 심볼들의 변화에 따라서 상태와 겉모습이 바뀌어야 합니다.

캔버스는 심볼의 그림을 그려 주어야 하므로 draw옵저버가 되고,
페인터는 심볼이 선택됨에 따라 해당 심볼의 속성을 각 컨트롤에 반영해야 합니다 (이부분이 뷰에 대당하는 것 같은데 컨트롤이 painter에서 구현 되어 있습니다...)그래서 속성 옵저버가 되고, 프로시저가 생성되고 소멸됨에 따라 현재 캔버스와 심볼매니저의 쌍을 교체 해야 하므로 프로시저 옵저버가 필요합니다.
여기서는 표현 되어 있지않지만 사용자에 의해 현재 캔버스와 심볼매니저의 쌍을 교체 해주어야 하는데 이것은 페인터가 내부적으로 해결 할 수 있을 것 같습니다.

심볼 매니저는 만들어진 모든 옵저버를 받아드리고 notify하는 subject를 구현 하도록 하였습니다.


신고
by danguria 2009.11.18 00:14
조금 게을러지긴 했지만 얼추 마무리를 했습니다.

마지막까지 고생을 시킨 것이 있었는데요..

pallet이 생각했던데로 디자인이 되지 않고 자기 멋대로 행동 하더라구요... 

아무튼 이래저래 해서 안정시켜 두었는데 GUI layout을 구성할때 공부가 부족했던것 같습니다.

얕잡아본것이죠...

아무튼 다음주 부터는 controller와 연동하는 것인데 그에 앞서 전체적인 설계를 다시 하면서 연동해야 겠습니다.

함수기능을 염두에 두고 구현 해야 하죠...


신고
by danguria 2009.11.16 00:58
아쉬움이 있는데 디버깅 창을 구현 하였습니다.

디버깅 버튼을 누르면 창이 생기고, 디버깅 종료 버튼을 누르면 창이 사라지도록 했습니다.

이 창은 새로 팝업 되는 창이 아니라, canvas가 위치 하는 곳의 영역 일부를 빌려 위치합니다.

실제 구현은 디버깅 버튼이 눌리면, canvas를 빼내고, JSpiltePane에 canvas와 JTable을 담은 

JScrollPane(JTable담고 있음)을 담아서 canvas가 위치 한 곳에 넣어 줌니다.

실제 디버깅 툴의 UI를 보면 도킹이라고 불리는 기술을 사용하는데 저는 그것을 어떻게 구현하는지도 배울 시

간도 부족 하므로 고정된 곳에 넣어 두었습니다.

그래도 전보다 UI가 이뻐지고 있어 만족 하고 있습니다.

상세한 요구 사항을 만족하도록 커스티마이징 하였고 이제 데이터만 넣으면 됩니다.

아참 이 작업을 하기 전에 property를 구현 하다가 말았는데요.. 그건 다음에 설명 드리죠... 아직 미완성이랍니

다.


신고
by danguria 2009.11.13 20:24
오랜만에 Flower 프로젝트를 했습니다.

요즘.. 개을러 지기도 했고, 학교 과제도 많았기 때문에 조금 지체 되었습니다.

아무튼 이번달 구현해야 하는 것은 크게 몇가지가 있습니다.

GUI 껍데기(?!)구현하기

기존에 구현된 기능을 GUI와 붙이기

위의 둘을 MVC 패턴을 이용하여 구현하기

순서도 그리는 모듈 미완성부분 완성하기

컴파일러 모듈과 통신을 위한 설계 회의 하기

이번주는 GUI껍데기와 기존의 순서도 모듈을 붙이는 것까지가 목표입니다.

오늘은 Property pallet부분과 debugging panel을 제외한 부분을 모두 완성 시켰습니다.

나름 이쁘게 나온 것 같아서 좋습니다.ㅋ


신고
by danguria 2009.11.10 21:44
두 번째 회의에서는
 - 1차 회의 내용을 구현의 관점에서 좀더 이야기
 - 설계
 - resource(사진..) 만들기
 - 비행기 게임 source분석

을 하기로 했습니다.
리소스는 제가 카메나 메모리를 날려 버리는 바람에 다름주로 미뤄졌고, 
소스코드를 가져 오지 않아서 못했습니다.ㅠㅠ

아무튼 1차 회의 내용을 구현의 관점에서 좀더 이야기 해서 나름 진전이 있었내요..


회의 내용

 - 디자인 컨셉
    - 사진을 포토샵의 특수 기능을 이용하여 그림처럼 연출하기로 함
    - 전체 적인 분위기 : 배경은 스케치한 듯한 느낌, 캐릭터는 통통튀는 듯한 느낌

 - 캐릭터
- 컴공 인물들 ( 남자들만 ) 
- 무기
- 리소스를 찾는대로 하기로 함
- 사운드
- 배경 이야기 - 녹음하기(롤러 코스터 컨셉으로) - 까꿍이가 녹음
- 게임 진행시 배경음 <--- 성근이가 인터넷에서 찾아보기
- 투척 효과음 & 말 효과음 (목소리 녹음 ) - 성근이 녹음
- 맞추거나 못맞추거나 효과음( 목소리 녹음) - 성근이 녹음
- 실패 & 성공 시나리오 - 녹음 - 성근

설계에 대한 이야기는 간단하게만 하였음
 - 게임 시작 스테이트 외에는  단순이 sceen 보여 주기만 하면 되므로 sceen을 관리하는 모듈이 중요
 - 게임 시작 스테이트는 하나의 스테이지 동작알고리즘은 같고 그에 해당하는 데이터가 다름.


다음주 해야 할 것
 - 월요일, 화요일 - 사진
 - 금요일 - 오프닝, 앤딩 녹음하기
 - 토요일 - 구름게임 분석, 설계(상세설계)



신고
by danguria 2009.11.08 00:40
MVC
Undo Redo기능을 구현하고 painter 클래스의 복잡성이 너무 커지고, 전체적인 구조가 흔들려서 

과감히 리팩토링을 하고 있습니다. 일단 MVC모델을 기반으로 하려고 하고 있고(전에도 그랬었지만 view와 controller가 섞여 있었습니다.) 그 첫단계로 UI(view)를 설계하고 있습니다.

함수 기능과, 디버깅 기능을 추가 고려 하여 완벽한 버전의 UI를 만들고 있습니다.

아마 다음주 중간쯤에는 완성될 것 같네요.. 

이번주말은 컴파일러 숙제가 있어서 많이 코딩을 하지는 못할 것 같습니다.
신고
by danguria 2009.11.08 00:29
여자친구와 함께 프로젝트를 진행하게 되어서 회의가 곧 데이트?이므로 좋습니다.

놀지 말고 열심히 해야 되는데요....


- 회의 및 개발 일정
   : 매주 토요일 점심을 먹고 까페에서 저녁 먹을때 까지 회의 및 개발을 한다.

- 게임 전체 state diagram

- 게임 세부 사항 
i) 게임 시작 화면



ii) 투척 기능
  - 목표물을 향해 무기를 투척할때 
맞으면 - 맞은 목표물의 맞은 그림으로 교체하고 말풍선
안 맞으면 - 말풍선
iiI) 표적 종류
vi) 무기 종류
수박, 바나나, 캔, 축구공, 교수님, 조교, 마우스, 키보드,,,,,,


- 다음 주 계획
10/31일 회의 내용을 구현의 관점에서 좀더 이야기
설계
resource 만들기
옥상 사진
비행기 게임 source 분석






신고
by danguria 2009.11.04 00:24
학교 수업인 게임프로그래밍 수업에서 게임을 만드는 프로젝트를 하게 되었습니다.

제안서를 만들어 일단 제안을 하게 되었습는데 시간이 없어서 잘될지는 모르겠지만 열심히

해야 겠습니다.


아래는 수업때 제안한 제안서입니다.

Homework #4 Game Project Proposal

 

 

1. Team Name : 삽질은내운명

Ø  2003038101 김성근, 2005038074 이정은

 

2. Game Title: 무적의 솔로부대

 

3. Brief Description:

Ø  Plot

n  26년째 솔로부대의 활동으로 심신이 피폐해진 공대생 A형 주인공 AAA. 쉬는시간 9호관 옥상에서 학교를 내려다보는데, 오늘따라 커플들이 심하게 눈에 띄어 달콤한 휴식시간을 방해한다. 신경이 날카로워진 AAA는 심신을 지치게 하는 학교내의 모든 커플을 오늘하루동안 모두 물리치겠다고 마음속 깊이 다짐한다.

Ø  Identify player’s problem

n  AAA 의 달콤한 쉬는 시간을 방해하는 학교내의 커플들을 괴롭혀 준다.

Ø  Describe the problem or task

n  AAA는 쉬는 시간마다(Stage) 옥상에서 몰래 망원경을 보면서 손에 잡히는 것을 마구마구 커플을 향에서 던진다.

n  AAA 가 처음 물건을 던지기 시작한 시점에서 함부로 물건을 던지는 AAA를 혼내주기 위해 경비아저씨가 옥상으로 올라간다.

Ø  Explain how player will succeed in the game

n  쉬는 시간동안 구역 안의 모든 커플을 맞추면 Stage clear. 하지만, 경비아저씨가 올라오기 전에 모든 일을 끝내야 한다.

 

4. Motivation:

Ø  스나이퍼 게임이 매우 흥미있지만, 대부분의 스나이퍼 게임의 잔인하거나 어두운 게임 분위기로 인해 거부감을 가지는 사람이 많다는 점을 생각하여, 밝고 잔인하지 않은 스나이퍼 게임을 만들기로 하였다.

 

5. Competitive Analysis: (Previous games)

Ø  The Sniper(http://playgames.co.kr/web/game/flash_detail/05/c9ja2lyio0)

n  특징 : 평범한 타격감, 시나리오가 좋음, 잔인한 장면 연출, stage가 여러 개로 나누어짐

Ø  이름(http://nextframe.jp/flash/matsnp/matsnp.html)

n  특징 : 타격감이 좋고, 실제 사격의 느낌 표현, 폭력적인 장면이 없고, 표적 단순

 

6. Differences and Expectancy effects: (차별성 및 기대효과)

Ø  무적의 솔로부대 차별성

n  탄탄한 스토리 - 우리에게 친근한 주변 이야기를 소재로 게임을 진행한다.

n  귀여운 게임요소 대부분의 스나이퍼 게임의 잔인한 요소를 배제하고, 귀여운 게임요소를 이용하여, 누구나 거부감없이 즐길 수 있도록 한다.

n  다양한 표적과 무기 총과 총알을 무기로 하고, 사람이나 단순한 표적을 사용하는 기존의 게임과는 다르게 다양한 표적과 무기를 사용하여 게임의 재미를 높인다.

n  실감나는 타격감 기존의 좋은 타격감을 가지는 스나이퍼 게임과 비슷한 타격감을 가지게 한다.

Ø  기대효과

n  기존의 스나이퍼 게임은 잔인한 설정과 내용이 많은데, 그것을 재미있는 시나리오와 설정으로 누구나 관심을 가질 수 있게 표현하고, 실감나는 타격감을 구현하여 중독성을 더하는 효과를 기대한다.


신고
by danguria 2009.10.31 17:54
일단 마무리를 지어야 할 것 같습니다.

구현은 다 했지만 테스트를 하기 위한 환경이 갖추어 지지 않았네요..

painter 쪽, 즉, 컨트롤러 쪽이 리팩토링을 해야 할 시기가 온것 같습니다..

오늘의 코딩 시나리오를 알려 드리죠.ㅋㅋ 

redo undo가 구현이 완료 되어서 history에 언제 넣는지 결정하고 소스의 해당부분에 코드를 집어

 넣으려고 했습니다. painter가 redoUndomanager와 symbolManager를 모두 갖고 있었기 때문에 

코드는 redoUndoManager.add(symbolManager.createMemento()); 였습니다.

하지만, 굳이 painter가 redoUndoManager를 가질 필요가 없다고 생각하여 symbolManager가 

redoUndoManager를 갖고 내부적으로 symbol들의 상태를 저장해야될 필요가 있을때 

redoUndoManager의 add함수를 호출 하는 식으로 루틴을 변경했습니다. 하지만, 이렇게 하면

세밀한 history를 저장하지 못하고, 불필요한 history를 저장할 수 밖에 없는 상화이 오므로 다시 원래 

대로 복구 했습니다. 이렇게 하는데 또다른 추가 사항이 생겼습니다.

속성창을 통해서 속성을 변경하게 된다면, 이것도 history에 저장해햐 하는데 propertyManager는 

undoManager와 symbolManger와 painter를 모르기 때문에 속성이 바뀐것에 대한 history저장을 

할 수 없다는 것을 알게 되었습니다. 물론, property manager가 위의 것들을 알면 되지만 이렇게 되면 

너우 서로 의존도가 심하기 때문에 결굴 모든것을 중단하고 painter, symbolManger, 

redoundoManager, propertyManager, 간의 중재를 해주는 무언가를 두어 리팩토링을 해야 겠다는 

결론을 내렸습니다. 어떻게 할까 생각 하던중, 그렇다면, painter에 있는 버튼 그룹도 추가하여 서로 중

재해주면 되겠다는 생각을 추가하게 되었고, 더이상 머리가 복잡해지고, 이미 집중력의 한계와 늦은 시

간이 되었기 때문에 마무리를 하게 되었습니다.

헥헥헥.....

일단 쉬었다가 좋은 정신력으로 제대로 된 설계를 해야 하겠습니다.

그럼 안녕히 주무세요....~~


신고
by danguria 2009.10.29 23:12
createColne 매소드를 모든 심볼에 대해서 구현을 완료 했습니다.

concreteSymbol의 clone함수를 구현하려다 보니 부모 클래스의 멤버 변수도 모두 복사해야 다 던데요..

그부분을 각각의 concreteSymbol에 넣으니까 각 클래스에 중복된 코드가 엄청 많아 졌습니다.

부모클래스에 그 코드를 넣으려고 해도 자식클래스가 어떤 타입인지 모르기 때문에 결국 다시 

하위 클래스에서 다시 복사해야 할 것 같아서 일단 모두 concreteSymbol에서 모두 복사하도록 

하였습니다.

그렇게 하고 모듈 테스트를 위해 여전히 도형의 생성에 대해서만 redo undo 를 체크 했는데 생각하는 

것과 다른 결과가 나왔습니다.

undo를 많이 하고 나서 다른 작업을 할때는 redo할것이 없어야 합니다.( 다른 프로그램이 그렇게 하더

군요..ㅋㅋ) 하지만 그렇게 동하지 않았습니다. 

정상적으로 동작하지 않을때의 UndoRedoManager의 add함수입니다.

/**
     * history의 가장 마지막에 memento를 저장한다.
     * @param memento
     */
    public void add(DMemento memento){
        System.out.println("add memento to manager");
        // 만일 삽입할 위치 뒤에 다른 memento가 있다면 삭제 시킨다.

        // 현재 위치바로 위에 memento가 없을때까지 history의 현재 위치 다음
        // memento를 삭제 한다.        
        for ( int i =0 ;i < history.size(); ++i){//<---- 문제의 지점
history.remove(i);
}
        // 현재 위치를 증가 시키고 거기에 memento를 삽입한다.
        history.add(++currentPos, memento);
        
        System.out.println("Debug : after add history size = " + this.history.size());
        System.out.println("Debug : after add currentPos = " + this.currentPos);
    }


처음에는 어디가 문제인지 모르고 이리 저리 뒤적였지만 문제는 빨간색 부분의 코드였습니다.

저의 생각은 "현재 포지션 다음의 것을 모두 지워라"였지만 

실제 동작방식은 그렇게 되지 못했습니다.

history의 자료 구조가 LinkedList이고 이때 remove를 하면 전체 사이즈가 줄어든다는 것을 생각하지 

못했습니다.  

왜 그런지 알겠죠?( 모르면 ... 저처럼 삽질합니다.ㅋ)

그래서 코드를 다음과 같이 멋지게 수정했습니다.
// 현재 위치바로 위에 memento가 없을때까지 history의 현재 위치 다음
// memento를 삭제 한다.        
      // 와우~~ 멋집니다~~
        while(currentPos + 1 < history.size()){
            history.remove(currentPos + 1);
        }


이제 남은 것은 history에 언제 넣어 줄것인가 입니다. 

painter코드가 좀 지저분한데.... 즉 심볼이 바뀌는 것을 모조리 찾아서 쌍으로 넣어주려고 하니까.. 코

드가 지저분해 질 것 같습니다... 일단 좀 생각해봐야 겠습니다.

신고
by danguria 2009.10.28 22:27
Deep Copy... 과연 많이 해도 좋을지 모르겠습니다.

오전까지의 구현에서 얕은 복사를 하고 있었기 때문에 Undo, Redo를 해도 

제대로 동작 하지 않았습니다.

그래서 UndoRedoManager가 관리 하는 history에 SymbolManager가 만들어 낸 memento를 

넣을때 SymbolManager가 갖고 있는 멤버변수를 모두 Deep copy해야 한다는 결론이 나왔습니다.

일단, SymbolManager가 갖고 있는 멤버 변수들은 모두 colloection들로 모두 레퍼런스 변수를 

담고 있습니다.

이 레퍼런스 변수는 DSymbol이라는 놈들인데요..(실제로는 DSymbol을 상속받은 것들이겠죠)

 그림에 드려질 도형들입니다.

문제는 이 DSymbol안에 있는 것들도 상당한 양의 레퍼런스 변수를 담고 있어서 Deep Copy를 하면 

시간과 메모리가 많이 들것 같습니다.

문제는 그것만이 아니더군요..

UndoRedoManager가 Undo, Redo 함수를 통해 memento를 리턴할때도 Deep Copy 를 해서 그것을 넘겨주어

야 했습니다.

그렇게 하지 않으면 SymbolManager가 그 값을 변경하면 history의 memento도 갖이 변경이

 되니까요..

두가지 상황에서 많은 Deep copy가 일어 나고 있습니다.

마땅한 다른 해결책이 없어서 그대로 쓰지만 잘 봐야 할 점인 것 같습니다.

일단 오늘은, 특정 도형에 대해서만 Clone(Deep copy를 이용) 을 구현했습니다.

모두 구현 하고 최종 테스트는 내일이 될 것같습니다.

와우~~ 수고 했어!!!ㅋ


신고
by danguria 2009.10.27 21:38
어제 까지 시험이라서 설계만 하고 어제 저녁 부터 구현을 시작했습니다.

memento 패턴을 이용하여 설계하였고, 

추가로 UndoRedoManager를 두어 여러개의 memento를 관리하도록 했습니다.

구현을 어느정도 마친뒤에 테스트를 해보았습니다.

memento를 저장해야 하는 시점을 아직 확정하지 못해서 일단 심볼들이 캔버스에 생성되는 시점만 

정하고 제대로 동작하는지 디버깅 출력문을 두었습니다.

몇개의 오류를 잡았지만 생각 못한게 있었네요..

바로바로바로 memento에 들어가는 것들이 모두 referrence 타입이라는 것입니다.ㅋ

메멘토를 만들때 저장할 것들이 reference 타입이므로 그대로 대입하면 ( var = imRefType; )

 memento가 저장되는 것이 아니라 포인터만 늘어가게 되는 것이죠...

코드를 짜면서 생각해보았지만 혹시..하면서 일단 복사하지 않고 대입을 해보았는데(속도를 위해서..)

 안되더군요..

일단 학교를 가야 하므로 여기까지 해야 겠습니다.
신고
by danguria 2009.10.27 12:07
UndoRedo를 구현하기 위해서 Memento 패턴을 사용하고 있습니다.

Command패턴과 섞어서 쓰는 것이 맞는지 모르겠지만 일단 Memento만 이용하고 있습니다.

UndoRedo했을때 대상이 되는 상태를 심볼매니저에 있는 멤버변수들로 했습니다.

심볼매니저의 멤버변수에는 현재 캔버스에 그려진 심볼들, 사용자가 선택한 심볼들, 라인을 가질 후보 Figure

이 있습니다.

DSymbolManager가 Originator가 되고,

DMemento가 memento가 됩니다.

reodo undo를 하기 위해서 memento를 많이 갖고 있어야 하므로, 그것을 관리하는 UndoRedoManager를 만
들어 관리하도록 하였습니다.

클라이언트에 해당하는 painter클래스에 DSymbolManager와 UndoRedoManager를 가지고 redo undo를 

수행 하도록 했습니다.

내일 정보보호론 시험이 있는 관계로 설계만 하고 마쳐야 할 것 같습니다.


신고
by danguria 2009.10.25 12:04
기존의 타입 안전 열거형 클래스는 각 심볼의 타입을 나타내기 위해서 만들었습니다.
각 심볼의 순서가 필요하지 않기 때문에 클래스에 타입정보만 들어 있었습니다.

이번에 만든 타입 안전 열거형 클래스는 
심볼을 클릭하면 리사이즈 박스가 나오는데, 이때 8개의 리사이즈 박스를 나타내야 합니다.
(LEFT, RIGHT, UP, DOWN, LEFTUP, LEFTDOWN, RIGHTUP, RIGHTDOWN)
8개의 리사이즈 박스 자체만으로는 순서가 필요없지만, 마우스가 어떤 리사이즈 박스를 클릭했는지 알려면 
루프를 돌면서 확인을 해야 하고 그때의 딱 걸릴때의 루프 변수번째가 해당 박스라고 구현 되어 있으므로 
순서를 정해 주어야 했습니다.

다음은 기존의 리사이즈 박스에 대한 Named constant을 쓰고 있는 코드 입니다.

/**
     * 현재 클릭 된 곳이 리사이즈 박스안에 있는 것인가를 알아보는 함수
     * @param mousePoint
     * @return
     */
    public int isReSizeArea( Point mousePoint )

    {

        this.clickedResizeBox = -1;

        for( int i = 0; i < this.numResizeBox; i++)

        {

            if( (this.resizeBoxStartPoints[i].x <= mousePoint.x)

            && (this.resizeBoxStartPoints[i].x + this.resizeBoxWidth >= mousePoint.x)

            && (this.resizeBoxStartPoints[i].y <= mousePoint.y)

            && (this.resizeBoxStartPoints[i].y + this.resizeBoxWidth >= mousePoint.y))

            {

                this.clickedResizeBox = i;

            }

        }

        return this.clickedResizeBox;

    }


심볼에 대한 타입 안전 열거형 클래스에는 순서를 적용 할 수 없었지만,
방법이 없는건 아닙니다.
그래서 새로 만든 순서 기반의 타입 안전 열거 클래스입니다.


public class DResizeBox {
    private final String box;
    private DResizeBox(String box){
        this.box = box;
    }
    @Override
    public String toString(){
        return box;
    }

    public static final DResizeBox LeftUp = new DResizeBox("LeftUp");
    public static final DResizeBox RightUp = new DResizeBox("RightUp");
    public static final DResizeBox LeftDown = new DResizeBox("LeftDown");
    public static final DResizeBox RightDown = new DResizeBox("RightDown");
    public static final DResizeBox Up = new DResizeBox("Up");
    public static final DResizeBox Down = new DResizeBox("Down");
    public static final DResizeBox Right = new DResizeBox("Right");
    public static final DResizeBox Left = new DResizeBox("Left");
    public static final DResizeBox ArrowStart = new DResizeBox("ArrowStart");
    public static final DResizeBox ArrowTarget = new DResizeBox("ArrowTarget");
    public static final DResizeBox ArrowZigzag = new DResizeBox("ArrowZigzag");
    public static final DResizeBox None = new DResizeBox("None");
    private static final DResizeBox PRIVATE_ORDERED_BOX[] = {
        LeftUp, RightUp, RightDown, LeftDown, Up, Right, Down, Left    // None은 넣지 않았음.
    };
    public static final List orderedBox =
            Collections.unmodifiableList(Arrays.asList(PRIVATE_ORDERED_BOX));
}

타입 안전 열거로 정의한 상수는 객체이므로 컬렉션에 넣을 수 있습니다.. 이런식으로 하여 아까전의 코드를 거의 바꾸지 않고 구현 할 수 있었습니다..

매우 좋은것 같다.ㅋㅋ


신고
by danguria 2009.10.23 22:44

기나긴 고민뒤에 Type safe enumeration pattern이라는 것을 발견하고 public static finale int 로 정의된 열거

형 변수들을 정리 하고 있습니다.

C언어에서는 enum구문이 자바에는 없습니다.

 (Enumeration이라는 인터페이스가 있지만 C/C++의 enum과 달리 iterator입니다.)

C에서는

#define TERMINAL 0

#define PROCESS 1

#define LINE 2

...

이런식으로 하던지, 

typedef enum { TERMINAL, PROCESS, LINE, ARROW, ...}symbolType;

이런식으로 사용했습니다.

하지만 자바에서는(물론 자바에서만은 아니겠지만 지금은 자바만 생각하고 있습니다.) 어떻게 해야 할지 몰랐습니다.

그래서 C와 비슷한 방식으로, 클래스안에 값을 직접 적어 넣었습니다.(일종의 하드 코딩을 했습니다.)

Class DSymbol{

public static final int TERMINAL = 0;
public static final int PROCESS = 1;
public static final int LINE = 2;
}


아직까지 이렇게 했을때 큰 문제점을 없었습니다. 있다고 한다하더라고 큰 문제는 없을 것입니다.

하지만!!! 아름다운 코드를 만들기위해서 이렇게 하면 안좋다는 것을 알게 되었습니다.


문제점을 찾아보니 

1. 새로운 상수를 추가 했을 경우 사용자 코드도 다시 컴파일 해야 한다.

2. 새로운 상수가 사용자 코드와 충돌을 일으킬 수 있다.

3. 이런 방식은 출력 가능한 문자열로 바꾸거나, 상수들을 모두 열거할 수 있는 방법을 제공하지 않는다.

그리고 이펙티브 자바책을 보니 "public static final String TERMINAL = "TERMINAL";"로 구현 해도 안된다고 합니다.

이경우 사용자가 TERMINAL과 같은지 비교 하기 위해 "TERMINAL"이라는 문자열을 코드에 직접 넣을 경우, 타이핑

오류를 런타임에 확인 할 수 없고, 디버깅이 어려지기 때문이죠. 

1.번과 2.번과 같은 경우는 내가 짠것을 나만 쓴다면 이런 문제가 없겠지만 이것을 API화 하여 다른 사람이 이것을 쓰

거나 팀프로젝트를 할 경우, 다른 팀원이 나의 클래스를 사용할 경우에 문제가 될 수 있습니다. 

(항상 내코드는 남이 쓸것이다라는 생각을 해야 좋은 코드가 나올 것 같네요..)


이런 문제점을 해결하기 위한 좋은 방법이 있습니다.

Type safe enumeration pattern이라는 것이 있습니다.

가장 간단한 구현은 다음과 같습니다.

public class DSymbolType {

    private final String type;

    private DSymbolType(String type){

        this.type = type;

    }

    public String toString(){

        return type;

    }
    public static final DSymbolType Terminal = new DSymbolType("Terminal");
    public static final DSymbolType Process = new DSymbolType("Process");
    public static final DSymbolType Decision = new DSymbolType("Decision");
}

이 방법의 좋은 점은 다음과 같습니다.


1. static final필드에서 정의된 객체 외에 다른 객체가 생성될 수 없다.

2. 컴파일 시점의 타입 안정정을 제공해준다.

3. 새로운 상수가 추가되더라도 client코드를 변경할 필요가 없다.

4. 상수를 출력가능한 문자열로 문자열로 바꿀수 있다.

1. 같은 경우는 클래스가 final선언이 되어 있지 않지만 생성자가 private으로 선언되어 있으므로, 

이 함수를 상속받더라고 생성자를 호출 할 수 없어서서 결국 상속 받을 수 없다. 따라서 정해진 객체만 참조 할 수 있

는 것이겠죠.

2. 번 은 이 타입안정 열거형을 사용했을 경우, DSymbol의 객체는 NULL아니면 세개 중의 하나겠죠,

 그러므로 잘못된 코드를 작성할 경우 컴파일 타임에 그것을 알게 될 것입니다.

3. 예전에는 새로운 상수가 추가 되면 client 쪽 코드도 변경이 되어야 했지만 이렇게 함으로서 client쪽 코드를 변경

하지 않아도 되게 되었습니다. OCP원칙을 지키게 되었네요.ㅋ

4. 클래스의 toString() 함수를 이용함으로써 상수를 문자열로 제공 할 수 잇는 수단이 생겼습니다.


기본적인 타입 안전 열거형을 업그레이드 하는 버전이 많지만 오늘을 여기 까지 해야 겠네요..


아무튼 저의 코드가 아름다워 지고 있습니다~~


와~~ 만세~~~

신고
by danguria 2009.10.20 23:58
| 1 |

티스토리 툴바