Flash with Adobe AIR

Starling-Hungry Hero-04

GrayrabbiT 2015. 2. 16. 13:53
반응형

04가 맞는지 모르겠네요.ㅡㅡ; 뭐 이건 중요한거 아니니까 나중에 수정하도록 하고…

 

이게 블로그질을 하다 보니 점점 의무감으로 포스팅을 하고 있네요. 흐악.. 할것도 많은데 이걸 다루고 싶은 마음이 커서요. 뭐랄까? 한국어로 된 사이트들 중에서 Starling을 제대로 소개하고 있는 사이트도 잘 못찾겠고. 책도 찾기 어렵고. 게다가 다 부분부분 있는 거라서 어떻게 해야 할지 감이 안오는 날들이 많았는데. 이걸 보고 좀 연습해 보는 중입니다. 이글을 혹시 보신다면 여러분들도 검색검색 하다가 이렇게 누추한 블로그까지 오셨겠죠? 헛소리 집어치우고 시작하겠습니다.

 

일단 objects 패키지에서 하나를 더 만들께요. GameBackground 클래스 입니다. Sprite 자식이구요.(Starling요)

 

 

이렇게 만들구요. InGame 클래스로 돌아가서 이녀석을 하나 만들어 주자구요. 전 bg라는 이름으로 만들꺼고 먼저 선언해 주도록하겠습니다.

 

 

        private var bg:GameBackground;

 

그리고 drawGame 메소드로 가서 이렇게 추가해주겠습니다. drawGame 전체 메소드입니다.

 

        private function drawGame():void

        {

            bg = new GameBackground();

            this.addChild(bg);

            

            hero = new Hero();

            hero.x=stage.stageWidth>>1;

            hero.y=stage.stageHeight>>1;

            this.addChild(hero);

            

        }

 

이제는 뒷배경에 대해서 이야기 해 보죠. 우리는 총 4장의 레이어로 배경을 구성할 것입니다. 이런 류의 게임을 좀 해보셨으면 아시겠지만 보통 배경은 계속 같은 녀석들이 돌아가게 되어 있습니다. 또한 2D게임에서는 이러한 배경들에 원근감을 주기 위해서 레이어가 지나가는 속도를 약간 다르게 설정하죠. 우리도 한번 해보자구요.

그런데 먼저 레이어를 깔아야 하기 때문에 …. Asstes.as로 돌아가겠습니다.

일단 하나 추가해 주어야 할 것이 bglayer1.jpg 파일입니다.이녀석을 이렇게 추가해 주도록 하겠습니다.

 

        [Embed(source="../assets/graphics/bgLayer1.jpg")]

        public static const BgLayer1:Class;

 

네 적당히 끼워 넣으시면 되요. 이제 클래스를 하나 만들텐데요 이녀석이 배경화면을 조정할 것입니다. 일단 BgLayer 입니다.

이렇게 만들어 주시면 될 것 같습니다. 자. 이제 이녀석을 어떻게 요리할까요? 생각해보면 일단 우리가 가진 재료부터 살펴보아야 겠죠? 우리가 가진 재료는 제일 큰 화면인 BgLayer1.jpg 입니다. 이녀석은 거의 풀 화면으로 들어갈 녀석이에요 그리고 나머지 재료들은 SpriteSheet에 차곡차곡 있습니다. 3개의 레이어가 그쪽에 가 있습니다.

 

자 그러면 어떻게 처리할까를 고민해보면 이렇게 처리하면 되겠죠. 일단. 클래스 하나를 더 만들어서 레이어 두개 복제해서 한 세트로 취급하는거죠. 그림 두장을 똑같이 만들어서 하나의 객체처럼 처리할 수 있도록 만드는 것입니다. 그래서 우리는 이녀석을 BgLayer.as 인 클래스로 만들 것입니다. 이렇게요.

그리고 BgLayer 클래스에서 필요한 걸 살펴보면 먼저 이미지 2장을 만들어야 되니까 일단 선언을 하죠.

 

        private var image1:Image;

        private var image2:Image;

        

        private var _layer:int;

        private var _parallax:Number;

        

 

또한 레이어가 총 4장이니까 그에 따라 반응해 주게 하기위해서 다음과 같이 만들겠습니다. _layer 번호구요. _parallax 는 레이어들의 속도를 조정해 주기위해 설정해 주는 변수라고 생각하시면 간단할 것 같습니다. 그리고 다음과 같이 생성자에 매개변수를 넣죠. 생성할때 레이어 번호를 받아오도록요.

        public function BgLayer(layer:int)

        {

            super();

            this._layer = layer;

            this.addEventListener(Event.ADDED_TO_STAGE,onAdded);

        }

    

이렇게 만들어주구. 이벤트 하나 걸어주겠습니다.

        private function onAdded(e:Event):void

        {

            this.removeEventListener(Event.ADDED_TO_STAGE,onAdded);

            

            if(_layer==1)

            {

                image1 = new Image(Assets.getTexture("BgLayer"+_layer));

                image2 = new Image(Assets.getTexture("BgLayer"+_layer));    

            }

            else

            {

                image1 = new Image(Assets.getAtlas().getTexture("bgLayer"+_layer));

                image2 = new Image(Assets.getAtlas().getTexture("bgLayer"+_layer));

            }

            image1.x=0;

            image1.y=stage.stageHeight-image1.height;

            

            image2.x=image2.width;

            image2.y=image1.y;

            

            this.addChild(image1);

            this.addChild(image2);

        }

 

자 이렇게 구성하려고 합니다. 일단 이벤트 하나 제거하구요. 만약에 레이어가 1번일 경우에는 스프라이트시트에 없는 녀석이기 때문에 우리가 만들어 놓은 Assets 클래스의 getTexture를 써서 하나를 가져옵니다. 이때 이름에서 레이어번호를 넣어주면 구별이 되겠죠?

만약에 1이 아닌 경우에는 스프라이트 시트에 들어있기때문에 getAtlas로 textureAtlas를 반환받은 다음에 getTxture를 통해서 받아오도록 합니다.

그리고 받아온 후에는 좌표 설정을 해주는데요. 일단 첫번째 이미지는 x좌표 0에 그다음 Image2의 x좌표는 그림 한장을 넓이 만큼 이동하면 될 것 같습니다.

Y 좌표의 경우에는 배경이란 모든게 땅에서 부터 시작하기 때문에 스테이지의 넓이에서 바닥에서 정렬하기 위해서 저렇게 꾸며주었습니다. 그리고 붙여넣겠죠.

또 각 레이어마다 속도를 주는 변수였던 _parallax 는 getter setter 를 생성합니다.

        public function get parallax():Number

        {

            return _parallax;

        }

 

        public function set parallax(value:Number):void

        {

            _parallax = value;

        }

요렇게 설정하면 되겠죠? 이게 전부입니다. BgLayer.as 의 전체코드입니다.

 

package objects

{

    import starling.display.Image;

    import starling.display.Sprite;

    import starling.events.Event;

    

    public class BgLayer extends Sprite

    {

        private var image1:Image;

        private var image2:Image;

        

        private var _layer:int;

        private var _parallax:Number;

        

        public function BgLayer(layer:int)

        {

            super();

            this._layer = layer;

            this.addEventListener(Event.ADDED_TO_STAGE,onAdded);

        }

        

        private function onAdded(e:Event):void

        {

            this.removeEventListener(Event.ADDED_TO_STAGE,onAdded);

            

            if(_layer==1)

            {

                image1 = new Image(Assets.getTexture("BgLayer"+_layer));

                image2 = new Image(Assets.getTexture("BgLayer"+_layer));    

            }

            else

            {

                image1 = new Image(Assets.getAtlas().getTexture("bgLayer"+_layer));

                image2 = new Image(Assets.getAtlas().getTexture("bgLayer"+_layer));

            }

            image1.x=0;

            image1.y=stage.stageHeight-image1.height;

            

            image2.x=image2.width;

            image2.y=image1.y;

            

            this.addChild(image1);

            this.addChild(image2);

        }

        

        public function get parallax():Number

        {

            return _parallax;

        }

 

        public function set parallax(value:Number):void

        {

            _parallax = value;

        }

 

    }

}

 

이렇게 하고 이제 GameBackground로 돌아가도록 하죠.

이제 그냥 부분 부분 설명드리지 않고 … 소스를 다 넣고 주석으로 설명드릴께요.ㅡㅡ; 귀찮네요.

 

GameBackground.as

 

package objects

{

    import starling.display.Sprite;

    import starling.events.Event;

    

    public class GameBackground extends Sprite

    {

        private var bgLayer1:BgLayer;//레이어 4개를 선언한다. 배경은 4장이니까

        private var bgLayer2:BgLayer;

        private var bgLayer3:BgLayer;

        private var bgLayer4:BgLayer;

        

        private var _speed:Number=0;

        

        public function GameBackground()

        {

            super();

            this.addEventListener(Event.ADDED_TO_STAGE, onAdded);

        }

        

        private function onAdded(e:Event):void

        {

            this.removeEventListener(Event.ADDED_TO_STAGE, onAdded);

            

            //레이어들을 객체로 해준다 . 일단 BgLayer 클래스의 객체를 생성하면서 그에 맞는 번호를 넣어준다.

            bgLayer1 = new BgLayer(1);

            bgLayer1.parallax=0.02;

            this.addChild(bgLayer1);

            

            bgLayer2 = new BgLayer(2);

            bgLayer2.parallax=0.2;

            this.addChild(bgLayer2);

            

            bgLayer3 = new BgLayer(3);

            bgLayer3.parallax=0.5;

            this.addChild(bgLayer3);

            

            bgLayer4 = new BgLayer(4);

            bgLayer4.parallax=1;

            this.addChild(bgLayer4);

            

            this.addEventListener(Event.ENTER_FRAME, onEnterFrame);

        }

        

        private function onEnterFrame(e:Event):void

        {

            //레이어들의 좌표를 이동시킨다. 좌표는 - 점점 돌아가며 , 만약 x 좌표가 넓이보다 작아지면 좌표를 0으로 리셋시킨다.

            bgLayer1.x-=Math.ceil(_speed*bgLayer1.parallax);

            if(bgLayer1.x<-stage.stageWidth) bgLayer1.x=0;

            

            bgLayer2.x-=Math.ceil(_speed*bgLayer2.parallax);

            if(bgLayer2.x<-stage.stageWidth) bgLayer2.x=0;

            

            bgLayer3.x-=Math.ceil(_speed*bgLayer3.parallax);

            if(bgLayer3.x<-stage.stageWidth) bgLayer3.x=0;

            

            bgLayer4.x-=Math.ceil(_speed*bgLayer4.parallax);

            if(bgLayer4.x<-stage.stageWidth) bgLayer4.x=0;

        }

        

        public function get speed():Number

        {

            return _speed;

        }

 

        public function set speed(value:Number):void

        {

            _speed = value;

        }

 

    }

}

보시면 이해가 되시리라 믿습니다. 일단 BgLayer의 객체를 생성할때 레이어의 번호를 던저주면 알아서 그에 맞는 레이어를 생성하겠죠. 그리고 두 장을 한꺼번에 붙여서 생성해놓을 것입니다. 또, getter setter를 해놓았기 때문에 그에 맞는 값을 입력할 수 있도록 해 놓았습니다. 자 여기까지 되면…

이벤트로 엔터프레임을 하나 걸어주죠. 이녀석을 프레임이 지나갈때 마다 레이어들의 위치를 변화시킬꺼에요. 보시면 아시겠지만 레이어들의 넓이… 즉,, 2장을 붙여 놓은 것 중에서 하나가 다 넘어가면 다시 0의 좌표로 돌립니다. 무슨 뜻인고 하면…

직접 보여드리면서 설명드리면 쉬운데. 모니터를 생각해 보세요. 만약 그림한장이 지나가고 있습니다. 그럼 그 그림끝에는 아무것도 없어서 검정화면이 나오겠죠? 이런 상황을 발생시키지 않기 위해서 일단 2장을 붙여 놓습니다. 그리고 다시 움직여보면 한장이 화면 밖으로 완전히 빠져나왔을때, 다른 한장은 화면에 있겠죠? 이때, 엔터프레임이벤트 안에서는 한장이 완전히 벗어났기 때문에 이 전체를 다시 처음으로 돌립니다.

생각해보면 stage.stageWidth * 2 = bglayer.width 가 되는 상태기 때문에 코드를 저렇게 넣어주는 것이죠.옙 뭐 그렇다구요. 아시는데 장황하게 설명드려 대단히 송구스럽네요.ㅡㅡ;

 

그리고 스피드도 getter setter를 넣어줍니다. 이녀석은 나중에 만약 캐릭터가 장애물에 부딪칠 경우에 속도를 팍 떨궈줘야 겠죠? 그때 사용하기위해서 일단 세팅해 놓습니다.

 

이녀석을 디버깅 해 보면 이제 히어로가 날아가고 배경들이 그럴싸 하게 움직일 것입니다.

04번은 여기까지 하겠습니다~

 

 

 

 

 

 

반응형

'Flash with Adobe AIR' 카테고리의 다른 글

  (0) 2015.02.16
Starling-Hungry Hero-05  (0) 2015.02.16
Starling-Hungry Hero-03  (0) 2015.02.16
Starling-HungryHero-02  (0) 2015.02.16
ANE for Android -2  (0) 2015.02.11