iDev

GameController 프레임 워크 허접 사용법

KraZYeom 2013. 12. 23. 08:27
반응형

Moga 게임 콘트롤러를 약 10만원 이상 주고 구매했으니, 게임만 할게 아니라 GameController 프레임 워크를 사용해서 한번 API 테스트나 해보기로 했습니다. 


일단 애플 공식 Game Controller Programming Guide 를 펼칩니다. 대충 이해는 되나 뭐라고 하는지 모르겠습니다. 그래서 일단 다시 구글링을 합니다. 관련된 싸이트가 하나있습니다. 애플 공식 Game Controller Programming Guide 입니다. 스택오버플로우 검색합니다. 관련된 질문이 하나 있습니다. 답변은 애플 공식 Game Controller Programming Guide 입니다. 모든 포인터는 애플 공식 Game Controller Programming Guide 향 합니다. 하하. 


WWDC 2013 Session 501 Game Controller Programming Guide 을 봅니다. 그나마 낫습니다. 보기 귀찮습니다. 그래서 Document 검색을 하니 Adventure 게임 소스가 검색 됩니다. 여기서 검색하니 좋은 예제가 나옵니다. 그래서 약간 배껴서 필요없는 부분 삭제하고 예제 프로젝트를 만들어서 공유합니다. 다양하게 구현하는 방법이 있는데 아래 방법은 그냥 일부분입니다. 


0. GameController.framework 를 추가합니다.

1. 게임 시작 후, 우선 게임 콘트롤러가 연결되면 노티를 줍니다. 

2. 게임 시작전 연결된 콘트롤러가 있으면 따로 처리합니다. 

3. 알아서 상하좌우, 다양한 버튼 등등의 구현을 합니다. 


삽질 한번 한 것이. 게임 콘트롤러가 연결되면 무조건 노티를 주는줄 알았습니다. 그게 아니여서 한참 삽질을 하고 뭔가 깨달음. 기존에 연결된 콘트롤러가 있으면 따로 구현을 해야한다는 것. 


게임 페드의 프로파일은 두 종류가 존재하며, 제가 구입한 Moga 게임 콘트롤러는 확장(Extended) 콘트롤러입니다. 아나로그 스틱이 더 있습니다. 




//
//  ViewController.m
//  GameControllerSample
//
//  Created by Steve Yeom on 12/23/13.
//  Copyright (c) 2013 Appilogue. All rights reserved.
//

#import "ViewController.h"
#import <GameController/GameController.h>

@interface ViewController ()
  @property (nonatomic, strong) UILabel *label;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
  self.label = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 200, 50)];
  _label.text = @"Test String";
  [self.view addSubview:_label];
  [self configureGameControllers];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Game Controllers
- (void)configureGameControllers {
  // 노티피 케이션 센터에서 연결되거나 끊겼을 경우 노티를 받는다.
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(gameControllerDidConnect:) name:GCControllerDidConnectNotification object:nil];
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(gameControllerDidDisconnect:) name:GCControllerDidDisconnectNotification object:nil];

  // 현재 미리 연결된 상태의 콘트롤러를 설정한다.
  [self configureConnectedGameControllers];

  // 블루투스로 연결된 것이 있으면 시작한다. 이건 현재 거의 쓸모 없음. 콘트롤러가 없음.
  [GCController startWirelessControllerDiscoveryWithCompletionHandler:^{
    NSLog(@"Finished finding controllers");
  }];
}

- (void)configureConnectedGameControllers {
  // First deal with the controllers previously set to a player.
  for (GCController *controller in [GCController controllers]) {
    [self configureController:controller];
  }
}

- (void)gameControllerDidConnect:(NSNotification *)notification {
  GCController *controller = notification.object;
  NSLog(@"Connected game controller: %@", controller);

  [self configureController:controller];
}

- (void)gameControllerDidDisconnect:(NSNotification *)notification {
  GCController *controller = notification.object;

  NSLog(@"Disconnected game controller: %@", controller);
}

- (void)configureController:(GCController *)controller  {
  NSLog(@"Assigning %@", controller.vendorName);

  GCControllerDirectionPadValueChangedHandler dpadMoveHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) {
    if ( xValue < 0) {
      _label.text = @"left";
    }
    if (xValue > 0) {
      _label.text = @"right";
    }
    if (yValue > 0) {
      _label.text = @"up";
    }
    if (yValue < 0) {
      _label.text = @"down";
    }
  };

  // Use either the dpad or the left thumbstick to move the character.
  controller.extendedGamepad.rightThumbstick.valueChangedHandler = dpadMoveHandler;
  controller.extendedGamepad.leftThumbstick.valueChangedHandler = dpadMoveHandler;
  controller.gamepad.dpad.valueChangedHandler = dpadMoveHandler;

  GCControllerButtonValueChangedHandler fireButtonHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
    if ([button isEqual:controller.gamepad.buttonA]) {
      _label.text = @"Button A";
    }
    if ([button isEqual:controller.gamepad.buttonB]) {
      _label.text = @"Button B";
    }
    if ([button isEqual:controller.gamepad.buttonY]) {
      _label.text = @"Button Y";
    }
    if ([button isEqual:controller.gamepad.buttonX]) {
      _label.text = @"Button X";
    }
    if ([button isEqual:controller.gamepad.leftShoulder]) {
      _label.text = @"Button leftShoulder";
    }
    if ([button isEqual:controller.gamepad.rightShoulder]) {
      _label.text = @"Button rightShoulder";
    }
    if ([button isEqual:controller.extendedGamepad.rightTrigger]) {
      _label.text = @"Button rightTrigger";
    }
    if ([button isEqual:controller.extendedGamepad.leftTrigger]) {
      _label.text = @"Button leftTrigger";
    }
  };

  controller.gamepad.buttonA.valueChangedHandler = fireButtonHandler;
  controller.gamepad.buttonB.valueChangedHandler = fireButtonHandler;
  controller.gamepad.buttonX.valueChangedHandler = fireButtonHandler;
  controller.gamepad.buttonY.valueChangedHandler = fireButtonHandler;
  controller.gamepad.leftShoulder.valueChangedHandler = fireButtonHandler;
  controller.gamepad.rightShoulder.valueChangedHandler = fireButtonHandler;
  controller.extendedGamepad.rightTrigger.valueChangedHandler = fireButtonHandler;
  controller.extendedGamepad.leftTrigger.valueChangedHandler = fireButtonHandler;
}

@end


위 코드를 복사 붙여넣기 하고 콘트롤러에 연결해서 테스트 하면, 상하좌우, 각각의 버튼을 누르면 레이블에 뭘 눌렀는지 나옵니다. 잘 수정해서 구현하면 될 것 같습니다. 드래곤 라이더에도 살짝 추가해봤는데 잘 되네요! :-)


자, 이제 마음 놓고 게임을 해도 되겠네요. :-) 


반응형