2010년 4월 20일 화요일

8. BitmapData

Bitmap이란 픽셀로 이루어진 이미지 데이터를 의미한다.

 

액션스크립트에서는 이 Bitmap 이미지를 편집하여 사용할 수 있다.

액션스크립트에서 Bitmap을 생성하려면 BitmapData 클래스를 이용하여 생성할 수 있다.

 

그럼 BitmapData 클래스에 대해 알아보자.

 

BitmapData

 

 

 

BitmapData 는 display 패키지에 포함되어있다.

BitmapData는 기본적으로 Rectagle을 포함하고 있으며, 픽셀 제한이 있다.

 

BitmapData 객체의 최대 크기가 8,192픽셀이며 총 픽셀 수는 16,777,216 픽셀을 초과할 수 없다. 따라서 BitmapData 객체의 폭이 8,192 픽셀이면 높이가 2,048 픽셀이어야 한다.

 

BitmapData 객체 1픽셀은 16진수로 0x00000000 로 나타내며 AARRGGBB로 표현된다.

AA = alpha, RR = red, GG = green, BB = blue 이다.

 

한 색상은 8bit이고 이것이 ARGB 4개가 하나로 합쳐진 것이므로 32bit 버퍼에 저장된다.

Bitmap 을 생성하기 위해서는 BitmapData 클래스의 BitmapData() 메서드를 이용하면 된다.

 

 

BitmapData() 메서드를 이용하여 bitmap을 생성할 수는 있지만 화면에 보여줄 수는 없다.

왜냐면 BitmapData는 DisplayObject가 아니기 때문이다.

 

지금까지 DisplayObject(눈에 보이는 모든 객체)는 addChild()를 통해 화면에 나타내주었다.

하지만 BitmapData는 DisplayObject가 아니므로 addChild() 할 수 없다.

 

BitmapData 에서 이미지를 생성하여 로드하는 순간 캡쳐를 뜨고 바로 unload()시키기 때문이다.  여기서 캡쳐는 원본이미지를 핸들링할 수 있는 BitmapData 형태로 바꿔주는 것을 말한다.

플래시에서는 캡쳐를 하면 원본을 캡쳐하고, 이 캡쳐된 비트맵 데이터를 가지고 편집을 한다.

 

그럼 캡쳐를 어떻게 하냐... BitmapData 클래스의 메서드 중에 draw() 라는 메서드를 이용하면 된다.

 

 

Flash Player 또는 AIR 벡터 렌더러를 사용하여 비트맵 이미지에 source라는 파라미터를 그리는 것이다.

 

여기서 매개변수 IBitmapDrawable은 인터페이스 클래스이다.

 

IBitmapDrawable (인터페이스 클래스)

 

눈에 보이는 모든 것들은 DisplayObject를 상속받는다.

DisplayObject는 모든 눈에 보이는 것들을 만든다.

눈에 보이는 모든 것들 : Sprite extends DisplayObject implements IBitmapDrawable

그래서 눈에 보이는 모든 것들은 IBitmapDrawable 인터페이스 클래스를 가지고 있다.

 

그럼 어떻게 할까?  아래 보이는 계층구조를 한번 살펴보자.

 

 

DisplayObject의 하위클래스로 Bitmap 클래가 있다.

 

그럼 Bitmap 클래스가 또 어떤 기능을 하는지 알아보자.

 

Bitmap

 

 

 

Bitmap 클래스는 비트맵 이미지를 표시하는 객체이다. 여기서 비트맵 이미지는 Loader클래스를 이용할 수도 있고, Bitmap() 생성자로 만들 수도 있다.

 

 

파라미터로 BitmapData를 사용한다.

 

음...그렇다면 BitmapData 클래스에서 이미지를 생성하고 편집한 걸 Bitmap 클래스가 화면에 보여준다는 말이군..

 

그럼 예제를 한번 만들어보자.

 

2010년 4월 16일 금요일

7. Motion _ (2) 재생 버튼 모션 만들기

이번에는 버튼으로 모션을 제어하는 예제를 만들어보자.

 

[code as3]
package
{
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;

public class MotionExample02 extends Sprite
{
 public function MotionExample02()
 {
  super(); // Sprite 객체 생성

  pan_mc.stop(); // 펜 초기 설정 정지

  play_mc.stop(); // 재생버튼 초기 설정 정지

  // 각 버튼 이벤트 등록
  play_mc.addEventListener(MouseEvent.CLICK, playButtonClickHandler);
  stop_mc.addEventListener(MouseEvent.CLICK, stopButtonClickHandler);
  prev_mc.addEventListener(MouseEvent.CLICK, prevButtonClickHandler);
  next_mc.addEventListener(MouseEvent.CLICK, nextButtonClickHandler);

  // 각 버튼 마우스 오버시 손모양
  setButtons(play_mc);
  setButtons(stop_mc);
  setButtons(prev_mc);
  setButtons(next_mc);
 }

 /**
  *  @private
  *  버튼 모드
  */
 private function setButtons(target:MovieClip):void
 {
  target.buttonMode = true;
  target.useHandCursor = true;
 }

 /**
  *  @private
  *  재생 버튼
  */
 private function playButtonClickHandler(event:MouseEvent):void
 {
  if(play_mc.currentFrame == 1) // // 재생버튼이면
  {
   play_mc.gotoAndStop(2); // 일시정지 버튼으로

   pan_mc.play(); // 재생

   pan_mc.addEventListener(Event.ENTER_FRAME, panStopHandler); // 펜 정지 이벤트 수신 등록
  }
  else // 일시정지 버튼이면
  {
   play_mc.gotoAndStop(1); // 재생 버튼으로

   pan_mc.stop(); // 펜 정지
  }
 }

 /**
  *  @private
  *  정지 버튼
  */
 private function stopButtonClickHandler(event:MouseEvent):void
 {
  play_mc.gotoAndStop(1); // 재생 버튼 모드
  pan_mc.gotoAndStop(1); // // 처음 재생 모드
 }

 /**
  *  @private
  *  펜 정지
  */
 private function panStopHandler(event:Event):void
 {
  if(pan_mc.currentFrame == pan_mc.totalFrames) // 프레임이 끝나면
  {
   pan_mc.stop(); // 재생 정지
   play_mc.gotoAndStop(1); // 처음 재생 모드로
   pan_mc.removeEventListener(Event.ENTER_FRAME, panStopHandler); // 수신 이벤트 제거
  }
 }

 /**
  *  @private
  *  이전 버튼
  */
 private function prevButtonClickHandler(event:MouseEvent):void
 {
  if(pan_mc.currentFrame == 1) // 첫 프레임이면
  {
   pan_mc.gotoAndStop(pan_mc.totalFrames); //마지막 프레임으로
  }
  else
  {
   pan_mc.prevFrame(); // 이전 프레임으로
  }
 }

 /**
  *  @private
  *  다음 버튼
  */
 private function nextButtonClickHandler(event:MouseEvent):void
 {
  if(pan_mc.currentFrame == pan_mc.totalFrames) // 마지막 프레임이면
  {
   pan_mc.gotoAndStop(1); // 첫 프레임으로
  }
  else
  {
   pan_mc.nextFrame(); // 다음 프레임으로
  }
 }
}
}
[/code]

 

 

아주 간단한 예제를 한번 만들어 보았다. 음..잘되는 것 같다. 하지만 여기에는 많이 문제들이 숨어 있다.

2010년 4월 14일 수요일

7. Motion _(1) 간단한 모션 만들기

간단한 모션을 한번 만들어보자. 모션을 만들위해서는 MovieClip 클래스를 이용하여 만들어야한다.

 

액션스크립트 1.0, 2.0 에서는 MovieClip을 많이 사용하였다. 하지만 MovieClip을 많이 사용하게 되면 과도한 메모리 과부하가 일어나는 문제가 발생하는 등 여러가지 단점이 많았다.

 

그래서 액션스크립트 3.0 에서는 이를 극복하기 위해 새로운 클래스를 만들었다.

주로 Sprite 클래스를 이용한다. 그렇다고해서 MovieClip을 사용하지 않는다는 것은 아니다.

 

# MovieClip을 사용하는 경우

 

1. 타임라인을 이용하여 무비를 제어할때 : 애니메이션, 모션

2. Scean 및 FrameLabel을 이용하여 작업할때

3. 타임라인 PLAY HEAD를 조작하는 작업을 할때

 

위와 같은 경우에는 MovieClip을 이용하여 작업을 한다.

 

그럼 MovieClip 클래스에 대해 한번 알아보자.

 

 

MovieClip 객체는 Sprite 객체와 다르게 타임라인이 있다.

 

MovieClip은 이렇게 많은 걸 상속받고 있다. 그래서 무겁다고 하는 것이다.

 

그럼 MovieClip 클래스에서 주로 쓰이는 속성과 메서드에는 어떤 것이 있는지 한번 알아보자.

 

속성

 

 

 

메서드

 

 

 

주로 쓰이는 메서드는 gotoAndStop(), gotoAndPlay(), nextFrame(), prevFrame(), stop() 이 있다.

 

자 그럼 이제 예제로 간단한 모션을 만들어 보자.

 

먼저 플래시 파일을 하나 만들자. 새로 만든 파일에서 ctrl + F8번을 눌러 무비클립 심볼을

하나 만든다.

 

 

그런다음 이 무비클립의 인스턴스네임을 rect_mc로 하자.

 

 

그럼 타임라인이 아래와 같이 MovieClip심볼이 생성되어 나타난다.

 

 

 

rect_mc 무비클립을 더블클릭하고 들어가서 사각형을 한번더 무비클립으로 만들어준다.

 

 

이 무비클립의 인스턴스네임은 inner_mc라고 하자.

 

 

그런 다음 타임라인에서 1프레임을 클릭하고 오른쪽 마우스를 클린한다음 Create Classic Tween을 클릭한다.

 

 

그런다음 30프레임을 클릭하고 F6을 눌러 프레임을 추가한다.

 

 

그런다음 추가한 30프레임에서 사각형을 오른쪽으로 이동시킨다. 그럼 아래와 같이 된다.

 

 

마지막으로 properties에서 Class를 아래와 같이 지정한다.

 

 

중요한것은 rect_mc 무비클립안에서 inner_mc 라는 무비클립을 하나더 만들어주는 것이다.

 

여기서 왜 무비클립을 만들고 또 그 안에 무비클립을 만드냐 하면..

 

모션 줄때 shape으로는 액션을 줄수가 없다.

 

 꼭 무비클립으로 만든 다음에 모션을 줘야한다.

 

또한 모션을 줄 땐 인스턴스네임이 필요하므로 꼭 인스턴스네임을 지정해 줘야 한다.

 

그럼 이제 MotionExample01.as 파일을 만들어 보자.

 

[code as3]
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;

public class MotionExample01 extends Sprite
{
 public function MotionExample01()
 {
  super();

  rect_mc.buttonMode = true; // 사각형 마우스 오버시 손모양

  rect_mc.stop(); // 초기 상태 정지 설정

  rect_mc.addEventListener(MouseEvent.CLICK, clickHandler); // 마우스 클릭 이벤트 등록
 }

/**
  *  @private
  *  사각형 클릭
  */
 private function clickHandler(event:Event):void
 {
  rect_mc.addEventListener(Event.ENTER_FRAME, moveRectHandler); // 사각형 이동 이벤트 등록
 }

/**
  *  @private
  *  사각형 이동
  */
 private function moveRectHandler(event:Event):void
 {
  if(rect_mc.currentFrame == rect_mc.totalFrames) // 현재 프레임이 마지막 프레임이면
  {
   rect_mc.stop(); // 사각형 정지 : 타임라인 정지

   rect_mc.removeEventListener(Event.ENTER_FRAME, clickHandler); // 사각형 이동 이벤트 제거
  }
  else
  {
   rect_mc.play(); // 사각형 이동 : 타임라인 재생
  }
 }
}
}
[/code]

 

 

 

 

자 이제 실행해보자. 위의 파란색 사각형을 클립해보자. 잘 실행되는가? 그럼 간단한 모션만들기는 성공!

 

다음에는 버튼을 추가하여 모션을 제어하는 조금더 복잡한 모션예제를 만들어보자.

 

2010년 4월 9일 금요일

FileReference _ (1) 파일 업로드 (PHP-APM 서버 연동)

파일 업로드 예제를 만들기 전에 필요한 것들이 몇가지 있다. 파일을 올릴 서버가 필요하며, 서버랑 연동할 php파일이 필요하다.

 

먼저 웹 서버를 구축 해보자. 웹 서버로 APMSETUP을 사용하겠다.

 

APMSETUP은 APM(Aphach, PHP, MySQL)를 사용할 수 있도록 자동으로 설치, 설정해주는 프로그램이다.

 

1. 주소창에 http://www.apmsetup.com  이라고 쳐보자.

 

 

위와 같은 화면이 나온다. 그럼 저기에서  다운로드 메뉴를 클릭해보자.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

그럼 위와 같이 APMSETUP을 다운받아보자. 다운로드를 클릭하고 저장을 누른다.

APMSETUP을 실행시켜보자. 그럼 아래 그림 그림 같이 나온다.

 

 

언어를 선택하고 오케이를 누르면 아래와 같은 화면이 나온다.

 

 

다음 버튼을 계속누른다. 알아서 세팅이 된다. 그럼 마지막에 아래와 같이 나온다.

 

 

마침을 누른다. 와~! 드디어 설치가 완료되었다. 바탕화면과 작업표시줄을 확인해보자.

 

 

 

 

자 이제 그럼 로컬 서버가 잘 구축되었는지 확인해보자.

 

주소창에 http://127.0.0.1 을 쳐보자. 그럼 아래와 같이 나온다. 이것이 개인 로컬 서버이다.

 

 

위치는 C:/APM_Setup/htdocs 이다.

 

 

즉, 127.0.0.1의 위치는 C:/APM_Setup/htdocs 폴더가 된다.

 

자 이제 준비는 다 끝났다. 그럼 이제 파일 업로드를 한번 만들어보자.

 

위의 그림 같이 C:/APM_Setup/htdocs 폴더 안에 upload파일을 하나 만들자.

 

이 폴더는 업로드한 파일이 올려질 폴더이다.

 

그리고나서 서버랑 연동할 upload.php 파일을 만들자.

 

먼저 upload.php 파일을 작성해 보자.

 

[code as3]
<?php
$errors = array();
$data = "";
$success = "false";

function return_result($success,$errors,$data) {
echo("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
?>

<results>
<success><?=$success;?></success>
<?=$data;?>
<?=echo_errors($errors);?>
</results>

<?
}

function echo_errors($errors) {
for($i=0;$i<count($errors);$i++) {

?>

<error><?=$errors[$i];?></error>

<?
}
}
switch($_REQUEST['action']) {
case "upload":

$file_temp = $_FILES['file']['tmp_name'];
$file_name = $_FILES['file']['name'];
$file_path = $_SERVER['DOCUMENT_ROOT']."/upload";

//checks for duplicate files
if(!file_exists($file_path."/".$file_name)) {
     //complete upload
     $filestatus = move_uploaded_file($file_temp,$file_path."/".$file_name);

     if(!$filestatus) {
     $success = "false";
     array_push($errors,"Upload failed. Please try again.");
     }
}
else {
$success = "false";
array_push($errors,"File already exists on server.");
}
break;

default:
$success = "false";
array_push($errors,"No action was requested.");
}
return_result($success,$errors,$data);
?>
[/code]

 

그럼 이제 FileUploadExample.as 파일을 작성해 보도록하자.

 

[code as3]
package
{
import flash.display.Sprite;
import flash.events.*;
import flash.net.FileFilter;
import flash.net.FileReference;
import flash.net.URLRequest;
import flash.net.URLVariables;
import flash.net.URLRequestMethod;

public class FileUploadExample extends Sprite
{
  private const UPLOAD_HOST:String = "http://127.0.0.1/upload.php";

 public function FileUploadExample()
 {
  super();
  setButton();
 }

 private var uploadURL:URLRequest;

 private var file:FileReference;

 private function setButton():void
 {
  select_btn.label = "Select";
  upload_btn.label = "Upload";

  select_btn.addEventListener(MouseEvent.CLICK, selectButtonClickHandler);
  upload_btn.addEventListener(MouseEvent.CLICK, uploadButtonClickHandler);
 }

 private function configureListener():void
 {
  file.addEventListener(IOErrorEvent.IO_ERROR, fileIOErrorHandler);
  file.addEventListener(ProgressEvent.PROGRESS, fileProgressHandler);
  file.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, fileDataUploadCompleteHandler);
  file.addEventListener(Event.SELECT, fileSelectHandler);
 }

 private function selectButtonClickHandler(event:MouseEvent):void
 {
  if(!file)
  {
   file = new FileReference();
  }
   configureListener();

   file.browse();  
 }

 private function uploadButtonClickHandler(event:MouseEvent):void
 {
   var requestData:URLVariables = new URLVariables();
   requestData.action = "upload";

   var request:URLRequest = new URLRequest(UPLOAD_HOST);
   request.method = URLRequestMethod.POST;
   request.data = requestData;

   file.upload(request, "file");
 }

 private function fileIOErrorHandler(event:IOErrorEvent):void
 {
  trace("File upload IO Error 발생.", "Error");
 }

 private function fileProgressHandler(event:ProgressEvent):void
 {
  var file:FileReference = FileReference(event.target);
  trace("progressHandler name=" + file.name + " bytesLoaded=" + event.bytesLoaded + " bytesTotal=" + event.bytesTotal);
 }

 private function fileDataUploadCompleteHandler(event:DataEvent):void
 {
  var xmlData:XML = new XML(event.data);

  if(xmlData.success == "true")
  {
   trace("File Upload Complete", "Success");
  }
  else
  {
   trace(xmlData.error, "Error");
  }
 }

 private function fileSelectHandler(event:Event):void
 {
  select_btn.enabled = true;
  fname_txt.text = file.name;
  fsize_txt.text = file.size + "bytes";
  ftype_txt.text = file.type;
 }
}
}
[/code]

 

 

 

 

자 이제 실행해보자. 그럼 C:/APM_Setup/htdocs/upload 폴더 안에 업로드한  파일이 올라갔을 것이다. 참고로, 여기서는 실행이되지 않으며, APMSETUP을 설치한 분들만 업로드가 가능하다.  

 

 

FileReference

FileReference 클래스

 

FileReference 클래스는 사용자 컴퓨터와 서버사이에서 파일을 업로드나 다운로드를 할 수 있는 방법을 제고하는 클래스이다. 운영체제 대화상자는 업로드할 파일이나 다운로드할 위치를 선택하라고 표시된다.

 

각각의 FileReference 객체는 사용자 디스크의 단일 파일을 나타내며, 속성으로 파일 사이즈, 타입, 이름, 생성날짜, 수정날짜 등의 정보가 포함되어 있는 속성을 가지고 있다.

 

 

 참조 :

 

https://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/net/FileReference.html

 

그럼 속성과 메서드에 대해 간단하게 살펴보자.

 

# 속성

 

 

위에서 설명했던데로 파일 정보에 관한 속성들이 있다. 이것은 예제를 통해 하나씩 알아보자.

 

 

# Method

 

 

 

메서드에는 파일을 업로드, 다운로드 할 수 있는 메서드들이 있다. 이것도 예제를 통해 알아보자.

 

그런데 업로드, 다운로드 메서드에서 매개변수 URLRequest가 있다. 흠..그럼 이 URLRequest가 뭔지 알아야겠군, 그럼 한번 알아보자.

 

URLRequest 클래스

 

하나의 HTTP 요청에 포함된 모든 정보를 가진다.

 

URLRequest 객체는 Loader, URLStream 및 URLLoader 클래스의 load() 메서드 및 URL 다운로드를 시작하는 기타 로드 작업에 전달된다.

 

 

FileReference 클래스의 upload()download()메서드에도 전달됩니다.

 

즉, 외부에서 파일을 가져오기위한 클래스로 통신을 하기위해 기본적으로 갖추어야할 클래스이다.

 

 

자, 그럼 이제 URLRequest 클래스에 대해서도 알봤으니 예제를 한번 만들어보자.

 

 

 

 

2010년 4월 8일 목요일

6. 스크롤바 _ (2) 간단한 스크롤바 만들기(마우스 클릭)

저번에 만들었던 스크롤바는 마우스로 Drag & Drog으로 bar를 움직이는 스크롤바였다.

 

그렇다면 이번에는 bar를 움직이지 않고 마우스로 line을 클릭하였을 때 bar가 line을 클릭한위치에 오도록 만들어보자.

 

(1) 간단한 스크롤바 만들기 예제 코드와 플래시 파일을 조금 수정하였다.

 

먼저 플래시 파일의 line을 무비클립으로 만들어 주고 인스턴스명을 line_mc로 하였다.

 

수정된 코드는 아래와 같다.

 

[code as3]
package classes.display
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;

public class ScrollBarExample extends Sprite
{
 public function ScrollBarExample()
 {
  super(); // Sprite 객체 생성

  scrollBar_mc.bar_mc.buttonMode = true; // 스크롤바 마우스 오버시 손모양

  // 스크롤바 마우스다운 이벤트 등록
  scrollBar_mc.bar_mc.addEventListener(MouseEvent.MOUSE_DOWN, barMouseDownHandler);

  // 스크롤바 라인 클릭 이벤트 등록
  scrollBar_mc.line_mc.addEventListener(MouseEvent.CLICK, lineClickHandler);
 }

 /**
  *  @private
  *  스크롤바 라인 최소값
  */
 var min:Number = 0;

 /**
  *  @private
  *  스크롤바 라인 최대값
  */
 var max:Number = 300;

 /**
  *  @private
  *  스크롤바 라인 클릭 위치
  */
 var pos:Number;

 /**
  *  @private
  *  스크롤바 라인 클릭
  */
 private function lineClickHandler(event:MouseEvent):void
 {
  // 라인 클릭시 스크롤바 클릭 지점으로 이동
  scrollBar_mc.bar_mc.x = scrollBar_mc.line_mc.mouseX;

  // 라인 클릭 지점 위치 값 표시
  showValue(event);
 }

 /**
  *  @private
  *  스크롤바 마우스 다운
  */
 private function barMouseDownHandler(event:MouseEvent):void
 {
  // 스크롤바 이동 시 값 표시 이벤트 등록
  scrollBar_mc.bar_mc.addEventListener(Event.ENTER_FRAME, showValue);

  var bounds:Rectangle = new Rectangle(0, 0, 300, 0); // 드래그 영역 지정

  // startDrag(lockCenter : Boolean,  bounds : Rectangle)
  // lockCenter : 마우스 클릭 지점을 중심으로 lock 됨
  // bounds : 제한 영역 지정
  scrollBar_mc.bar_mc.startDrag(false, bounds); // 드래그 시작

  //화면 전체 영역에서 마우스 업 되도록 이벤트 등록
  stage.addEventListener(MouseEvent.MOUSE_UP, barMouseUpHandler);
 }

 /**
  *  @private
  *  스크롤바 마우스 업
  */
 private function barMouseUpHandler(event:MouseEvent):void
 {
  // 스크롤바 이동 시 값 표시 이벤트 리스너 제거
  scrollBar_mc.bar_mc.removeEventListener(Event.ENTER_FRAME, showValue);

  scrollBar_mc.bar_mc.stopDrag(); // 드래그 멈춤

  //화면 전체 영역 이벤트 리스너 제거
  stage.removeEventListener(MouseEvent.MOUSE_UP, barMouseUpHandler);
 }

 /**
  *  @private
  *  위치 값 출력
  *
  *  Math.round()  반올림
  *
  *  비례식   (300 - 0) : (bar_mc.x - 0) = (max - min) : (pos - min)
  *          (bar_mc.x - 0) X (max - min) = (300 - 0) X (pos - min)
  *           pos = (bar_mc.x X(max - min)) / 300 + min
  */
 private function showValue(event:Event):void
 {
  // 클릭 지점 위치 계산 : 비례식 사용
  pos = (scrollBar_mc.bar_mc.x * (max - min)) / 300 + min;

  // scrollBar_mc.bar_mc.x 값 Number, scrollBar_mc.txt.text는 Sring이므로
  // String으로 Casting(형변환) 시켜줌
  scrollBar_mc.txt.text = String(Math.round(scrollBar_mc.bar_mc.x));
 }
}
}
[/code]

 

 

회색라인을 클랙해보자. 스크롤바가 클릭 지점 위치로 오는가? 값도 잘 나오는가? 음..

실행이 잘 된다. 그럼 다음시간에는 이를 활용한 예제를 정말로 만들어 보자.

2010년 4월 7일 수요일

6. 스크롤바 _ (1) 간단한 스크롤바 만들기

스크롤바를 이용하여 볼륨, 콘텐츠 등 다양하게 스크롤바를 활용할 수 있다. 그럼 간단하게 스크롤바를 한번 만들어보자.

 

1.  폴더를 하나 만들고 그안에 ScrollBarExample.as와 ScrollBarExample.fla을 만든다.

 

ScrollBarExample.fla 파일의 properties에서 Class를 지정한다.

 

 

 

 

2. 플래시 파일에서  ctrl + F8 을 눌러 무비클립을 하나 만들고, 그 안에 또 하나의 무비클립을 만든다.

 

 

 

 

 

 

이 무비클립은 스크롤바를 이동시킬 무비클립이다. 위의 그림에서 파란색 무비클립이 이에 해당한다.  그리고 라인 하나를 만들고, 이동한 무비클립의 x속성 값을 보여줄 텍스트도 하나 만든다.

 

3. 인스턴스명을 적어준다.

    먼저 처음 만들었던  스크롤바, 라인, 텍스트 3개를 묶어 놓은 무비클립의 인스턴스명을

    scrollBar_mc로 한다.

 

 

 

 

2 에서 만들었던 무비클립안의 스크롤바에 해당하는 파란색 무비클립의 인스턴스명을 bar_mc로 한다.

 

 

 

 

텍스트는 외부에서 컨트롤할 수 있는 Dynamic Text로 지정하고 인스턴스명은 txt로 한다.

 

 

4. ScrollBar.as 파일을 작성한다.

 

[code as3]
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;

public class ScrollBarExample extends Sprite
{
 public function ScrollBarExample()
 {
  super(); // Sprite 객체 생성

  scrollBar_mc.bar_mc.buttonMode = true; // 스크롤바 마우스 오버시 손모양

  // 스크롤바 마우스다운 이벤트 등록
  scrollBar_mc.bar_mc.addEventListener(MouseEvent.MOUSE_DOWN, barMouseDownHandler);
 }

 /**
  *  @private
  *  스크롤바 마우스 다운
  */
 private function barMouseDownHandler(event:MouseEvent):void
 {
  // 스크롤바 이동 시 값 표시 이벤트 등록
  scrollBar_mc.bar_mc.addEventListener(Event.ENTER_FRAME, showValue);  

  var bounds:Rectangle = new Rectangle(0, 0, 300, 0); // 드래그 영역 지정

  // startDrag(lockCenter : Boolean,  bounds : Rectangle)
  // lockCenter : 마우스 클릭 지점을 중심으로 lock 됨
  // bounds : 제한 영역 지정
  scrollBar_mc.bar_mc.startDrag(false, bounds); // 드래그 시작

  //화면 전체 영역에서 마우스 업 되도록 이벤트 등록
  stage.addEventListener(MouseEvent.MOUSE_UP, barMouseUpHandler);
 }

 /**
  *  @private
  *  스크롤바 마우스 업
  */
 private function barMouseUpHandler(event:MouseEvent):void
 {
  // 스크롤바 이동 시 값 표시 이벤트 리스너 제거
  scrollBar_mc.bar_mc.removeEventListener(Event.ENTER_FRAME, showValue);

  scrollBar_mc.bar_mc.stopDrag(); // 드래그 멈춤

  //화면 전체 영역  마우스 업  이벤트 리스너 제거
  stage.removeEventListener(MouseEvent.MOUSE_UP, barMouseUpHandler);  
 }

 /**
  *  @private
  *  텍스트 필드
  */
 private function showValue(event:Event):void
 {
  // scrollBar_mc.bar_mc.x 값 Number, scrollBar_mc.txt.text는 Sring이므로
  // String으로 Casting(형변환) 시켜줌
  scrollBar_mc.txt.text = String(Math.round(scrollBar_mc.bar_mc.x));
 }
}
}
[/code]

 

 

위에서 Drag & Drag에 대한 내용이 나온다. 이해가 잘 되지 않는다면 여기를 참조하자.

또 Rectangle 클래스에 대해서도 나오는 이것도 잘 이해가 가지 않는다면 여기를 참조하자.

실행이 잘 되는가? 그럼 간단한 스크롤바를 만들어보았다. 다음번에 이 스크롤바를 적용한 예제를 만들어보자.

 

parent 대신 callback 함수 사용하기

Actionscript 2.0 에서는 parent를 사용하였다. Actionscript 3.0 에서는 parent를 절대 사용하면 안되다. 무조건!!!! 왜냐하면 parent를 사용하게 되면 종속관계에 있어 강한 결합이 되어 유지보수 등이 어려워진다.

 

parent를 쓰지 않고 부모 클래스에 접근하는  방법은 두가지가 있다.

 

Event

 

 

 

Main 클래스가 있고 Sample 클래스가 있다. 그런데 Sample 클래스에서 Main 클래스에 값을 전달하고 싶은때 Sample 클래스의 메서드에서 dispatcEvent를 발생시켜 Event 를 통해 메인에 값을 전달할 수 있다. 이벤트에 대해서는 다음에 자세히 알아보도록 하자.

 

CallBack 함수

 

 

 

callback 함수를 사용하게 되면 이벤트 객체 만드는 시간이 줄어들고, 또한 다이렉트로 연결할 수 있다.

 

예제를 한번 만들어보자.

 

1. 폴더 하나를 만들고 그 폴더안에 플래시 파일 하나와 CallBack.as파일 하나를 만든다.

2. 그 안에 classes라는 폴더를 하나 더 만든다.

 

 

3. classes 폴더 안에 display라는 폴더를 하나더 만든다.    display 폴더 안에 Seed.as 파일

   을 하나 만든다.

 

 

 

 

 

4. 플래시 파일의 properties에서 Class에 CallBack이라고 적는다.

 

 

자, 이제 모든 준비는 끝났다. 이제 CallBack 함수를 이용하여 만들어보자.

 

먼저, CallBack.as 파일을 작성해보자.

 

 

[code as3]
package
{
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;

import classes.display.Seed;

public class CallBack extends Sprite
{
 public function CallBack()
 {
  super();  // Sprite 객체 생성

  configreListeners(); // stage 설정
 }

 /**
  *  @private
  *  화면 설정
  */
 private function configreListeners():void
 {
  stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); // 화면 전체 영역 이벤트 등록
 }

 /**
  *  @private
  *  마우스 효과
  *
  *  seedTransparent : 내부 메서드
  *  seed.onTransparent : 외부 Seed 클래스 내부의 _onTransprarent 속성에
  *                                 seedTransparent함수 전달.
  *  scaleX, scaleY : 객체의 가로, 세로 크기 (백분율)
  */
 private function mouseMoveHandler(event:MouseEvent):void
 {
  var seed:Seed = new Seed(); // 마우스효과 줄 객체 생성

  seed.onTransparent = seedTransparent; // 함수명만 적어주면됨

  seed.x = mouseX; // 객체의 X좌표 값을 현재 마우스의 X좌표로 위치 설정  
  seed.y = mouseY; // 객체의 y좌표 값을 현재 마우스의 y좌표로 위치 설정

  var ratio:Number = Math.random(); // 임의의 비율값

  seed.scaleX = ratio; // 객체 가로크기 임의의 비율값 적용
  seed.scaleY = ratio; // 객체 세로크기 임의의 비율값 적용

  seed.alpha = Math.random(); // 임의의 알파값 적용

  addChild(seed); // 객체 화면에 표시
 }

 /**
  *  @private
  *  객체 제거
  *
  *  @param  diaplay  Seed 객체
  */
 private function seedTransparent(display:DisplayObject):void
 {
  removeChild(display); // 화면에서 제거
 }
}
}
[/code]

 

그럼 이제 Seed.as 파일을 만들어보자.

 

[code as3]
package classes.display
{
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.ColorTransform;

public class Seed extends Sprite
{
 public function Seed()
 {
  super();  // Sprite 객체 생성

  vx = Math.random() * 10 - 5; // -5 ~ 5 사이값
  vy = Math.random() * 10; //0 ~ 10 사이값 : 아래로 떨어질거라 무조건 상수값

  gravity = 1; // 중력가속도 값 설정

  addEventListener(Event.ENTER_FRAME, alphaEnterFrameHandler);
 }

 /**
  *  @private
  *  속도 : X
  */
 private var vx:Number;

 /**
  *  @private
  *  속도 : Y
  */
 private var vy:Number;

 /**
  *  @private
  *  중력가속도
  *
  *  Number사용 : 소수점나옴 : 좀더 자연스러움을 주기위해
  */
 private var gravity:Number;  

 /**
  *  @private
  *  callBack 함수
  */
 private var _onTransparent:Function;

 /**
  *  @private
  *  seeTransparent() 설정
  *
  *  @param   value  CallBack 클래스의 seedTransparent() 메서드
  */
 public function set onTransparent(value:Function):void
 {
  _onTransparent = value; // seeTransparent()를 _onTransparent로 설정
 }

 /**
  *  @private
  *  seeTransparent() 조정
  */
 public function get onTransparent():Function
 {
  return _onTransparent;
 }

 /**
  *  @private
  *  객체 알파값 설정
  */
 private function alphaEnterFrameHandler(event:Event):void
 {
  vy = vy + gravity; // 중력가속도값(gravity)에 임의의 y속도를 더하여 중력가속도가 됨

  this.x += vx; // X속도 값을 현재 객체의 x좌표값으로 설정
  this.y += vy; // Y속도 값을 현재 객체의 Y좌표값으로 설정

  this.alpha -= 0.05; // 화면에서 점점사라지게 설정

  this.scaleX += 0.05; // 가로크기 증가
  this.scaleY += 0.05; // 세로크기 증가

  var ct:ColorTransform = this.transform.colorTransform; // 객체 색상 변경

  ct.color = Math.random() * 0xFFFFFF; // 임의의 색상 설정

  this.transform.colorTransform = ct; // 설정 색상값 적용

  if(this.alpha < 0) // 객체가 화면에 보이지 않으면
  {
   removeEventListener(Event.ENTER_FRAME, alphaEnterFrameHandler); //알파로 안보일뿐 사라지지(삭제)는 않음

   if(_onTransparent != null) // _onTransparent속성에 함수가 설정되지 않으면
   {
    _onTransparent(this); // CallBack 클래스의 seedTransparent()의 파리미터로 객체를 넘겨준다.
   }
  }
 }
}
}
[/code]

 

 

 

 

2010년 4월 2일 금요일

5. 다양한 객체 만들기 _ Duplicate (3) 충돌감지하여 객체 만들기

객체들간에 충돌을 감지하여 이미 만들어진 객체와 새로 만들어진 객체가 충돌하지 않고 새로운 객체를 계속 생성하는 것이다. 충돌감지에 대한 자세한 내용은 여기를 참고하자.

 

[code as3]
package
{
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.events.Event;
import flash.filters.GlowFilter;

public class Main extends Sprite
{
 public function Main()
 {
  super(); // Sprite 객체 생성

  stage.frameRate = 40; // 프레임 속도 40으로 설정
  stage.addEventListener(Event.ENTER_FRAME, createParticleHandler); // 프레임마다 이벤트 등록
 }

 /**
  *  @private
  *  객체 참조 저장 배열
  */
 private var holder:Array = new Array();

 /**
  *  @private
  *  box 객체  
  */
 private var box:Sprite;

 /**
  *  @private
  *  객체 배치
  *
  *  scaleX : scaleY  객체의 가로, 세로 크기 (백분율) 1.0 = 100%
  */
 private function createParticleHandler(event:Event):void
 {
  box = new Box(); // 객체 생성

  box.x = Math.random() * stage.stageWidth;  // stage 범위 안에 표시할 수 있도록 x좌표 계산
  box.y = Math.random() * stage.stageHeight; // stage 범위 안에 표시할 수 있도록 y좌표 계산

  box.scaleX = box.scaleY = Math.random() * 1; // 객체를 임의의 크기로 계산

  holder.push(box); // box 객체 배열에 추가

  if(isOk(box)) // isOk() 함수 호출
  {
   addChild(box); // box 화면 표시

   var glow:GlowFilter = new GlowFilter(); // GlowFilter 적용

   glow.color = Math.random() * 0xFFFFFF; // 임의의 색상 적용

   box.filters = [glow];
  }
  else
  {
   holder.pop(); // 배열에서 객체 삭제
  }
 }

 /**
  *  @private
  *  충돌 감지
  *
  *  @param   mc  box객체
  */
 private function isOk(mc:Sprite):Boolean
 {
  for(var i=0; i<holder.length-1; i++) // holder 배열 있는 수 만큼
  {
   var flag:Boolean = holder[i].hitTestObject(mc); // 배열에 저장된 객체와 현재 객체 충돌 비교

   if(flag) // 충돌되면
   {
    return false; // false 반환

    break;
   }
  }
  return true; // 충돌되지 않으면 마지막에 true 반환
 }
}
}
[/code]

 

 

 

위의 코드에서 나오는 여러가지 클래스의 속성, 메서드에 대해서 간단하게 알아보자.

 

Stage 클래스

 

Stage는 Flash 화면에 보이는 전체 영역을 말한다. 그럼 Stage 클래스의 framRate의 속성에 대해알아보자.

 

 

 

stage의 프레임 속도를 설정하나다. 프레임 속도는 fps(frame per second)로 정의된다.
기본적으로 첫번째 SWF 파일의 프레임 속도가 기본 프레임 속도로 설정된다. 프레임 속도의 유효범위는 0.01 ~ 1000 이다.

 

Array 클래스

 

배열에 접근하거나 조정할 수 있다. 인덴스는 0 부터이다. 첫번째 요소는 [0] 이다.

 

 

push()

 

배열 끝에 하나 또는 그 이상의 요소를 추가하고 , 추가한 새로운 배열의 길이를 반환한다.

 

 

 

pop()

 

배열의 마지막 요소를 제거하고, 배열의 요소의 값을 반환한다.

 

 

GlowFilter 클래스

 

 

객체에 광선 효과를 적용할 수 있는 클래스이다.

 

 

 

DisplayObject  클래스

 

 

DisplayObject 클래스의 hitTestObject() 메서드에 대해 알아보자.

 

 

객체와 객체간의 외각 영역이 겹치거나 교차하는지 확인한다.