본문 바로가기

AS3/ActionScript

flixel 게임 프레임웍을 이용한 미니게임 만들기

오픈소스 게임 프레임웍 Flixel을 이용해서 간단한 코인 모으기
게임을 만들어 보면서 Flixel 프레임웍의 기능들을 알아볼 수
있는 예제입니다.
 
flixel.org 사이트에 있는 내용이며 처음 접하시는 분들의 이해를
돕기 위해 작성된 글입니다.

해당 예제에서는 플레이어(레드박스), 코인, 출구, 스코어 표시,
현재 상태, 타일맵 생성 그리고 게임의 승리 조건을 나타내는
소스들로 이루어져 있습니다.

실제 사용자가 작성해야할 코드는 크게 EZPPlatformer.as(메인
클래스) 와 PlayState.as(게임화면) 두개의 클래스로 이루어져 있습니다. 어렵지 않으니 차근차근 보시면 됩니다~~!
 

package
{
	import org.flixel.FlxGame
	[SWF(width="640", height="480", backgroundColor="#000000")]
	[Frame(factoryClass="Preloader")]

	public class EZPlatformer extends FlxGame
	{
		public function EZPlatformer()
		{
			super(320,240,PlayState,2);
			forceDebugger = true;
		}
	}
}
EZPlatformer.as
메인 클래스(EZPlatformer) 생성 합니다.
부모 클래스 생성자 인자값으로 가로 320 세로 240에
최초에 보여질 게임화면 PlayState를 참조시키고 화면을 2배 줌합니다.


package
{
	import org.flixel.*;

	public class PlayState extends FlxState
	{
		public var level:FlxTilemap;
		public var exit:FlxSprite;
		public var coins:FlxGroup;
		public var player:FlxSprite;
		public var score:FlxText;
		public var status:FlxText;
		
		override public function create():void
		{
			//배경색을 밝은 회색으로 설정 (0xAARRGGBB)
			FlxG.bgColor = 0xffaaaaaa;
PlayState.as
실제 보여질 게임화면을 구성 작성합니다.
앞으로 만들어질 모든 게임과 관련된 화면들은
FlxState 클래스를 상속해서 화면을 구성합니다.
우선 FlxG 클래스의 bgColor 클래스 속성을 이용해 배경 색을 변경합니다.


			//맵 디자인 (320x240 화면에 40x30 으로 채운다 )
			var data:Array = new Array(
			
				1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
				1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
				1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
				1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
				1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
				1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
				1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1,
				1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1,
				1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
				1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
				1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
				1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
				1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
				1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1,
				1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
				1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
				1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
				1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
				1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1,
				1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1,
				1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1,
				1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
				1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
				1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
				1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
				1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
				1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
				1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1,
				1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1,
				1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 );
			//레벨 데이터를 이용해 타일맵을 만듭니다. Create a new tilemap using our level data
			level = new FlxTilemap();
			level.loadMap(FlxTilemap.arrayToCSV(data,40),FlxTilemap.ImgAuto,0,0,FlxTilemap.AUTO);
			add(level);
타일 맵 구성하기
타일 맵을 만들기위해 data배열에 맵을 그려줄 데이터를 넣습니다(1과0으로 이루어진).
level 변수에 FlxTilemap클래스를 객체로 생성합니다.
level 객체의 loadMap 함수를 이용해 타일맵을 만듭니다.


			//출구를 만듭니다. 처음에는 숨겨져 있는 어두운 회색 상자
			exit = new FlxSprite(35*8+1,25*8);
			exit.makeGraphic(14,16,0xff3f3f3f);
			exit.exists = false;
			add(exit);
출구 만들기
FlxSprite클래스를 이용해 출구로 사용할 객체를 만듭니다.


			//수집할 동전을 만듭니다. 
			coins = new FlxGroup();
			//상단 왼쪽에 코인들
			createCoin(18,4);
			createCoin(12,4);
			createCoin(9,4);
			createCoin(8,11);
			createCoin(1,7);
			createCoin(3,4);
			createCoin(5,2);
			createCoin(15,11);
			createCoin(16,11);
			
			//하단 왼쪽에 코인들
			createCoin(3,16);
			createCoin(4,16);
			createCoin(1,23);
			createCoin(2,23);
			createCoin(3,23);
			createCoin(4,23);
			createCoin(5,23);
			createCoin(12,26);
			createCoin(13,26);
			createCoin(17,20);
			createCoin(18,20);
			
			//상단 오른쪽 코인들
			createCoin(21,4);
			createCoin(26,2);
			createCoin(29,2);
			createCoin(31,5);
			createCoin(34,5);
			createCoin(36,8);
			createCoin(33,11);
			createCoin(31,11);
			createCoin(29,11);
			createCoin(27,11);
			createCoin(25,11);
			createCoin(36,14);
			
			//하단 오른쪽 코인들
			createCoin(38,17);
			createCoin(33,17);
			createCoin(28,19);
			createCoin(25,20);
			createCoin(18,26);
			createCoin(22,26);
			createCoin(26,26);
			createCoin(30,26);

			add(coins);
코인 만들기
createCoin(x, y) 함수를 이용해 화면에 보여질 코인들을 생성합니다.


	
			//플레이어 만들기 (붉은상자)
			player = new FlxSprite(FlxG.width/2 - 5);
			player.makeGraphic(10,12,0xffaa1111);
			player.maxVelocity.x = 80;
			player.maxVelocity.y = 200;
			player.acceleration.y = 200;
			player.drag.x = player.maxVelocity.x*4;
			add(player);
플레이어 만들기(붉은상자)
FlxSprite클래스를 이용해 플레이어 객체를 생성합니다.
Player 속성값을 이용해 중력값과 가속도를 설정합니다.


			
			score = new FlxText(2,2,80);
			score.shadow = 0xff000000;
			score.text = "SCORE: "+(coins.countDead()*100);
			add(score);
스코어 보드 만들기
FlxText클래스를 이용해 스코어 보드 객체를 생성합니다.


			
			status = new FlxText(FlxG.width-160-2,2,160);
			status.shadow = 0xff000000;
			status.alignment = "right";
			switch(FlxG.score)
			{
				case 0: status.text = "Collect coins."; break;
				case 1: status.text = "Aww, you died!"; break;
			}
			add(status);
현재 상태창 만들기
FlxText클래스를 이용해 상태창 객체를 생성합니다.


		}
		
		//코인을 타일 좌표에 생성
		public function createCoin(X:uint,Y:uint):void
		{
			var coin:FlxSprite = new FlxSprite(X*8+3,Y*8+2);
			coin.makeGraphic(2,4,0xffffff00);
			coins.add(coin);
		}
코인 생성 메서드
FlxSpritet클래스를 이용해 화면에 코인객체를 생성해주는 메서드입니다.


		
		override public function update():void
		{
			//플레이어 움직임 컨트롤
			player.acceleration.x = 0;
			if(FlxG.keys.LEFT)
				player.acceleration.x = -player.maxVelocity.x*4;
			if(FlxG.keys.RIGHT)
				player.acceleration.x = player.maxVelocity.x*4;
			if(FlxG.keys.justPressed("SPACE") && player.isTouching(FlxObject.FLOOR))
				player.velocity.y = -player.maxVelocity.y/2;
	
			//모든 객체를 업데이트 한다.
			super.update();

			//플레이어가 코인과 오버랩 되는지 체크
			FlxG.overlap(coins,player,getCoin);
			
			//플레이어가 출구를 건들였는지 체크
			FlxG.overlap(exit,player,win);
			
			//마지막으로 플레이어가 맵에 다달았을때 충돌 체크
			FlxG.collide(level,player);
			
			//플레이어가 죽었는지 체크
			if(player.y > FlxG.height)
			{
				FlxG.score = 1; //sets status.text to "Aww, you died!"
				FlxG.resetState();
			}
		}
화면 업데이트 하기(update())
enterFrame에 의해 모든 상황을 체크하는 심장이라고 볼 수 있습니다.
플레이어와 코인, 출구, 타일 맵 충돌등을 그리고 죽었을 때의 상황을 계속 체크합니다.


		//플레이어가 코인을 건들였을 때
		public function getCoin(Coin:FlxSprite,Player:FlxSprite):void
		{
			Coin.kill();
			score.text = "SCORE: "+(coins.countDead()*100);
			if(coins.countLiving() == 0)
			{
				status.text = "Find the exit.";
				exit.exists = true;
			}
		}
getCoin()
플레이어가 코인에 충돌할 경우 코인을 삭제합니다.
스코어 보드에 점수를 추가 합니다.
코인의 갯수가 0이 되었을 경우 출구가 보이게 됩니다.


		//사용자가 출구에 도착 했을 때
		public function win(Exit:FlxSprite,Player:FlxSprite):void
		{
			status.text = "Yay, you won!";
			score.text = "SCORE: 5000";
			Player.kill();
		}
	}
}
게임을 클리어 했을 경우 (win())
현재 상태창을 변경합니다.
스코어보드에 점수값을 대입
플레이어를 죽입니다 ;ㅁ;




게임을 만들기 위해서는 기술적으로 많은 기능들이 들어가는데 flixel 프레임웍을 이용한다면
게임에 필요한 기능들을 쉽고 간편하게 사용해서 단기간에 게임 개발이 가능합니다.
잘 활용한다면 좋은 프레임웍이 될 수 있을거 같네요.

현재도 플래시를 통해 안드로이드, 아이폰 모바일 플랫폼 개발이 가능합니다.
추후에 나올 모레힐 버전에서는 하드웨어 가속을 통해 좀더 원활한 개발이 가능할것이고
모바일 게임 개발에 이런 다양한 프레임웍들이 큰 도움이 되리라 생각됩니다.

flixel 사이트에는 튜토리얼, 예제, 도움말등 더 많은
자료가 정리되어 있습니다. 참고하세요~ 

flixel이 지원하는 기본적인 기능 
- 카메라
- 패스파인딩
- 리플레이
- 충돌
- 타일맵 생성 & 자동 생성
- 파티클 생성
- 저장

프레임웍 사이트 : http://flixel.org

A
ir 2.6 + Flixel 을 통해 만들어진 IOS 게임들
- http://www.youtube.com/watch?v=Rd-i4mGJcSo 
http://johnlindquist.com/2011/03/29/flixel-on-the-ipad/ 

앱스토어 올라가있는 Air 2.6 + Flixel 게임 어플
http://itunes.apple.com/us/app/pixel-city-skater/id436758864?mt=8&ls=1
http://www.youtube.com/watch?v=vtFPuBQTgoU

'AS3 > ActionScript' 카테고리의 다른 글

osmf 샘플  (0) 2011.04.05
LocalConnection  (1) 2011.03.22
Actionscript 3 MySql Driver - assql  (0) 2011.03.14
as3.0 lib  (0) 2011.02.07
twitter API for ActionScrpit 3.0  (0) 2010.09.21