작동방법

- 마우스를 휘저어 보세요

- 화면을 클릭하고 마우스를 휘저어 보세요

- 오른쪽 아래 구석에 있는 podo로고를 클릭해 보세요

  한 번 누를 때 마다 노란 불빛이 켜졌다가 꺼졌다가를 반복하며

  불이 켜져 있을 때는 화면에 잔상이 남아서 색다른 모양을 볼 수 있습니다.

  

(1차 수정 : podo로고가 두번씩 눌려서 켜졌다가 다시 꺼지는 버그 수정)



(▼ 이곳에 플래시가 삽입되어 있습니다. 일부 환경에서는 보이지 않을 수 있습니다.) 




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
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.geom.Point;
import flash.utils.ByteArray;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
import flash.filters.GlowFilter;
 
 
const MAX_UNIT:int = 4096;
 
 
var bmpDatF:BitmapData = new BitmapData(1,1,false,0x0000ff);
var bmpDatB:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight,false,0x000000);
var canvas:Bitmap = new Bitmap(new BitmapData(stage.stageWidth, stage.stageHeight,false,0xffffff));
var velVec:Vector.<Point> = new Vector.<Point>(MAX_UNIT);
var posVec:Vector.<Point> = new Vector.<Point>(MAX_UNIT);
var colorVec:Vector.<uint> = new Vector.<uint>(MAX_UNIT);
var blueTransform:ColorTransform = new ColorTransform(0.86,0.86,0.86);
 
 
var datumPoint:Point = new Point(0,0);
var theta:Number = 0;
 
velVec.fixed = true;
posVec.fixed = true;
colorVec.fixed = true;
 
for(var i:int=0; i<MAX_UNIT; i++) {
    velVec[i] = new Point(0,0);
    posVec[i] = new Point(0,0);
    colorVec[i] = getColorByHue(i/MAX_UNIT*i/MAX_UNIT*i/MAX_UNIT*i/MAX_UNIT*360);
}
addChild(canvas);
 
 
 
 
var timer:Timer = new Timer(1000/60);
timer.addEventListener(TimerEvent.TIMER, timerHandler);
timer.start();
 
function timerHandler(evt:TimerEvent):void
{
    canvas.bitmapData.lock();
     
    if(podoed)
        canvas.bitmapData.colorTransform(canvas.bitmapData.rect, blueTransform);
    else
        canvas.bitmapData.copyPixels(bmpDatB,bmpDatB.rect,datumPoint);
         
    var dx:Number;
    var dy:Number;
    var direction:Number;
    var color:uint;
    for(var i:int=MAX_UNIT-1; i>=0; i--) {
        dx = stage.mouseX-posVec[i].x;
        dy = stage.mouseY-posVec[i].y;
        direction = Math.atan2(dy,dx);
         
        velVec[i].x += (i/MAX_UNIT*3.6+0.5)*Math.cos(direction);
        velVec[i].y += (i/MAX_UNIT*3.6+0.5)*Math.sin(direction);
         
        posVec[i].x += velVec[i].x;
        posVec[i].y += velVec[i].y;
         
        velVec[i].x *= i/MAX_UNIT*0.14+0.85;
        velVec[i].y *= i/MAX_UNIT*0.14+0.85;
         
        if(Math.abs(dx)<1&&Math.abs(dy)<1) {
            posVec[i].x = stage.mouseX;
            posVec[i].y = stage.mouseY;
            velVec[i].x = 0;
            velVec[i].y = 0;
        }
        canvas.bitmapData.setPixel(posVec[i].x,posVec[i].y,colorVec[i]);
    }
    canvas.bitmapData.unlock();
}
 
 
stage.addEventListener(MouseEvent.MOUSE_DOWN, clickHandler);
function clickHandler(evt:MouseEvent):void
{
    if(evt.stageX>podo.x && evt.stageX<podo.x+podo.width
       && evt.stageY>podo.y && evt.stageY<podo.y+podo.height) {
        podoClicked(null);
        return;
    }
    for(var i:int=0; i<MAX_UNIT; i++) {
        velVec[i].x = 0;
        velVec[i].y = 0;
        posVec[i].x = evt.stageX;
        posVec[i].y = evt.stageY;
        //velVec[i].y = Math.random()*-20;
         
    }
}
 
function getColorByHue(angle:Number):uint
{
var hue:Number = (angle+0) % 360;
    var variation:uint = uint((hue % 60)/60*0xff);
    var red:uint, blue:uint, green:uint;
    if (hue<60) {
        red = 0xff;
        blue = 0;
        green = variation;
    }
    else if (hue < 120) {
        red = 0xff - variation
        blue = 0;
        green = 0xff;
    }
    else if (hue < 180) {
        red = 0
        blue = variation;
        green = 0xff;
    }
    else if (hue < 240) {
        red = 0x0;
        blue = 0xff;
        green = 0xff-variation;
    }
    else if (hue < 300) {
        red = variation;
        blue = 0xff;
        green = 0x0;
    }
    else if (hue < 360) {
        red = 0xff;
        blue = 0xff-variation;
        green = 0;
    }
     
    return red<<16|green<<8|blue;
}
 
 
var podo:Sprite = new Podo();
podo.width*=0.40;
podo.height*=0.40;
podo.x = stage.stageWidth-podo.width;
podo.y = stage.stageHeight-podo.height;
stage.addChild(podo);
 
var podoed:Boolean = false;
var podoFilter:GlowFilter = new GlowFilter(0xffff00,1,4,4,4,3);
function podoClicked(evt:MouseEvent):void
{
    if(!podoed) {
        podo.filters = [podoFilter];
        podoed = true;
    }else{
        podo.filters = [];
        podoed = false;
    }
}
===========================================================================







자석과 나침반을 단순하게 구현한 것.

체크박스에 체크를 하면 자석이 나타난다.

막대자석 모양이 나타나지만 완벽하게 구현되어 있지는 않다..



▽이곳에 플래시가 삽입되어 있습니다.





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






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) {
        //...
    }
     
    //...
    //...
    //...
}


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





연습. (Flash swf포함)

유전적 알고리즘 연습


플래시가 첨부되어 있는 글입니다.




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








저해상도 RGB모니터효과 플래시.


- 순서

1. 플래시

2. 미리보기

3. 소스코드




1. 플래시






2. 미리보기













3. 소스코드


package  {
	import flash.display.BitmapData;
	import flash.display.Bitmap;
	import flash.display.MovieClip;
	import flash.net.FileReference;
	import flash.net.FileFilter;
	import flash.events.Event;
	import flash.utils.ByteArray;
	import flash.display.Loader;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.display.DisplayObjectContainer;	
	
	public class TVeffect extends MovieClip{
		
		public function TVeffect() {
			
			var file:FileReference = new FileReference();
			file.addEventListener(Event.SELECT,onSelected);
			var loadedBytes:ByteArray;
			var image:Loader = new Loader();
			var container:MovieClip = new MovieClip();
			
			var tf1:TextField = new TextField();
			tf1.autoSize = TextFieldAutoSize.LEFT;
			tf1.x = tf1.y = 200;
			tf1.text = "화면을 눌러서 그림파일을 선택하세요.";
			addChild(tf1);
			var tf2:TextField = new TextField();
			tf2.autoSize = TextFieldAutoSize.LEFT;
			tf2.x = tf2.y = 450;
			tf2.text = "http://tibyte.kr";
			addChild(tf2);
			addChild(container);
			
			stage.addEventListener(MouseEvent.CLICK, onClick);
			function onClick(evt:MouseEvent):void
			{
				file.browse([new FileFilter("image file (JPG, JPEG, GIF, PNG)","*.jpg;*.jpeg;*.gif;*.png")]);
			}
			function onSelected(evt:Event):void
			{
				evt.target.load();
				evt.target.addEventListener(Event.COMPLETE, onCompleted);
			
			}
			
			function onCompleted(evt:Event):void
			{
				loadedBytes = evt.target.data;
				image.contentLoaderInfo.addEventListener(Event.INIT,onInited);
				image.loadBytes(loadedBytes);
			}
			
			
			function onInited(evt:Event):void
			{
				removeChildAll(container);
				var bmp:Bitmap = evt.target.content as Bitmap;
				container.addChild(bmp);
				for(var i_x:int = 0; i_x<bmp.bitmapData.width; i_x++){
					for(var i_y:int = 0; i_y<bmp.bitmapData.height; i_y++) {
						bmp.bitmapData.setPixel(i_x,i_y,bmp.bitmapData.getPixel(i_x,i_y)&0x0000ff<<(i_x%3)*8);
					}
				}
			}
			
			function removeChildAll(container:DisplayObjectContainer):void
			{
				for(var i:int=0; i<container.numChildren; i++) {
					container.removeChildAt(i);
				}
			}
				
		}
	
	}
	
}

 









정상파 발생 플래시입니다. 소리를 들어보세요.

(화면에 표시되는 내용은 스피커에 전달될 샘플링 데이터를 나타낸 것으로 정상파와는 맞지 않습니다.)







소스코드

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
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.text.TextField;
import flash.events.MouseEvent;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.text.TextFieldAutoSize;
import flash.media.Sound;
import flash.events.SampleDataEvent;
 
var mySound:Sound = new Sound();
 
var t:Number = 0;
var amplitude:Number = 0.25;
var graph_amplitude:Number = 50/amplitude;
var bmpDat:BitmapData = new BitmapData(400,200,false,0x0);
var bmp:Bitmap = new Bitmap(bmpDat);
bmp.y=50;
addChild(bmp);
 
 
var tfield:TextField = new TextField();
tfield.text = "화면을 누르면 시작.";
tfield.x = 120;
tfield.y = 100;
tfield.autoSize = TextFieldAutoSize.LEFT;
tfield.selectable = false;
var tformat:TextFormat = tfield.getTextFormat();
tformat.color = 0x33cc33;
tformat.align = TextFormatAlign.CENTER;
tfield.setTextFormat(tformat);
addChild(tfield);
stage.addEventListener(MouseEvent.CLICK, mouse_h);
 
 
function sineWaveGenerator(event:SampleDataEvent):void {
    t+=2;
    bmpDat.fillRect(new Rectangle(0,0,400,200),0x0);
    var wave:Number;
    for ( var c:int=0; c<2048; c++ ) {
        wave = getWave(c+event.position,t);
        event.data.writeFloat(wave);
        event.data.writeFloat(wave);
        if(c<800){
            bmpDat.setPixel(c,wave*graph_amplitude+100,0x00ff00);
        }
    }
    bmp.bitmapData = bmpDat;
 
}
 
 
function getWave(p:Number,t:Number):Number
{
    return (Math.sin(0.420*(Number(p+t)/Math.PI/2))+Math.sin(0.420*(Number(p)/Math.PI/2)))*amplitude;
}
 
function mouse_h(evt:MouseEvent):void
{
    mySound.addEventListener(SampleDataEvent.SAMPLE_DATA,sineWaveGenerator);
    mySound.play();
    removeChild(tfield);
}









 1. 플래시


자세한 설명은 아래에 있습니다.







2. 데이터&설명


지구에서 관측되는 화성의 움직임을 플래시로 나타내 본 것입니다.

아래와 같은 조건들을 설정했습니다.


- 공전궤도 모양

원(평면)으로 가정


- 공전궤도 반지름

지구 : 1
화성 : 1.5


-공전속도

지구 : 1.88

화성 : 1


- 궤도경사와 승교점경도

지구 : 7.3˚ 349˚
화성 : 5.7˚ 50˚


- 천구의 중심

태양 (중심을 지구로 잡으면 투영면이 움직여서 알아보기가 불편하고,

태양으로 잡아도 화성의 역행 움직임이 나타나는 모양을 설명하기에는

큰 차이가 없기 때문에 편의상 태양을 기준으로 함.) 


- 관찰자의 고도

황도를 기준으로 pi/13 라디안



지구와 화성의 공전궤도면이 일치하지 않기 때문에

화성이 충 부근에서 역행을 할 때 α모양이나 s모양이 나타나게 됩니다.


예전에 만들었던 것(http://www.tibyte.kr/126)은 두 행성의 공전궤도를 평면상에 둬서 

이런 현상을 확인할 수 없었는데 이번에 입체로 구현해보았습니다.



3. 코드 구현


(1)

Vector3D객체에 각 천체들의 위치벡터를 저장한 후

눈으로 직접 보기 위해 Sprite객체를 움직일 때는 아래와 같은 코드를 사용함.


earth.x = earthPoint.x + sunPoint.x;

earth.y = Math.sin(viewAng)*(earthPoint.y)+sunPoint.y +

 Math.cos(viewAng)*(earthPoint.z)+sunPoint.z;


viewAng는 시점의 고도이며, 이 값에 따라 위치벡터의 y,z값이 Sprite의 y값에 적용됩니다.

모니터는 2D니까 3차원 좌표를 2차원 좌표로 변환해야 하기 때문임.



(2)

공전궤도를 기울이는 함수 inclineObt()


function inclineObt(vec3D:Vector3D,xy:Number=0, zx:Number=0):Vector3D

{

var transVec3D:Vector3D = new Vector3D();

var matrix:Matrix = new Matrix(0,0,0,0);

matrix.a = vec3D.x;

matrix.b = vec3D.z;

matrix.rotate(zx);  //

transVec3D.x = matrix.a;

transVec3D.z = matrix.b;

matrix.a = transVec3D.x;

matrix.b = vec3D.y;

matrix.rotate(xy);

transVec3D.x = matrix.a;

transVec3D.y = matrix.b;

transVec3D.w = vec3D.w;

return transVec3D;

}


궤도경사와 승교점고도 수치에 맞게 공전궤도를 기울인다.

Matrix클래스의 rotate메서드는 이차원 회전행렬 

( cos -sin)
( sin  cos) 를 대상 행렬 앞에 곱함.




(3)

천구면에 투영된 화성의 위치를 구하는 함수


function calcProjPoint(vec1:Vector3D, vec2:Vector3D):Vector3D

{

var direcVec3D:Vector3D = vec2.clone();

direcVec3D.decrementBy(vec1);

var a:Number = direcVec3D.x;

var b:Number = direcVec3D.y;

var c:Number = direcVec3D.z;

var d:Number = vec1.x;

var e:Number = vec1.y;

var f:Number = vec1.z;

/* 이차방정식의 근의 공식으로 투영된 외행성의 위치를 구한다*/

var product:Number = calcQuadratic(a*a+b*b+c*c, 2*(a*d+b*e+c*f), d*d+e*e+f*f-sphereRad*sphereRad);

direcVec3D.scaleBy(product);

return direcVec3D.add(vec1);


}


천구면은 편의상 중심점을 태양의 중심으로 맞춤.

sphereRad 는 천구의 반지름값이므로 투영된 화성의 상은 태양으로부터 항상 sphereRad위치에 있게 됨.

천구면에 투영된 화성의 위치벡터는 (지구의위치벡터 + p*지구에서화성을바라보는벡터) 이므로 p값을 먼저 구해야 함.


즉, 지구벡터+p*(화성-지구벡터)의 거리는 sphereRad와 같으므로

거리 = 거리 방정식을 세워보면 위 코드와 같은 방법으로 p(product)값을 구할 수 있다. (calcQuadratic은 근의 공식으로 이차방정식의 (큰)해를 구하는 함수) 



(4) 

3D천구 뼈대를 그리는 부분


var polygons:Vector.<Vector.<Vector3D>> = new Vector.<Vector.<Vector3D>>(19);

var model2D:Vector.<Vector.<Point>> = new Vector.<Vector.<Point>>(19);

for(var i_lati:int = 0; i_lati<19; i_lati++) {

polygons[i_lati] = new Vector.<Vector3D>(36);

model2D[i_lati] = new Vector.<Point>(36);

for(var j_longi:int = 0; j_longi<36; j_longi++) {

polygons[i_lati][j_longi] = new Vector3D();

model2D[i_lati][j_longi] = new Point();

//초기위치 

polygons[i_lati][j_longi].z = radius*Math.sin(getLatitude(i_lati));

polygons[i_lati][j_longi].x = radius*Math.cos(getLatitude(i_lati))*Math.cos(getLongitude(j_longi));

polygons[i_lati][j_longi].y = radius*Math.cos(getLatitude(i_lati))*Math.sin(getLongitude(j_longi));

//시점에따른 변환

model2D[i_lati][j_longi].x = polygons[i_lati][j_longi].x + central.x;

model2D[i_lati][j_longi].y = Math.sin(viewAng)*(polygons[i_lati][j_longi].y)+central.y +

Math.cos(viewAng)*(polygons[i_lati][j_longi].z)+central.z;

}

}

function getLatitude(index:int):Number{return (index*10-90)/180*Math.PI;}

function getLongitude(index:int):Number{return (index*10)/180*Math.PI;} 



Vector에  Vector3D객체와 Point객체를를 2차원으로 할당하고

Vector3D에는 위도를 10도단위로 한층씩 훑어가면서 경선을 이루게 될 36개의 점의 xyz 3차원 좌표를 저장.

Point에는 2차원인 모니터에 표시하기 위해 위에서 구한 xyz좌표를 xy좌표로 변환 .











재미로하는 10년간의 행운그래프 입니다.

운이 별로 좋지 않게 나오면 노력으로 메꾸세요.


사용방법 : 태어난 년도와 이름을 적고 확인버튼을 누르세요.

마우스 오른쪽 버튼으로 언어전환을 할 수 있습니다. (fp11.2)









코드
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
package
{
    import adobe.utils.CustomActions;
    import flash.display.BitmapData;
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Point;
    
    /**
     * ...
     * @author tibyte.kr
     */
    public class Main extends Sprite
    {
        private var form1:Form1;
        private var drawingContainer:Sprite = new Sprite();
        
        public function Main():void
        {
            if (stage)
                init();
            else
                addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            stage.addEventListener(MouseEvent.RIGHT_CLICK, rightClick_h);
            form1 = new Form1();
            form1.name_input.text = "";
            form1.interfaceText.mouseEnabled = false;
            
            addChild(form1);
            addChild(drawingContainer);
            
            form1.ok_btn.addEventListener(MouseEvent.CLICK, btnClick_h);
        }
        
        private function rightClick_h(evt:MouseEvent):void
        {
            form1.title.gotoAndStop(form1.title.currentFrame % 2 + 1);
            form1.interfaceText.gotoAndStop(form1.interfaceText.currentFrame % 2 + 1);
        }
        
        private function calcData(year:intname:String):Array
        {
            var dataArray:Array = new Array(11);
            var md5:String = MD5.getMD5(name + year);
            var seed:int =parseInt("0x"+md5.slice(2, 6));
            var bmp:BitmapData = new BitmapData(220, 1);
            var luck:int;
            var offsets:Array = new Array(6);
            for (var j:int = 0; j < 6; j++)
            {
                offsets[j] = new Point(20*(new Date().getUTCFullYear()%30), 0);
            }
            
            /* 행운값 추출 */
            bmp.perlinNoise(120, 1, 6, seed,falsetrue, 7, true, offsets);
            for (var i:int = 0; i < 11; i+=1)
            {
                luck = Math.floor((Math.max(10, Math.min(80, (bmp.getPixel(i*20, 0) >> 16) / 255 * 100)) - 10) * (5 / 4));
                dataArray[i] = luck;
            }
            return dataArray.concat();
        }
        
        private function drawData(data:Array, dest:Sprite, form:Form1):void
        {
            dest.graphics.clear();
            
            /* 보조선 */
            dest.graphics.lineStyle(0.1, 0x666666);
            for (var i:int = 0; i < 11; i++)
            {
                dest.graphics.moveTo(calcX(i, form), calcY(100, form));
                dest.graphics.lineTo(calcX(i, form), calcY(0, form));
            }
            
            /* 그래프 */
            dest.graphics.lineStyle(2, 0xcc0033);
            dest.graphics.moveTo(calcX(0, form), calcY(data[0], form));
            for (var i:int = 1; i < 11; i++)
            {
                dest.graphics.lineStyle(2, 0xcc0033);
                dest.graphics.lineTo(calcX(i, form), calcY(data[i], form));
            }
        }
        
        private function calcY(value:int, form:Form1):Number
        {
            return form.point2_mc.y - (form.point2_mc.y - form.point1_mc.y) / 100 * value;
        }
        
        private function calcX(index:int, form:Form1):Number
        {
            return form.point1_mc.x + (form.point2_mc.x - form.point1_mc.x) / 10 * index;
        }
        
        private function btnClick_h(evt:MouseEvent):void
        {
            if (form1.name_input.text == "")
                return;
            var dataArray:Array = calcData(form1.age_input.value, form1.name_input.text);
            drawData(dataArray, drawingContainer, form1);
        
        }
    }
 
}
















0.2 비교 알고리즘 개선, 버튼 엔터키 추가
0.3 그래픽 개선, 그래프 추가 

재미로 해보는 삼자대결 게임!
비교할 3명의 이름을 입력하고 버튼을 누르면 
이름에 따른 결과가 나옵니다.



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









최신버전(0.3.7) : http://www.tibyte.kr/132



재미로 해보는 삼자대결 플래시입니다.
버전 0.1.3


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







+ Recent posts