클라이언트

[GameKit] 간단한 가위바위보 멀티게임 만들기

애기공룡훈련병 2025. 2. 16. 08:15
반응형

GameKit과 SwiftUI를 활용하여 간단한 가위바위보 멀티플레이 게임을 만들어 보겠습니다. 이 튜토리얼은 단계별로 진행되며, 처음부터 끝까지 따라할 수 있도록 상세하게 설명합니다.

 

1. 프로젝트 설정하기

Xcode 프로젝트 생성

  1. Xcode를 실행하고 "Create a new Xcode project"를 선택합니다.
  2. App을 선택하고 "Next"를 클릭합니다.
  3. 프로젝트 이름을 RockPaperScissorsGame으로 설정합니다.
  4. Interface는 SwiftUI, Life Cycle은 SwiftUI App을 선택합니다.
  5. Language는 Swift로 설정하고 "Next"를 눌러 프로젝트를 생성합니다.
 

2. GameKit 설정하기

GameKit을 사용하려면 Game Center를 활성화해야 합니다.

Game Center 활성화

  1. Signing & Capabilities 탭에서 + Capability를 클릭합니다.
  2. Game Center를 검색하여 추가합니다.
  3. Background Modes도 추가하고 Background FetchRemote Notifications를 활성화합니다.
 

3. GameKit을 사용한 플레이어 인증

GameKit을 사용하려면 GKLocalPlayer를 이용해 플레이어를 인증해야 합니다.

GameViewModel.swift 생성

import Foundation
import GameKit

class GameViewModel: ObservableObject {
    @Published var isAuthenticated = false
    @Published var playerName: String = ""
    
    init() {
        authenticatePlayer()
    }
    
    func authenticatePlayer() {
        let localPlayer = GKLocalPlayer.local
        localPlayer.authenticateHandler = { vc, error in
            if let vc = vc {
                // UI에서 ViewController를 띄워야 함
            } else if localPlayer.isAuthenticated {
                DispatchQueue.main.async {
                    self.isAuthenticated = true
                    self.playerName = localPlayer.displayName
                }
            } else {
                print("Game Center 인증 실패: \(error?.localizedDescription ?? "알 수 없는 오류")")
            }
        }
    }
}

SwiftUI 뷰에서 플레이어 인증 확인

import SwiftUI

struct ContentView: View {
    @StateObject private var viewModel = GameViewModel()
    
    var body: some View {
        VStack {
            if viewModel.isAuthenticated {
                Text("환영합니다, \(viewModel.playerName)!")
            } else {
                Text("Game Center에 로그인하세요.")
            }
        }
        .padding()
    }
}
 

4. 가위바위보 게임 로직 구현

이제 기본적인 가위바위보 로직을 구현하겠습니다.

GameChoice 열거형 정의

enum GameChoice: String, CaseIterable {
    case rock = "✊"
    case paper = "✋"
    case scissors = "✌️"
    
    static func randomChoice() -> GameChoice {
        return GameChoice.allCases.randomElement()!
    }
}

게임 결과 계산

func determineWinner(playerChoice: GameChoice, opponentChoice: GameChoice) -> String {
    if playerChoice == opponentChoice {
        return "무승부!"
    }
    
    switch (playerChoice, opponentChoice) {
    case (.rock, .scissors), (.scissors, .paper), (.paper, .rock):
        return "승리!"
    default:
        return "패배..."
    }
}
 

5. 멀티플레이 기능 추가

GameKit의 GKMatchmaker를 사용하여 멀티플레이어 기능을 추가합니다.

MultiplayerManager.swift 생성

import GameKit

class MultiplayerManager: NSObject, ObservableObject, GKMatchDelegate {
    @Published var match: GKMatch?
    @Published var isMatched = false
    
    func findMatch() {
        let request = GKMatchRequest()
        request.minPlayers = 2
        request.maxPlayers = 2
        
        GKMatchmaker.shared().findMatch(for: request) { match, error in
            if let match = match {
                self.match = match
                self.isMatched = true
                match.delegate = self
            } else if let error = error {
                print("매치 찾기 오류: \(error.localizedDescription)")
            }
        }
    }
}
 

6. UI 구성

GameView.swift 생성

import SwiftUI

struct GameView: View {
    @StateObject private var multiplayerManager = MultiplayerManager()
    @State private var playerChoice: GameChoice?
    @State private var opponentChoice: GameChoice?
    @State private var result: String = ""
    
    var body: some View {
        VStack {
            Text("가위바위보 게임").font(.largeTitle)
            
            HStack {
                ForEach(GameChoice.allCases, id: \ .self) { choice in
                    Button(action: {
                        self.playerChoice = choice
                        self.opponentChoice = GameChoice.randomChoice()
                        if let player = self.playerChoice, let opponent = self.opponentChoice {
                            self.result = determineWinner(playerChoice: player, opponentChoice: opponent)
                        }
                    }) {
                        Text(choice.rawValue).font(.system(size: 50))
                    }
                }
            }
            
            if let playerChoice = playerChoice, let opponentChoice = opponentChoice {
                Text("당신: \(playerChoice.rawValue)")
                Text("상대: \(opponentChoice.rawValue)")
                Text(result).font(.title)
            }
        }
    }
}
 

7. ContentView에서 게임 실행

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink("멀티플레이어 게임 시작", destination: GameView())
            }
        }
    }
}

 

 

반응형