1
2
3
4
5
6
7
8
9
10
11
12
13
14
var file:File = new File();
file.addEventListener(Event.SELECT, onSelected);
file.browseForSave("save");
 
function onSelected(evt:Event):void
{
    if (evt.target.extension != "bin")
        evt.target.nativePath += ".bin";
     
    var stream:FileStream = new FileStream();
    stream.open(evt.target as File, FileMode.WRITE);
    stream.writeUTF("Content");
    stream.close();
}


File 객체에서 browseForSave로 저장창을 열고

Event.SELECT이벤트가 발생했을 때 

파일의 확장자를 확인하여 원하는 확장자로 덧붙인다.


FileStream을 써야 하기 때문에 Adobe AIR로 해야한다.






*********************************************************




var urlLdr:URLLoader = new URLLoader();

try {

urlLdr.load(new URLRequest("http://tibyte.kr/tibyte.txt"));

} catch (e:IOError) {  //cannot catch

}


다음과 같이 존재하지 않는 파일을 로드하면 런타임 에러가 뜬다.

예외처리를 했는데도 catch가 되지 않는데, 에러가 비동기적으로 발생하기 때문.

그래서 이벤트를 통해 예외처리를 해야한다. 


var urlLdr:URLLoader = new URLLoader();

urlLdr.addEventListener(IOErrorEvent.IO_ERROR, function h(e:IOErrorEvent){});

urlLdr.load(new URLRequest("http://tibyte.kr/tibyte.png"));


 ※Loader클래스일때는 contentLoaderInfo속성에 IOErrorEvent를 걸어주면 된다. 











Flash Professional에서 프레임에 직접 입력하였다.

스테이지에 btn0부터 btn15까지 16개의 버튼이 미리 배치되어 있다.


키보드 방향키로 상하좌우 이동을 하며 엔터 키로 버튼을 누를 수 있다.

코드는 아래에...


 





윈도우 바탕화면에서 아이콘을 키보드로 포커싱하는 것과 비슷하게 동작하도록 했다.
화면에 배치되어 있는 무비클립 객체들의 위치관계를 파악하여 각 방향으로
유출이 가능한지 여부에 대한 유향그래프를 생성한다.
그렇기 때문에 스테이지에서나 스크립트로 버튼의 배치를 바꿔도 
버튼들의 위치관계를 계산하여 문제없이 키보드 초점이동을 할 수 있다. 


코드 :

Hello SyntaxHighlighter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import flash.events.KeyboardEvent;
import flash.display.DisplayObject;
import flash.filters.DisplacementMapFilter;
 
const MAX_BTN:int = 16;
const RIGHT:int = 0;
const LEFT:int = 1;
const UP:int = 2;
const DOWN:int = 3;
 
var pressedKey:Array = new Array();
var lastKey:int;
var moveGraph:Array = new Array(MAX_BTN);
var focus:int = 0;
var time:int=0;
 
 
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown_h);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUp_h);
 
setFocus(0);
updateMoveGraph();
 
 
function keyDown_h(evt:KeyboardEvent):void
{
    if(getTimer()-time<50 && lastKey==evt.keyCode) return;
    time = getTimer();
    lastKey = evt.keyCode;
    //if(pressedKey[evt.keyCode] == true) return;
        switch(evt.keyCode) {
            case Keyboard.RIGHT:
            case Keyboard.LEFT:
            case Keyboard.UP:
            case Keyboard.DOWN:
                moveFocus(evt.keyCode);
                break;
            case Keyboard.ENTER:
                selectBtn();
                 
        }
    pressedKey[evt.keyCode] = true;
}
 
function keyUp_h(evt:KeyboardEvent):void
{
    pressedKey[evt.keyCode] = false;
    if(evt.keyCode == Keyboard.ENTER) this["btn"+focus].gotoAndStop("over");
}
 
 
function moveFocus(key:uint):void
{
    if(key == Keyboard.RIGHT) {
        setFocus(moveGraph[focus][RIGHT]);
    }
    else if(key == Keyboard.LEFT) {
        setFocus(moveGraph[focus][LEFT]);
    }
    else if(key == Keyboard.UP) {
        setFocus(moveGraph[focus][UP]);
    }
    else if(key == Keyboard.DOWN) {
        setFocus(moveGraph[focus][DOWN]);
    }
     
}
 
 
function updateMoveGraph():void
{
    var i:int, j:int;
    var dx:Number, dy:Number;
     
    for(i=0; i<MAX_BTN; i++) {
        moveGraph[i] = new Array(4);
        moveGraph[i][RIGHT] = -1;
        moveGraph[i][LEFT] = -1;
        moveGraph[i][UP] = -1;
        moveGraph[i][DOWN] = -1;
    }
    for(i=0; i<MAX_BTN; i++) {
        for(j=0; j<MAX_BTN; j++) {
            if(i==j) continue;
             
            dx = this["btn"+i].x - this["btn"+j].x
            dy = this["btn"+i].y - this["btn"+j].y
             
            if(dx<0 && dx*dx>dy*dy) {
                if(moveGraph[i][RIGHT] == -1)  moveGraph[i][RIGHT] = j;
                else if(getNear(this["btn"+i],this["btn"+j],this["btn"+moveGraph[i][RIGHT]]) == 1) {
                    moveGraph[i][RIGHT] = j;
                }
            }
             
            else if(dx>0 && dx*dx>dy*dy) {
                if(moveGraph[i][LEFT] == -1)  moveGraph[i][LEFT] = j;
                else if(getNear(this["btn"+i],this["btn"+j],this["btn"+moveGraph[i][LEFT]]) == 1) {
                    moveGraph[i][LEFT] = j;
                }
            }
             
            else if(dy>0 && dx*dx<dy*dy) {
                if(moveGraph[i][UP] == -1)  moveGraph[i][UP] = j;
                else if(getNear(this["btn"+i],this["btn"+j],this["btn"+moveGraph[i][UP]]) == 1) {
                    moveGraph[i][UP] = j;
                }
            }
             
            else if(dy<0 && dx*dx<dy*dy) {
                if(moveGraph[i][DOWN] == -1)  moveGraph[i][DOWN] = j;
                else if(getNear(this["btn"+i],this["btn"+j],this["btn"+moveGraph[i][DOWN]]) == 1) {
                    moveGraph[i][DOWN] = j;
                }
            }
             
        }
    }
}
 
 
function getNear(src:DisplayObject, dest1:DisplayObject, dest2:DisplayObject):int
{
    var distance1:Number;
    var distance2:Number;
    distance1 = (src.x-dest1.x)*(src.x-dest1.x)+(src.y-dest1.y)*(src.y-dest1.y);
    distance2 = (src.x-dest2.x)*(src.x-dest2.x)+(src.y-dest2.y)*(src.y-dest2.y);
    if(distance1<distance2) return 1;
    else if (distance1>distance2) return -1;
    return 0;
}
 
 
function setFocus(num:int):void
{
    if(num==-1) return;
    this["btn"+focus].gotoAndStop("up");
    focus = num;
    this["btn"+focus].gotoAndStop("over");
}
 
function selectBtn():void
{
    if(pressedKey[Keyboard.ENTER] != true) {
        this["btn"+focus].gotoAndStop("down");
    }
     
    if(focus==0) {
        //...
    }
    if(focus==1) {
        //...
    }
    if(focus==2) {
        //...
    }
    if(focus==3) {
        //...
    }
     
    //...
    //...
    //...
}


===================================================








 코딩을 하면서 각종 상황에 대한 테스트가 필요했기 때문에

Valve社의 게임에서 볼 수 있는 것과 비슷한 콘솔 창을 구현하기로 했다.  


 콘솔 창은 싱글턴 패턴으로 프로그래밍했는데

액션스크립트는 생성자 함수의 접근제한자로 private를 둘 수 없기 때문에

해당 클래스 파일의 패키지 외부에 클래스 하나를 더 두고

싱글턴 클래스 생성자의 매개변수로 그 클래스 타입을 넣어주어야 한다.

아래와 같은 모양이다.


package {

public class Singleton {

private static var instance...

public function Singleton(block:SingletonBlocker)

{

if (block == null) throw new Error...

}

public static function getInstance()...

}

}

class SingletonBlocker{}



 프로젝트의 클래스에서 콘솔 창에 뭔가를 표시하는 함수를 호출하면 

콘솔창이 없을 경우 새로 창을 띄우고 있으면 그 창에 내용을 출력한다.


 콘솔 창은 NativeWindow클래스를 사용하여 새 윈도우를 띄우게 되는데,

이 윈도의 크기가 원하는 대로 되지 않았다. 액션스크립트 도움말을 보면 

NativeWindow객체의 stage.stageWidth 나 Height속성을 조절하면 창 크기가 

그에 맞게 바뀐다고 하는데 전혀 그렇지가 않는 것이었다..


 해결책은 역시 도움말에 나와있었는데  

_mainWindow.stage.scaleMode = StageScaleMode.NO_SCALE;

_mainWindow.stage.align = StageAlign.TOP_LEFT;

이 두 구문이 있어야 제대로 창크기 조절이 된다.



코드를 컴파일후 실행시키니 제대로 출력이 나왔다.






 다음은 게임에서 사용할 월드 데이터 파일을 제작하는 간단한 툴을 만드는 것이었다.

FileStream클래스와 File클래스로 파일쓰기를 한다.


File객체를 만들 때, 파일쓰기 하려는 위치가 어플리케이션이 있는 폴더라면

var file:File = File.applicationDirectory;

와 같이 초기화해야 한다고 해서 그렇게 해 보니 보안문제로 오류가 났다.-_-;


이 경우에는 

var file:File = new File(File.applicationDirectory.nativePath);

file = file.resolvePath("하위폴더"+File.separator+파일이름+".확장자");

요렇게 하니까 되더라..


 그 다음 이렇게 해서 생성된 월드 데이터파일에 어플리케이션을 연결해 보기로 했다.

이 작업은 그리 어렵지 않게 할 수 있다.

if(NativeApplication.nativeApplication.isSetAsDefaultApplication("확장자")==false)

NativeApplication.nativeApplication.setAsDefaultApplication("확장자");

연결이 되어 있지 않으면 '이 어플리케이션'을 해당 file의 연결 프로그램으로 설정한다.

단, 응용 프로그램 설명자(xml파일)의 fileTypes노드에 파일의 정보가 선언되어 있어야 한다.


 빌드를 하니 128x128 아이콘 파일의 크기가 맞지 않는다는 오류가 계속 뜨는데

src폴더 내의 파일을 수정해도 빌드만 하면 다시 129x129크기의 파일로 바뀌어 버렸다.

bin-debug폴더에 들어있는 파일을 지우니 제대로 빌드가 되었다.



(▲ 데이터파일의 아이콘이 바뀐 모습. 실행하면 맵에디터가 열리고 해당 파일을 불러들인다.) 



하나 빼먹은 게 있어 추가로 적는데,

프로그램 연결은 연결프로그램으로 쓸 어플리케이션이 컴퓨터에 설치되어 있는 상태여야 한다. (디버그모드에서는 확인할 수 없다.)








 


플래시에서 무비 테스트(Test Movie , Ctrl+Enter)를 실행할 때.
키보드 입력을 처리하도록 되어 있는 무비의 경우, 키보드를 누르면
플래시의 각종 단축키가 동작하는 경우가 있습니다. (h키, m키 , t키, F1~F9키 등등)
이것이 동작하지 않게 하고 싶으면 아래 그림과 같이 Disable Keyboard Shotcuts에 체크해 주면 됩니다.

 

 이 게시글의 일부 혹은 전체 내용에 대하여
저작자의 허락 없는 사용을 금지합니다.


 

액션스크립트를 Flash에서 직접작성할 때
Stage.를 입력하면 코드힌트가 나옵니다.
하지만 Stage 클래스는 DisplayObject인스턴스의 stage 속성을 통해 접근해야하기 때문에
소문자인 stage로 입력해야하는데 이렇게하면 코드힌트가 나오지 않습니다.





(윈도) 컴퓨터의 C:\Documents and Settings 경로에서 현재 유저가 쓰고 있는 이름의 폴더를 들어가서
Local Settings\Application Data\Adobe\Flash CS3 의 경로로 다시 들어갑니다.
언어에 맞는 폴더를 선택하고 \Configuration\ActionsPanel\ActionScript_3 의 경로로 추가로 들어가면

ActionsPanel_3.xml 이라는 xml파일이 있습니다.

xml 파일의 밑부분에 있는 codehints노드를 살펴보면,

  <typeinfo pattern="*_array" object="Array" />
  <typeinfo pattern="*_str" object="String" />
  <typeinfo pattern="*_btn" object="flash.display.SimpleButton" />
  <typeinfo pattern="*_txt" object="flash.text.TextField" />
  <typeinfo pattern="*_fmt" object="flash.text.TextFormat" />
.
.
.

위와 같이 접미어로 코드힌드를 나오게 하는 부분이 있는데 그 밑부분에
 <typeinfo pattern="stage" object="flash.display.Stage" />
이라고 추가하면,



아래 그림과 같이 코드힌트가 뜨게됩니다.









다른 툴로 스크립팅 하시는분이면 필요없겠네요.





false

+ Recent posts