본문 바로가기

프로그래밍/iOS

[iOS] 화면 기울임에 따라 움직이는 나비 만들기

스토리 보드는 수정할 필요 없음




프로젝트 - General- Linked Framworks에서 추가(+)버튼을 눌러

CoreMotion.framwork를 추가한다.

 

첨부파일에 올려져있는 png파일들을 프로젝트로 불러들인다.(드래그앤 드랍)

ButterflyArt.zip




 

CoreMotion.h파일을 import한 뒤 필요한 변 수들을 추가한다.

아래 property는 해당 변수에 대해 자동으로 getter/setter를 추가해주는 기능이다.(굳이 사용안해도 된다.)

 

-  ViewController.m파일의 viewDidLoad함수안에 다음코드를 입력한다.

 

[self initButterflies]; //초기화 함수 호출

    motionManager=[[CMMotionManager alloc]init]; //모션관리자 생성

    NSOperationQueue* queue=[[NSOperationQueue alloc]init]; //모션관리자 작업 쌓는 

    if(motionManager.accelerometerAvailable)//가속도계사용가능

    {

        motionManager.accelerometerUpdateInterval=1.0/10.0;

        [motionManager startAccelerometerUpdatesToQueue:queue withHandler:^(CMAccelerometerData *accelerometer, NSError *error)

         {

             if(error)

                 [motionManager stopAccelerometerUpdates];

             else

             {

                 //가속도계의 요소  추출

                 float xx=-accelerometer.acceleration.x;

                 float yy=accelerometer.acceleration.y;

                 //최근의 각도 오프셋 저장

                 mostRecentAngle atan2(yy,xx);

                 //방향의 변경 여부 확인

                 float accelDirX=((xvelocity<0)?(-1):1)*-1.0f;

                 float newDirX=((xx<0)?(-1):1);

                 float accelDirY=((yvelocity<0)?(-1):1)*-1.0f;

                 float newDirY=((yy<0)?(-1):1);

                 //객체를 가속

                 if(accelDirX==newDirX)

                     xaccel=(abs(xaccel)+0.85f)*((xaccel<0)?(-1):1);

                 if(accelDirY==newDirY)

                     yaccel=(abs(yaccel)+0.85f)*((yaccel<0)?(-1):1);

                 //현재의 속도에 가속도계의 변화를 반영

                 xvelocity=-xaccel*xx;

                 yvelocity=-yaccel*yy;

             }

         }

         ];

 

    }

    else //가속도계사용불가

    {

        UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"경고" message:@"현재기기에서는 가속도계측이 불가합니다." delegate:self cancelButtonTitle:@"확인" otherButtonTitles:@"취소",nil];

        [alert show]; //경고창 출력

 

    }

 

- 위 코드에서 문제가 되는 초기화 함수를 입력한다.

 

-(void)initButterflies //초기화 함수

{

    CGSize size;

    //그림 여러장으로 애니메이션 효과

NSMutableArray *butterflies = [NSMutableArray array];

for (int i = 1; i <= 17; i++)

    {

        NSString *fileName = [NSString stringWithFormat:@"bf_%d.png", i];

        UIImage *image = [UIImage imageNamed:fileName];

        size = image.size;

[butterflies addObject:image];

    }

    //애니메이션 시작

    butterfly=[[UIImageView alloc]initWithFrame:(CGRect){.size=size}];

    [butterfly setAnimationImages:butterflies];

    butterfly.animationDuration=0.75f;

    [butterfly startAnimating];

    //나비의 가속도 설정

    xaccel=1.0f;

    yaccel=1.0f;

    //나비의 초기속도 설정

    xvelocity=0.0f;

    yvelocity=0.0f;

    // 중앙에 나비 추가

    butterfly.center=CGPointMake(CGRectGetMidX(self.view.bounds),CGRectGetMidY(self.view.bounds));

    [self.view addSubview:butterfly];

    //물리 타이머 가동, 0.03 단위로 tick호출

    [NSTimer scheduledTimerWithTimeInterval:0.03f target:self selector:@selector(tick) userInfo:nil repeats:YES ];

    

 

}

 

- 0.3초 단위로 호출 될 tick함수를 입력한다.

 

 

-(void)tick //0.3 단위로 호출될 함수

{

    butterfly.transform=CGAffineTransformIdentity; //위치를 바꾸기  나비의 모양을 원래대로 바꿈

    //현재 속도가 가해지는 벡터 방향으로 나비를 이동 시킴

    CGRect rect = CGRectOffset(butterfly.frame,xvelocity,0.0f);

    if (CGRectContainsRect(self.view.bounds, rect))

        butterfly.frame = rect;

    rect = CGRectOffset(butterfly.frame, 0.0f, yvelocity);

    if(CGRectContainsRect(self.view.bounds, rect))

        butterfly.frame=rect;

    //위치 상관없이 나비 회전

    butterfly.transform=CGAffineTransformMakeRotation(mostRecentAngle+M_PI_2);

 

}

 

- 마지막으로 화면 고정하는 함수를 입력한다.

-(BOOL)shouldAutorotate

{

    return YES;

}

-(NSUInteger)supportedInterfaceOrientations

{

    return UIInterfaceOrientationMaskPortrait;

    

 

}

 

실행해보면 다음과 같이 나비가 나타난다. 화면을 기울일때 마다 그 방향 아래쪽으로 나비가 내려간다.