Flash CS4 + ActionScript 3.0으로 게임 수학/물리 구현 공부 계속.

1-3: 물체를 원하는 방향으로 움직이기.

화면 중앙에서 꽃을 사방으로 날려 보내기.

14/12/4 목

소스(스테이지상에 미리 'flowerM'이란 이름의 꽃 무비클립을 놓아두었다):

var flower = flowerM;
var fAngle = Math.PI / 6; //초기 각도는 30도
var playerVel = 10; //이동 속도
var rightEnd = stage.stageWidth; //화면 우측 끝
var downEnd = stage.stageHeight; //화면 하단 끝


function init(){
	//꽃 초기 위치는 중앙
	flower.x = rightEnd/2; 
	flower.y = downEnd/2;
	//각도에 의해 이동 방향 정하기
	flower.vx = playerVel * Math.cos(fAngle); 
	flower.vy = playerVel * Math.sin(fAngle);
	stage.addEventListener(Event.ENTER_FRAME,loop);
}

function loop(e:Event){
	flower.x += flower.vx;
	flower.y += flower.vy;
	
	//꽃이 화면밖으로 나갈 경우 처리
	if((flower.x < -flower.width || flower.x > rightEnd) ||
	   (flower.y < -flower.height || flower.y > downEnd)){
		//꽃을 화면 중앙으로 되돌리기
		flower.x = rightEnd/2;
		flower.y = downEnd/2; 
		fAngle += 2 * Math.PI / 10; //각도 증가시키기
		//한바퀴 회전시 원래 각도로 돌리기
		if(fAngle > 2 * Math.PI) fAngle -= 2 * Math.PI;
		//각도에 의해 이동 방향 정하기
		flower.vx = playerVel * Math.cos(fAngle);
		flower.vy = playerVel * Math.sin(fAngle);
		//진행방향으로 꽃 회전시키기
		flower.rotation = fAngle * 180/Math.PI;
	}
}
init();

 


1-4: 물체에 중력 추가하기.

중력에의해 포물선을 그리며 낙하하는 볼.

소스(스테이지상에 미리 'ballm'란 이름의 볼 무비클립을 놓아두었다):

var ball = ballm;
var rightEnd = stage.stageWidth;
var downEnd = stage.stageHeight;
var grav = 0.2; //중력
var line:Sprite=new Sprite();//궤적 그리기용 선

function init(){
	ball.vx = 5;
	ball.vy = 0;
	addChild(line); //회전 궤적 그릴 선 추가
	line.graphics.lineStyle(1);
	line.graphics.moveTo(ball.x+ball.width/2, ball.y+ball.height/2);
	
	stage.addEventListener(Event.ENTER_FRAME,loop);
}
function loop(e:Event){
	ball.x += ball.vx;
	ball.y += ball.vy;
	ball.vy += grav; //중력 추가
	
	//볼이 화면밖으로 나갈 경우 처리
	if((ball.x < -ball.width || ball.x > rightEnd) ||
	   (ball.y < -ball.height || ball.y > downEnd)){
		//볼 시작 위치 좌하단으로 초기화
		ball.x = 0;
		ball.y = 260;
		//쏘아올리는 힘은 -10~0 사이 랜덤으로 재설정.
		ball.vy = Math.random()*-10;
		
		line.graphics.clear();
		var colors=Math.random()*16777215;
		line.graphics.lineStyle(1, colors, 1);
		line.graphics.moveTo(ball.x+ball.width/2, ball.y+ball.height/2);
	}
	line.graphics.lineTo(ball.x+ball.width/2, ball.y+ball.height/2);
}
init();

 


1-4a: 물체에 중력 추가하기(적분 응용).

중력에의해 포물선을 그리며 낙하하는 볼.

시간과 적분 공식을 이용해 구하기에 보다 정확하며 타임랙등이 걸렸을 경우에도 볼의 위치는 정확한 위치를 표시한다.

소스(스테이지상에 미리 'ballm'란 이름의 볼 무비클립을 놓아두었다. 궤적을 그리는 코드는 위와 동일하므로 제거했다):

var ball = ballm;
var rightEnd = stage.stageWidth;
var downEnd = stage.stageHeight;
var grav = 0.2; //중력
var ballYinit = 0; //y축 초기 위치 담기용 변수

function init(){
	ball.vx = 5;
	ball.vy = 0;
	ballYinit = ball.y;
	ball.t = 0; //볼의 시간 초기화
	stage.addEventListener(Event.ENTER_FRAME,loop);
}
function loop(e:Event){
	ball.t++; //볼의 시간 증가
	//적분을 응용한 포물선
	ball.x = ball.vx * ball.t;
	ball.y = 0.5 * grav * ball.t * ball.t + ball.vy * ball.t + ballYinit;
	//볼이 화면밖으로 나갈 경우 처리
	if((ball.x < -ball.width || ball.x > rightEnd) ||
	   (ball.y < -ball.height || ball.y > downEnd)){
		ball.x = 0; //볼 위치, 속도, 시간 초기화
		ball.y = 260;
		ballYinit = ball.y;
		ball.t = 0; 
		//쏘아올리는 힘은 -10~0 사이 랜덤으로 재설정.
		ball.vy = Math.random()*-10;
	}
}

 


1-5: 물체들을 랜덤하게 쏘아 올리기.

막대기들의 배열 만들어 랜덤하게 쏘아 올리기.

막대기의 각도를 실시간으로 구하기 위해 atan2(y, x)와 rotation 속성을 이용했다. 한데 x, y의 초기위치가 250, 260임에도 그 값을 빼주지 않고 계산하고는 어째서 회전이 제대로 이루어지지 않는걸까 하고 한참을 헤멨었다.

소스(라이브러리에 미리 'stickMov'란 Export 명의 막대 무비클립을 만들어두었다.):

var ballArr:Array = []; //막대기들 담을 배열
var ballArrNum:int = 20; //막대기들의 숫자 지정용
var rightEnd = stage.stageWidth;
var downEnd = stage.stageHeight;
var grav = 0.2; //중력
var ang = 0; //회전각도용

function init(){
     createBallArr();
     stage.addEventListener(Event.ENTER_FRAME,loop);
}
function createBallArr(){ //막대기 배열 만들기
     for(var i=0; i < ballArrNum; i++){
          var b:MovieClip = new stickMov();
          stage.addChild(b);
          b.x = 250, b.y = 260;
          b.vx = Math.random()* 5 - 5/2 ;
          b.vy = Math.random()* -10;
          b.rotation = 0;
          ballArr.push(b);
     }
}
function loop(e:Event){
     for(var i=0; i < ballArr.length; i++){
          ballArr[i].x += ballArr[i].vx;
          ballArr[i].y += ballArr[i].vy;
          ballArr[i].vy += grav;
          //진행각도 구해 회전시키기
          ang = Math.atan2(ballArr[i].y-260, ballArr[i].x-250);
          ballArr[i].rotation = ang*180/Math.PI;
     
          //막대기가 화면밖으로 나갈 경우 처리
          if((ballArr[i].x //< -ballArr[i].width || 
               ballArr[i].x > rightEnd)|| ballArr[i].y > downEnd){
               ballArr[i].x = 250; //막대기 위치 재초기화
               ballArr[i].y = 260;
               getRandVxy(i); //막대기 속도 재초기화
               ballArr[i].rotation = -90; //볼 회전각도 초기화
          }
     }
}
function getRandVxy(index){ //속도 랜덤하게 구하기
     ballArr[index].vx = Math.random()* 5 - 5/2 ;
     ballArr[index].vy = Math.random()* -10 -2;
}
init();