본문 바로가기
플래시 자료 제작

교플강9 - 관성효과에 의한 운동

by 민서아빠(과학사랑) 2013. 1. 16.

3. 관성효과를 이용한 공의 운동을 표현할 수 있다.

가. 키보드를 이용한 운동효과 구현

이번에는 키보드를 사용하여 우주선을 조절해 보도록 하자. 키보드로 우주선을 조절하기 위해서는 우선 플래시에서 키보드가 눌렸는지를 감지해야 할 것이다. 그리고 눌려진 키가 무엇인지도 알아내야 할 것이다.

onClipEvent 문을 사용하여 무비클립 자체에다 명령을 줄 수도 있으나, 우리는 지금까지 메인프레임에 액션스크립트를 부여해 왔기 때문에 조금 어렵더라도 액션스크립트에 명령을 부여 하는 방법을 택하도록 하겠다.

우선 키보드가 눌렸는지 체크하기 위해서는 아래와 같은 명령을 메인프레임에 적어 주면 된다.

 

//프레임이 반복될때 마다
onEnterFrame = function () {
//만약 커서키 중에 왼쪽커서키가 눌렸다면
if (Key.isDown(Key.LEFT)) {
trace("왼쪽버튼이 눌렸습니다.“);
}
}

 

즉 프레임이 반복될 때 마다 if 문을 사용하여 키가 눌렸는지를 체크하고, ()안에 우리가 원하는 키를 적어 넣으면 그 키가 눌렸는지 체크를 할 수 있다. 만약 우리가 원하는 키가 눌렸다면, 그에 해당하는 행동을 하게 하면 될 것이다.

if (Key.isDown(Key.LEFT))를 if (Key.isDown(Key.RIGHT)) 로 바꾼다면 오른쪽 키가 눌렸는지를 검사하게 될 것이다.

그럼 키보드를 이용해서 우주선을 좌우로 조절해보자.

우선 자신의 마음에 드는 ufo 라는 무비클립을 하나 만들어보자. 이제 우리는

커서키를 이용하여 이 ufo를 조절하게 될 것이다. 아래와 같은 액션스크립트를 메인 프레임에 작성해 보자.

 

onEnterFrame = function () {
if (Key.isDown(Key.LEFT)) {
ufo._x = ufo._x-0.5;
}
if (Key.isDown(Key.RIGHT)) {
ufo._x = ufo._x+0.5;
}
};

 

좌,우 커서키를 누를때 마다 우주선이 왼쪽, 또는 오른쪽으로 움직이는 것을 알 수 있다. 똑같은 방법으로 위, 아래로도 움직이게 할 수도 있다. 그런데 한가지 문제점이 있다. 물리적 현상에 의하면 우주공간에서는 마찰력이 없기 때문에 왼쪽으로 힘을 받으면 다시 힘을 받기 전까지는 계속해서 등속운동을 해야 한다. 그런데 지금 위에서 작성한 액션 스크립트를 적용해 보면, 커서키를 누를때 마다 한번 움직이고, 다시 정지하는 것을 볼 수 있다.

<키보드 방향키를 눌러 좌우로 이동시켜 보자>

ufo1.swf
다운로드

 


<생각> 관성의 법칙을 따르면서 우주공간처럼 마찰력이 없어서 한쪽 방향으로 한번 힘을 주면 계속해서 움직이게 하려면 어떻게 해야 할까?

 

 


 

벽돌깨기를 만들때 움직이던 공은 관성의 법칙을 따르고 있었다. 우주선도 같은 방법으로 접근하면 될 것이다. 우선 키보드로 우주선에게 한쪽 방향으로 힘을 주면 우주선은 다른 명령이 들어오지 않는 한 그 방향으로 계속해서 운동하면 될 것이다.

위 스크립트를 다음과 같이 수정해 보자.

 

//초기속도
vx = 0;
onEnterFrame = function () {
//관성에 따른 우주선의 움직임 구현
ufo._x = ufo._x+vx;
if (Key.isDown(Key.LEFT)) {
vx = vx-0.5;
}
if (Key.isDown(Key.RIGHT)) {
vx = vx+0.5;
}
};

 

즉 ufo라는 무비클립은 ufo._x = ufo._x+vx; 명령에 의해 자신의 x 좌표를 vx 값만큼 계속해서 바꾸면서 이동을 하게 된다. 우리가 해주는 것은 커서키를 이용하여 vx 의 값을 바꾸어 주는 일만 하면 되는 것이다.

<키보드를 이용하여 좌우로 이동시켜 보자>

ufo2.swf
다운로드


좌,우 뿐만 아니라, 위,아래로 움직일 수 있도록 수정해 보자.

 

나. 마찰력에 따른 운동 감쇠 효과 구현

실제 지구상에서는 한번 움직이기 시작한 물체는 계속해서 움직이지 못하고 마찰력 때문에 시간이 지나면 서서히 멈추게 된다. 위 스크립트를 마찰력에 따른 감쇠 효과가 나타나도록 해보자.

 

ufo._x = ufo._x+vx;

 

vx 값이 일정하다면 우주선은 계속해서 일정한 속도로 이동하게 된다. 따라서 서서히 멈추게 하려면 vx 의 값이 시간이 지날수록 작아지게 해야 할 것이다.

<토의> 위 스크립트를 어떻게 고쳐야 마찰력 효과가 나타나겠는가?

 


 

vx 값을 단순히 더하거나 빼는 것 만으로는 해결 할 수 없다.

 

vx=vx * 0.95;
ufo._x = ufo._x+vx;

 

vx 값에다 1보다 작은 수를 곱해주면 감쇠효과를 나타낼 수 있다. 프레임이 반복될 때마다. vx 값은 점점 작아지게 될 것이고, 그러면 이동하는 우주선의 속력도 점점 감소하게 되므로 결국은 멈추게 될 것이다. 즉 0.95 값이 감쇠효과를 나타내게 되는 것이다. vx 에 곱해진 값들을 바꾸어 가면서 어떤 결과가 나타나는지 실행 시켜 보자.

<키보드를 이용하여 상하좌우로 이동시켜 보자>

ufo3.swf
다운로드

 


다. 중력장 안에서 움직이는 우주선의 효과 구현

 

중력장 안에서는 조절을 하지 않으면 우주선은 아래로 자유낙하를 하게 된다. 따라서 중력장 안에서 움직이는 우주선을 만들기 위해서는 키보드로 방향조절을 하지 않아도 아래로 자유낙하 운동을 하는 우주선을 만들어야 할 것이다.

우선 ufo 라는 무비클립을 하나 만들고 x 축의 속도는 vx, y축의 속도는 vy 로 표시해 보자. 자유낙하 한다는 것은 계속해서 vy 의 속도가 증가하고 있다는 것을 의미한다. 따라서 조절을 하지 않아도 매 프레임마다 vy 값은 아래와 같이 증가해야 할 것이다.

 

vy = vy + 0.1;

 

그럼 중력장 안에서 키보드를 통해 우주선을 움직이도록 해보자. 이왕이면 멋진 배경을 만들고 멋진 우주선을 만들어서 움직이게 한다면 더 멋질 것이다.

ufo 라는 무비클립을 만들고 메인프레임에 아래와 같은 액션스크립트를 적어 주면 우주선을 움직일 수 있다. 중력효과 때문에 조절하지 않으면 자꾸 아래로 내려가려고 하는 것을 볼 수 있을 것이다.

 

//우주선 속도 초기화
vx = 0;
vy = 0;
//매프레임 마다 반복
onEnterFrame = function () {
//중력효과 반영
vy = vy+0.01;
//우주선 움직임
ufo._x = ufo._x+vx;
ufo._y = ufo._y+vy;
//우주선 키보드로 조절
if (Key.isDown(Key.LEFT)) {
vx = vx-0.5;
}
if (Key.isDown(Key.RIGHT)) {
vx = vx+0.5;
}
if (Key.isDown(Key.UP)) {
vy = vy-0.5;
}
if (Key.isDown(Key.DOWN)) {
vy = vy+0.5;
}
};

 

<생각>

1. 중력효과를 더 크게 하거나, 더 작게 해보자

2. 감쇠효과를 적용시켜 시간이 지날수록 느려지다 멈추도록 만들어 보자.

3. 키보드를 조절하는 것에 따라서 우주선이 분사하는 모습을 만들려면 어떻게 해야 할까?

4. 응용

<키보드를 이용하여 상하좌우로 이동시켜 보자>

ufocontrol.swf
다운로드


가. 중력장하에서 마우스로 공 집어 던지기

 

키보드가 아니라 마우스로 공을 잡아서 집어 던지면 그 속력을 유지하면서 날아가도록 해보자. 마우스로 공을 누르면 공이 마우스를 따라다니게 만들고, 마우스를 때는 순간 공이 이동해야할 속도를 결정해야 할 것이다.

즉 마우스를 누르고 움직이는 동안 매 프레임 마다 공이 얼마만큼을 이동하고 있는지를 체크하고 있다가 마우스를 때는 순간 공이 이동해가는 거리를 속도로 바꾸어서 공을 움직이게 해주면 되는 것이다.

ball 이라는 무비클립을 만들고 메인 프레임에 아래와 같이 명령을 주어보자, 그러면 공을 잡아서 움직이게 할 수 있을 것이다.

 

//초기 속력과 초기값
speedx = 0;
speedy = 0;
prevx = ball._x;
prevy = ball._y;
check1 = 0;
onEnterFrame = function () { //반복실행
if (check1 == 0) { //볼이동
ball._x = ball._x+speedx;
ball._y = ball._y+speedy;
} else { //속도 결정
tempx = ball._x-prevx;
tempy = ball._y-prevy;
prevx = ball._x;
prevy = ball._y;
}
};
ball.onPress = function() { //공 마우스로 눌렀을 때 볼 이동
_root.check1 = 1;
this.startDrag(true);
};

 

 

//공에서 마우스를 때는 순간 이동 속도 결정
ball.onRelease = function() {
stopDrag();
_root.check1 = 0;
_root.speedx = _root.tempx;
_root.speedy = _root.tempy;
};

 

벽돌깨기처럼 화면을 벗어나지 않고 벽에 부딪히면 다시 튕겨 나오도록 만들어 보자. 벽돌깨기 소스를 참고해서 벽을 벗어나지 않도록 처리해 주면 될 것이다.

<마우스로 볼을 잡다 원하는 방향으로 던져보자>