Tag Archives: PHP

PHP로 C2DM 푸시 이용하기

0.

아이폰의 푸시 서비스는 애플에서 제공하는 APNS(Apple Push Network Server)를 이용한다. 개별 아이폰 기기를 식별하는 udid 와 앱스토어의 개발자 계정만 갖고 있으면 푸시 서비스가 가능한 것. 왜 그랬는지는 도무지 모르겠지만 얼마전까지만 해도 안드로이드는 그러한 서비스를 갖고 있지 않았다. 따라서 무진장 귀찮게 커스텀 푸시 서비스를 구축하거나, 엄청난 배터리 소모와 트래픽을 요구하는 polling 방식을 사용할 수 밖에 없었던 것. 구글이 뒤늦게나마 정신 차려서 만든 것이 C2DM. 구글이 개발자에게 제공하는 푸시 네트웍 서버 되시겠다.

1.

안드로이드 내부에서 설정하는 부분은 그렇게 어렵지도 않거니와, 참고자료가 무진장 많다. 따라서 설명은 생략.
나보다 훨씬 더 잘 설명해주실 분들의 링크로 대신한다.

http://blog.naver.com/PostView.nhn?blogId=huewu&logNo=110087032264
http://eddykudo.com/91
http://code.google.com/android/c2dm/

2.

안드로이드 쪽의 개발은 전혀 문제가 없었는데, 전혀 문제 될 거라 생각하지 못했던 서버 쪽에서 문제가 발생했다.
구글이 제공하는 친절한 예제는 죄다 자바 서블릿 기반이라 PHP 로 만들어야 하는 내게는 쓸데 없는(그리고 머리 아픈) 자바 코드일 뿐이었다.
뭐 어쨌든 그 덕에 한동안 쓸 일 없었던 curl 을 징그럽게 공부했다. (그러나 늘 그렇듯 풀고보니 사소한 실수였음)

[code php]

$ch = curl_init(); 
 
curl_setopt($ch, CURLOPT_URL, "https://www.google.com/accounts/ClientLogin"); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
 
$data = array('accountType' => 'HOSTED_OR_GOOGLE', 
'Email' => '아이디', 
'Passwd' => '비번', 
'source'=>'test-1.0', 
'service'=>'ac2dm'); 
  
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 
curl_setopt($ch, CURLOPT_POST, true); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 

$result = curl_exec($ch);
$auth = substr(strstr($result, "Auth="), 5);
$auth = substr($auth, 0, strlen($auth)-1);

curl_setopt($ch, CURLOPT_URL, "https://android.apis.google.com/c2dm/send");

$data = "registration_id=등록아이디"."&collapse_key=1"."&data.msg=메세지";
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

$headers = array(
    "Content-Type: application/x-www-form-urlencoded",
    "Content-Length: ".strlen($data),
    "Authorization: GoogleLogin auth=$auth"
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
echo $result."\n";

curl_close($ch);

[/code]

정리 전혀 안된 명백한 테스트코드.
php 의 curl 모듈(일반적으로 기본설치)을 이용해 구글 ClientLogin 의 Authentication 을 획득하고, 그 복잡다단한 키를 헤더에 포함하여 c2dm 서버에 날리면 된다.
아아주 쉽다.

3.

사실 저 부분에서 포인트는

[code lang-php]
$auth = substr($auth, 0, strlen($auth)-1);
[/code]

달랑 요 한 줄이다.
보는 바와 같이 끝에 붙은 글자 하나 날리는 간단한 구문.
요 한 줄 때문에 한나절은 꼬박이 삽질했다.
단일 헤더 프로퍼티에는 절대, 무조건, 반드시! 개행문자가 삽입되면 안된다.
그런데 Google ClientLogin 으로 요청하면 SID, AUTH 등의 개별 키들을 개행문자로 구분해버리니 쉴 새 없이 Unauthorized 메세지가 뜬 것이다.

4.

비전공자가 보면 귀신 시나락까먹는 소리고, 이 블로그 방문객의 대다수가 비전공자이기 때문에 요런 글 웬만하면 안 쓰자-라는 주의였는데.
일하면서든, 혼자 뚜닥거리면서든 이렇게 작은 경험 올려주시는 많은 개발자 분들 덕택에 쉽게쉽게 갈 때가 많아
나름 보은의 차원에서 짧게 두드려봤다.

덧,
혹 C2DM 시도하다 해결되지 않는 문제가 있다면 댓글 남겨주시길.
해결은 못 해드려도, 같이 고민은 해드릴게요. ㅋ

Study Hard- 공부하자, 빡씨게-

어느 순간이 시작이었는지는 모르겠다.
나는 지금 Web Application Developer 가 되기로 마음 먹고 있다.
(그리고 어느 정도는 됐다고 해야 하나;)


[#M_내가 프로그래머가 되겠다고 생각하게 된 것은... (열기)|내가 프로그래머가 되겠다고 생각하게 된 것은... (닫기)|프로그래밍은 초등학교 때 퍼스널컴퓨터경진대회(정보올림피아드의 전신격인 대회) 에 참가하라는 선생님의 강권-_-에 잠깐 두리번거렸던 GW-Basic 이 시작이었다. 마땅한 테스트 환경도 없었고 (심지어 GWBASIC.COM 파일조차 없었으니 ㅋ) 그냥 무작정 친척형이 주고 간 책 한 권을 읽은 게 다였는데 덜컥 장려상을 타버렸다. 동상 이상이면 바로 시 대회 참가자격이 주어졌으니, 만약 내가 당시에 조금 더 공부를 열심히 했었다면 내 인생이 어떻게 바뀌었을지 자못 궁금하기도 하다.

중1 말에 동네 컴퓨터 학원에서 C언어를 배웠다. 초등학교 4학년부터 다니기 시작한 학원이었는데 내가 더이상 배울 게 없어지자 (그 학원의 거의 모든 수업을 다 들었으니까) 나와 몇몇 장기 수강-_- 학생들을 위한 원장님의 배려로 개설된 강좌였다. Turbo C 의 파란색 코드 스크린이 왜 그리 좋았는지 모른다. 그 때부터 참 이것저것 많이 배웠다. 당시에 나름 인기였던 비베(Visual Basic)와 델파이(Delphi)도 해봤다. 나를 가르쳤던 손동우 선생님이 조금만 더 나를 채찍질 하고 기본기를 닦아주었다면 좋았을걸 하는 아쉬움도 있지만, 어쨌거나 어린 나이에 이것저것 여러 언어들을 다뤄봤던 경험은 소중하게 남았다. (지금은 어디 계신지 연락도 안 되지만 꼭 한번 만나고 싶다)

중3 때 고등학교 과목들을 미리 배운다고 선수학습 하고 난리일 때, (정석과 성문 따위를 공부하는 애들이 반에 다섯 이상은 되던 때에) 나는 나름 C++ 계의 명저라고 할 수 있는 Sams Publishing 의 Teach Yourself C++ 를 껴안고 연습장에 코드들을 적으며 지냈다. 확실히 지금 봐도 좀 어리벙벙하게 볼 만큼 재미없는 책이고 설명도 그냥 나열식인데다가 번역도 그지 같은 책인데 그 땐 그냥 그런 어려운 책이라 더 좋아했던 것 같다.

고1 때 정보올림피아드 준비했던 이야기는 그간 많이 썼으니 패스.
고2 부터 PHP 를 시작했다. 홈페이지를 만드느라 제로보드 스킨을 공부했었고 그 때문에 약간의 사전지식 정도는 있던 스크립트지만, 이걸 제대로 시작하게 된 건 정말 웃기도록 단순한 이유였다. 당시 사귀던 여자친구(나름 풋풋한 내 인생의 첫사랑, ㅋ) 에게 보여주고자 D-Days Checker 를 만들기 위한 것이다. 사귄지 몇일 됐는지 알려주는 단순한 형태에서 200일 300일 기념일까지 알려주고 날짜에 따라 다른 음악까지 틀어주는 형태로 버젼업을 계속했다. 참 웃기지만, 그 친구와 헤어지고나서도 버젼업은 계속 됐다. 지금은 이 코드가 어디 갔는지 모르겠지만;

웹 프로그래밍을 제대로 시작한 건 제대 후였다. 군대 가기 전에 관심을 갖던 플래시 액션스크립트는 내가 군대에 있는 동안 3.0 이 대세가 되었고, 병장 때 틈틈이 공부하던 AS 2.0 코드들은 제대 후 쓸모가 없어졌다. 3.0 으로 마이그레이션 하며 공부하는 일은 여러모로 골치가 좀 아팠다. 컴공 다니는 후배의 숙제를 해주다가 지금 실력으론 답이 안 나오자 밤 새는 날이 길어졌고 덕분에 PHP 에 대한 이해도는 무진장 올라갔다.

우연히 지춘이 녀석을 통해 알게 된 실타래. 홀로 공부하던 그 긴긴 날들이 의미를 갖게 한 나름 소중한 시간, 이었지만. 모든 것들이 손발 맞는 느낌은 확실히 아니었다. 아이디어 수준의 기획을 공학 기반의 기획으로 바꾸는 일이 혼자서는 조금 버거웠다. 기획도 중간에 여러번 수정되었고, 그럴 수록 모자란 내 실력에 대한 안타까움이 늘었다. (약간의 자신감도 같이 크긴 했다)_M#]


… 이랬다.


하면 할 수록 공부 할 것들만 늘어간다.

경호 녀석의 뽐뿌질로 시작하게 된 Ruby On Rails.
배우면 배울 수록 재밌는 스크립트 언어다. 지금까지 내가 해왔던 것들과는 너무 다른 형태의 문법이 여러모로 좀 낯설지만 그런 것들을 배울만한 가치는 충분해 보인다. Ruby 와 Rails 모두. 아직은 Ruby 언어가 익숙치 않아 Rails 가 조금 답보 상태. Ruby 책을 또 사야 하나.

갈수록 알흠다워지는 Flex Flash
Flex Builder 3 는 ‘아직 시기상조인가;’ 싶었던 아쉬움을 날려줬다. 인간적으로 Builder 2 의 빌딩 타임은 짜증날 정도였다. 이클립스 기반의 개발 툴도 어느 정도 안정감 있게 자리 잡은 느낌이고, 다른 어떤 언어보다 코딩 감이 좋다. 다만 문제가 발생하면 걸리는 부분이 너무 많아 골치 아픈 점은 여전. 특히 Flash 기반은 더더욱 그렇다. 조금 된 이야기지만 Flash Player 10 이 (베타지만) 릴리즈 된 이후에 그래픽 처리 부분에서 꽤나 큰 성능 향상이 보인다. 조금 화려하다 싶으면 CPU 점유율이 미친듯이 치솟던 이전 버젼들에 비해 GPU 를 사용하는 새 버젼의 느낌은 참 좋다.

기대감이 가득차게 하는 WPF Silverlight
일단 나는 그냥 문법적인 느낌은 C# 이 가장 좋다. 가장 익숙하면서도 가장 간결하다. 또 Visual Studio 기반의 RAD 지원은 말이 필요 없는 최고 수준. (아; 이건 재론의 여지가 있지만 나의 경우 가장 코딩 속도가 붙는다) 하지만 지금 당장 배우기에 너무 많은 것들이 성에 차지 않는다 할까. 똑같은 결과물이 있을 때 이미 Flex 로는 세세한 구성부터 코딩까지 그려지는데 Silverlight 로는 뭐부터 해야 할지 난감하다. 아직 안정성 문제도 좀 떨어지는듯 싶고. 그러나 MSDN 을 믿는다. 플렉스는 우리나라의 용자들이 그 엄청난 노력을 통해 한글화 레퍼런스를 만들어 가고 있지만. MS, 늬들은 사용자들에게 저런걸 시키진 않을거라고 믿는다.

이외에도.
그냥 맛만 본 AJAX 도 Ruby On Rails 공부와 같이 다시금 해야 할 필요가 있을 듯 하고.
여러가지 디자인 패턴들도 공부 선상에 올려놓고 있다. (제일 먼저는 TDD, 근데 이거 배우려면 Python 먼저 배워야 된다;)
Objective-CCocoa 도 배우고 싶다. 이건 맥이 있어야 하니까 당분간은 패스. 음, 사실 이걸 배우고 싶은건지 그냥 맥을 갖고 싶은건지는 모르겠다. 어쩌면 둘 다일 거다. 저걸 보니까 맥이 갖고 싶어진 걸지도 모르고 ㅋ (사실 나는 별로 애플을 좋아하지 않는 사람 중 하나지만)


우선순위를 매기는 것은 힘들다.
그래서 동시에 다 하고 있다.
죽도 밥도 안 되어도 좋다, 먹기만 하자.

[FRDB Project] 03 – view.php 와 플래시 액션스크립트

그간 이래저래 공연도 끼어있고 해서 1,2번 포스트가 올라오던 시점에 비해 업데이트가 늦어졌다.
하지만 시간의 간극이 워낙 크다보니, 그 사이에 놀고 있지만은 않았다는 사실을 증명하듯.
의외로 꽤나 많은 부분에서 진척이 이루어졌다.

대망의 디자인 업데이트 된 페이지뷰가 등장하기 전에 몇가지 업데이트 사항을 기록하고자 한다.

1. menu.swf

[Flash] /attachment/1313033471.swf



- 별다른 설명이 필요 없는. 언제나 레이아웃 상단에 위치할 메인메뉴 네비게이션

* 동그라미에서 막대가 되는 애니메이션은 프레임을 이용했고, 각각의 메뉴가 독립적으로 동작하는 부분은 액션스크립트를 통한 프레임 액션 함수- MovieClip.prevFrame() MovieClip.nextFrame() -들을 이용하여 구현
* 동그라미에서 막대로 변하는 심볼은 하나지만, 각각에 대응하는 메뉴이름들은 전부 각각의 이름(접미어 _m) 으로 개별 등록되어 있고 액션스크립트를 통해 동적으로 등록- MovieClip.attachMovie() 후 일괄적으로 위치 배치 & 회전
* 동적으로 등록된 각각의 메뉴이름들은 재생된 프레임 비율을 계산하여, 등록된 Color 객체의 setRGB 메소드를 통해 밝기 변경
* 무비클립의 Tint 속성을 통해 개별 메뉴의 색 구분
* 각각의 메뉴에 대응하는 링크/타겟 배열을 두어 링크 관리를 용이하게 구현

※ 각각의 메뉴 무비클립 : menu01 ~ menu16 / 메뉴이름 동적연결 이름 (linkage name) menu01_m ~ menu16_m
[#M_menu.swf 액션스크립트 소스 - level0 (열기)|menu.swf 액션스크립트 소스 - level0 (닫기)|

(Language : javascript)


  1. // 본 파일은 소스코드 작성당시 파일이라 링크는 정확하지 않음


  2. var linkArray = new Array(


  3.       "http://minsangk.com/kid/test/02.html",


  4.       "http://minsangk.com/kid/test/03.html",


  5.       "http://minsangk.com/kid/test/04.html",


  6.       "http://naver.com",


  7.       "http://naver.com",


  8.       "http://naver.com",


  9.       "http://naver.com",


  10.       "http://minsangk.com/kid/test/08.html",


  11.       "http://minsangk.com/kid/test/10.html",


  12.       "http://pds6.egloos.com/pds/200711/08/03/12.bord2.html",


  13.       "http://pds7.egloos.com/pds/200711/08/03/11.bord1.html",


  14.       "http://minsangk.com/kid/test/09.html",


  15.       "http://pds7.egloos.com/pds/200711/08/03/13.bord3.html",


  16.       "http://pds7.egloos.com/pds/200711/08/03/14.bord5.html",


  17.       "http://cafe.naver.com/frdb",


  18.       "http://cafe.daum.net/kicha"


  19.       );


  20.  


  21. var targetArray = new Array(


  22.       "_self",


  23.       "_self",


  24.       "_self",


  25.       "_self",


  26.       "_self",


  27.       "_self",


  28.       "_self",


  29.       "_self",


  30.       "_self",


  31.       "_self",


  32.       "_self",


  33.       "_self",


  34.       "_self",


  35.       "_self",


  36.       "_blank",


  37.       "_blank"


  38.       );


  39.  


  40. headerTitle.onRelease = function()


  41. {


  42.  getURL("http://minsangk.com/kid/test/01.main(1).htm","_self");


  43. }


_M#]
[#M_menu.swf 액션스크립트 소스 - button_proto (열기)|menu.swf 액션스크립트 소스 - button_proto (닫기)|
(Language : javascript)


  1. stop();


  2.  


  3. // 최초 1회 실행


  4. if (count == undefined) {


  5.  // 각각의 메뉴 이름 동적으로 등록


  6.  this.attachMovie(this._name + "_m", this._name + "_m", this.getNextHighestDepth());


  7.  


  8.  // 등록된 메뉴 이름 무비클립의 재배치 / 회전


  9.  menuName = this[this._name + "_m"];


  10.  menuName._x = 9;


  11.  menuName._y = 54;


  12.  menuName._rotation = -49.5;


  13.  


  14.  count=1;


  15. }


  16.  


  17. // 메뉴 이름의 Color 객체 생성


  18. menuName_color = new Color(menuName);


  19. menuName_color.setRGB(0×000000);


  20.  


  21. // 롤오버-아웃시 rollover 변수의 값 토글


  22. this.onRollOver = function()


  23. {


  24.  rollover = true;


  25. }


  26.  


  27. this.onRollOut = function()


  28. {


  29.  rollover = false;


  30. }


  31.  


  32. this.onEnterFrame = function()


  33. {


  34.  if (rollover)


  35.  {


  36.   // 현재 프레임이 최종 프레임이 아니면 순방향 재생


  37.   if (this._currentframe != this._totalframes) {


  38.    this.nextFrame();


  39.   }


  40.   // 재생이 종료 되었을 경우 stop


  41.   else {


  42.    stop();


  43.   }


  44.  }


  45.  // 이외의 경우 역방향 재생


  46.  else


  47.  {


  48.   this.prevFrame();


  49.  }


  50.  


  51.  // 재생된 프레임 비율을 계산하여 setRGB 매개변수 포맷으로 변환


  52.  color_int = int ( (this._currentframe-1) / (this._totalframes-1) * 255 );


  53.  color_0x = “0x” + color_int.toString(16) + color_int.toString(16) + color_int.toString(16);


  54.  


  55.  // 메뉴 이름에 링크되어 생성된 Color 객체에 색 지정


  56.  menuName_color.setRGB(color_0x);


  57. }


  58.  


  59. // 클릭 시 해당되는 주소/타겟 으로 링크


  60. this.onRelease = function()


  61. {


  62.  linkIndex = Number(this._name.substr(4,2)) -1;


  63.  getURL(_root.linkArray[linkIndex],_root.targetArray[linkIndex]);


  64. }

_M#]
후배님이 디자인한 내용을 초안으로 최대한 노가다 작업을 아껴보고자 액션스크립트를 사용했다. 동적으로 연결되는 메뉴이름 무비클립들의 밝기를 일괄조정 하는 작업에서, 과도한 시스템 자원 낭비를 방지하기 위해  colorTransform 클래스를 안 쓰고 오로지 Color 객체의 setRGB 메소드만 사용했다. 왜 액션스크립트에는 변수를 포맷팅해서 출력해주는 함수가 없는가-_- 찾다찾다 gg치고 그냥 내가 하려하다보니 좀 난잡한 코드를 만든 감이 없잖아 많은듯-_- 어쨌든 구현에는 성공했다. 프레임 액션은 이것말고도 참 여러모로 쓸모가 많은 코드인듯 싶네. 여기 말고도 현재 제작중인 플라곤 홈페이지의 메인메뉴 네비게이션도 똑같은 방식으로 구현되어 있다. 그것도 그렇고 여기 이 녀석도 그렇고 어쨌든 메뉴 네비의 첫 구상을 내가 하지 않은 경우, 액션스크립트를 통해 자연스러운 애니메이션을 구현하다보면 결국 결론은 프레임 액션으로 귀결되는 것 같다. AS1.0 시절의 노가다성 프레임질에 AS2.0 을 통한 고급스러운 뒷마무리- 라는 느낌을 주는 기술. 어쨌거나 좀 더 화려하고 직관적인, 그러면서도 시스템 효율을 최대한으로 이끌어내는데에 참 유용한 기술인 것만은 분명하다. (다만 구현이 그렇다는 것이고, 구현 후에 수정하려면 여러모로 귀찮아진다는 것 때문에 본인은 별로 선호하지 않을뿐)


2. view.php

http://minsangk.com/frdb/view.php
- idx 파라미터를 넘겨받아 지정된 자료를 테이블로 출력하는 파일

* 구성된 레이아웃대로 각각의 필드를 출력
* 사업상황(state 필드) 의 내용에 따라 1:1 대응되는 신호등 이미지 출력
* 관련노선(linkingIDX 필드) 의 내용을 구분자(|)를 기준으로 explode 하고, 해당 idx 의 노선명을 쿼리 전송받아 각각의 링크를 가진 문자열로 출력
* 목록으로 되돌아가는 버튼 폼
* list.php 코드에 해당 인덱스를 매개변수로 하여 view.php 를 호출하는 하이퍼링크를 추가
 - <a href=”./view.php?idx=??”>

이건 후배님이 하고 있는 페이지 디자인의 초안이 나오면 들어가려고 계획된 것이었는데, 후배님의 PPT 발표 예정 상황과 겹쳐 하루만에 초고속 날림-_- 제작되었다. (그런데 중요한건 PPT 발표가 미뤄져서 이 녀석은 아직 미공개 상태라는거) 다른 페이지와 마찬가지로 CSS 가 눈꼽만큼만 사용된 극도의-_- 코드위주 페이지이지만 어쨌든 계획된 내용에서 필요한 부분으로 체크된 내용은 전부 구현되었다고 보아도 좋다. 관련자료 필드 추가가 이뤄지면 또 한번의 코드 수정은 불가피하겠지만, 그 외의 부분은 (디자인을 제외하고) 거의 완성 단계다.

워낙 오랜만에 다시 손 댄 PHP 코드라 내가 짜놓은 녀석들이 낯설어 보여 약간의 고생은 했지만, 요즘 과외 때문에 비슷한 구성과 색다른 문법을 지닌 JSP 를 공부하고 있는것이 나름의 상승 작용을 한 것 같은 느낌이다. PHP 코딩능력이 한결 좋아져서 이제 50라인 정도는 그냥 머릿속에 생각한 대로 옮기면 불필요한 중간 확인 과정을 거칠 필요 없이 작성이 가능해졌다.


3. 지역별분류.swf

[Flash] /attachment/1170838957.swf


- 입력된 DB 를 지역분류별로 출력하는 링크 네비게이션

* 각각의 조각지도를 롤오버 하면 최대 알파치로 진해지고, 롤아웃하면 다음 롤오버 액션에 상관없이 부드럽게 최소 알파치로 변경
X 각각의 조각지도에 대응하는 리스트 출력
(list.php 에서 각각의 상황에 맞는 vMode 추가가 이뤄지는대로 링크 예정)

※ 각각의 조각 지도 무비클립 : sub1 ~sub7

[#M_지역별분류.swf 액션스크립트 소스 - level0 (열기)|지역별분류.swf 액션스크립트 소스 - level0 (닫기)|
(Language : javascript)


  1. // sub (조각지도) 의 갯수


  2. AmountOf_sub = 7;


  3.  


  4. // 특정 링크 선택 변수(roll), 알파 변화 가속도(acc), 최대 알파치(maxAlpha), 최소 알파치(minAlpha) 초기화


  5. roll = 0;


  6. acc = 0.1;


  7. maxAlpha = 100;


  8. minAlpha = 40;


  9.  


  10. // 각각의 sub 가  롤오버되면 roll 변수에 sub 의 인덱스 저장


  11. for(var i =1; i<=AmountOf_sub; i++)


  12. {


  13.  this["sub"+i].onRollOver = function()


  14.  {


  15.   roll = substring(this._name,4,1);


  16.  }


  17.  this["sub"+i].onRollOut = function()


  18.  {


  19.   roll = 0;


  20.  }


  21. // 각각의 sub 를 최소 알파치로 초기화


  22.  this["sub"+i]._alpha = minAlpha;


  23. }


  24.  


  25. this.onEnterFrame = function()


  26. {


  27. // 선택된 sub 는 최대 알파치로 가속, 나머지 sub 는 최소 알파치로 가속


  28.  for(var i =1; i<=AmountOf_sub; i++)


  29.  {


  30.   if(i == roll) {


  31.    this["sub"+i]._alpha += (maxAlpha – this["sub"+i]._alpha)*acc;


  32.   }


  33.   else {


  34.    this["sub"+i]._alpha += (minAlpha – this["sub"+i]._alpha)*acc;


  35.   }


  36.  }


  37. }


_M#]
지도의 출처는 아마도 네이버가 아닐까 싶은데- 후배님이 손수 비트맵 파일을 따서 각각의 조각지도를 PNG 로 저장했고. 나는 그 파일을 받아 Magic Wand 툴로 투명 부분의 Shape 를 삭제해 심볼화했다. 군대 행정반에서부터 시작된 액션스크립트 2.0 공부는 사실상 이러한 스타일의 부드러운 메뉴 네비게이션을 구현하기 위해서 였다고 해도 과언이 아닐 거다. 이제는 그 코드 구현이 어느 정도 머릿속에 확고히 자리 잡아 어떠한 형식이라도 가장 간결한 형태로 코딩하는 방법을 찾았고. 위 코드는 대략 그 모든 조건이 최적화 되어 있다. 이 블로그에 구현될 메뉴 네비도 대략적으로는 이런 형식에서 크게 벗어나지 않는 형태가 될 듯. 문제는 노력과 시간. 일단 머릿속에 대강의 디자인과 구성이 들어가 있으니, FRDB 프로젝트가 끝나는대로 작업 시작이다-.-.- 그때쯤이면 넘치도록 뛰어난 후배님의 디자인 센스를 마구마구 부려먹는거다. 하하-.-.-


4. 수도권노선도.swf

 

[Flash] /attachment/1118899035.swf


- FRDB 에 DB화 되어 등록된 자료 중 수도권 분류 노선들과 1:1 매칭되는 수도권 노선도 플래시 파일

* 어느 위치에서나 토글(toggle) 방식으로 이동과 정지가 가능
* 화면 중앙을 중심으로 좌우상하 이동 폭에 따라 노선 이미지의 상하좌우 검색이 가능
* 노선 이미지의 경계선을 인식하여 유효범위가 오버플로우 되지 않음
* 등록된 노선을 오버마우스 하면 블러 필터를 통해 하이라이트 됨
* 등록된 노선을 배열로 관리하여 삽입, 수정, 삭제가 용이하게 구성
(위 파일은 현재 인천지하철 3개 노선만 등록되어 있음)
X 로드 매개변수로(GET Method) idx 를 입력받아 특정 노선을 하이라이트 시키고 그 위치로 전체 노선도를 위치시킴
(이건 조만간에 구현 예정 -_-_-)

※ 전체 노선도 무비클립 : mc_all / 각각의 노선 무비클립 : mc_all.sub?? (물음표 자리에 해당 노선의 idx)


[#M_수도권노선도 swf 액션스크립트 소스 - level0 (열기)|수도권노선도 swf 액션스크립트 소스 - level0 (닫기)|
(Language : javascript)


  1. // 노선도 이미지 전체 사이즈


  2. allWidth = 3100;


  3. allHeight = 2311;


  4.  


  5.  


  6. // 노선도 이미지 전체 사이즈


  7. allWidth = 3100;


  8. allHeight = 2311;


  9.  


  10. // 캔버스 전체 사이즈


  11. canvasWidth = 930;


  12. canvasHeight = 693;


  13.  


  14. // 이동 가속도, 이동/정지 모드 초기화


  15. acc = -0.05;


  16. _root.moveMode = false;


  17.  


  18. if(idx) {


  19. // idx 관련 구현 소스 들어갈 자리


  20. }


  21.  


  22. // 이동/정지 모드 토글


  23. mc_all.all.onRelease = function() {


  24.  if(_root.moveMode) {


  25.   _root.moveMode = false;


  26.  }


  27.  else {


  28.   _root.moveMode = true;


  29.  }


  30. }


  31.  


  32. this.onEnterFrame = function()


  33. {


  34. // 이동 모드일 때-


  35.  if (_root.moveMode == true) {


  36. // 화면 중앙을 중심으로 노선도의 좌우 이동


  37.   scrollStepX = (_root._xmouse - canvasWidth/2) *acc;


  38.   scrollStepY = (_root._ymouse - canvasHeight/2) *acc;


  39.  


  40. // 이미지 오버플로우 방지 if문


  41.   if(mc_all._x+scrollStepX >= canvasWidth-allWidth && mc_all._x+scrollStepX <= 0) {


  42.    mc_all._x += scrollStepX;


  43.   }


  44.   if(mc_all._y+scrollStepY >= canvasHeight-allHeight && mc_all._y+scrollStepY <= 0) {


  45.    mc_all._y += scrollStepY;


  46.   }


  47.  }


  48. }


  49.  


  50. // 블러 필터 클래스 import


  51. import flash.filters.BlurFilter;


  52.  


  53. // 관련 노선의 idx 를 배열로 등록


  54. var subListArray = new Array ( "93","95","96");


  55.  


  56. // 블러 필터 객체 생성


  57. var blur:BlurFilter = new BlurFilter(4,4,3);


  58.  


  59. // 관련 노선 필터 적용 (적용된 상태에서 알파값으로 하이라이트/노멀 상태 변경)


  60. for(var i in subListArray)


  61. {


  62.  this["sub"+subListArray[i]]._alpha=0;


  63.  this["sub"+subListArray[i]].filters=[blur];


  64.  


  65.  this["sub"+subListArray[i]].onRollOver = function()


  66.  {


  67.   this._alpha = 80;


  68.  }


  69.  


  70.  this["sub"+subListArray[i]].onRollOut = function()


  71.  {


  72.   this._alpha = 0;


  73.  }


  74. }

_M#]
후배님 수업시간에 누군가의 한마디 때문에 만들어야만 했던 녀석. 아마 그 학생은 이게 얼마나 힘든 작업인지 자기가 말하면서도 몰랐을 거다, 젠장 -_- 그 덕에 후배님의 피를 깎는 노가다와 본인의 머리털을 쥐어뜯는 노력이 만나 완성되었다. 지역별분류.swf 와 마찬가지로 후배님이 저 수많은 노선들을 손수 하나하나 포토샵으로 따서 PNG 로 저장해주었고, 나는 다시 그걸 Magic Wand 로 손보아 각각의 idx로 심볼화. 일단은 스크립트부터 완성시키느라 인천지하철 3개 노선 외에 나머지는 파일은 있으나 등록되어 있지 않은 상태. 지역별분류.swf 보다 몇배는 더 고심하고 고민하고 삽질해야 했던 스크립트였다. 이제 수십개의 관련 노선들을 추가하고 그 노선에 대응하는 idx 를 찾아 링크하고 각각의 노선 색깔에 맞는 하이라이트 컬러를 조정하고 등등의 노가다성 작업만 넘치도록 남았구나. 아아-_-_-



다음 FRDB Project 포스트는 이전 포스트에서 예고한 바와 같이 후배님이 제작중인 페이지 디자인을 중점적으로 소개해 보겠다. 아직은 이것저것 손 볼 것이 좀 많아 매 수업시간마다 있는 발표 과제 위주로 구성을 하다보니 전체적인 페이지 디자인의 윤곽이 흐릿해진 감이 있지만. PHP 코드 부분이나 중간중간 페이지를 빛내주는(ㅋ;) 플래시 액션스크립트가 어느 정도 궤도에 올랐으니, 조만간 페이지 디자인도 깔끔하게 이 무대에서 데뷔할 날이 올 것이다.


그런데,
소주 두어병 먹고 들어온 상태에서 내가 이런 포스트를 두드리게 될 줄 몰랐다. 요 아래 포스트는 우울해 죽을려고 하더니, 이렇게 신나게 이런 얘기를 떠들고 있는 것 보면. 나 그런대로 체질상 이게 맞는 거 같기도 하고. 에이, 모르겠네. 그냥 하는동안은 참 재밌었고, 해놓고 보니 꽤나 뿌듯하고. 두드리는대로 즉각적으로 결과가 튀어나오는 웹프로그래밍과 액션스크립트는 어쨌거나 참 매력 있는 녀석.

감당할 수 있는만큼만 최선을 다하면 그것도 참 열심히 사는 한 방법인데, 왠지 나란 인간은 그래서는 만족을 잘 못해버린다. 그래서 몰아놨다가 가끔 한번씩 스스로를 확 옥죄어버리면 늘 감당할 수 없을만큼 최선을 다해버리고 마는거다.

아, 참, 인생 좀 피곤하게 살아, 나도.