이전에 만든 앱에서 디자인과 판 수를 설정할 수 있도록 추가해 보겠습니다.
디자인은 무료 디자인을 사용했으며 글씨같은 것은 직접 포토샵으로 만들었습니다.
(디자인이 제일 힘든 것 같습니다...)
이번에도 어련운 것은 없기 때문에 빠르게 진행해 보겠습니다.
1. Storyboard에 디자인 작성
이번에는 딱히 화면전환을 만들지 않고 그냥 그 위에 커버 뷰를 하나 생성하여 씌웠다가 표시하고 숨기고 하는 방식으로 진행하였습니다. 향후에 메인 화면 게임 화면을 구성하여 만들고 싶으신 분은 추가해서 대응하시면 될 것 같습니다.
2. 판수 설정
판을 5전 3승과 같이 설정할 수 있도록 하는 메소드를 작성해 보겠습니다.
우선 게임 스타트 버튼을 눌렀을 때 보여지고 있는 커버 뷰를 지우고 이긴 횟 수, 진 횟 수를 초기화 합니다.
그리고 판 수가 입력이 되지 않았을 시 에러 다이어로그를 표시합니다.
(현재의 어플에서는 다른 문자열의 입력값이나 등 정수형 만을 입력할 수 있는 처리는 되어 있지 않습니다.)
private func gameStart() {
guard let textField = self.stageTextField.text, !textField.isEmpty else {
let alert = UIAlertController(title: "", message: "판 수를 설정해 주십시오!", preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
return
}
self.coverView.isHidden = true
self.stage = Int(textField) ?? 0
self.winCount = 0
self.loseCount = 0
}
과반수 이상일 경우 게임을 끝내고 다시 커버 뷰를 화면에 표시합니다.
private func stageCount() {
if self.winCount > self.stage / 2 {
self.coverView.isHidden = false
self.logoImageView.image = UIImage(named: "win")
} else if self.loseCount > self.stage / 2 {
self.coverView.isHidden = false
self.logoImageView.image = UIImage(named: "lose")
}
}
3. 애니메이션 설정
컴퓨터의 가위 바위 보를 애니메이션 화 시킵니다.
애니메이션 스탑과 시작에 맞추어 결과 라벨도 표시하거나 비표시 합니다.
private func startAnimation() {
self.resultDescriptionLabel.isHidden = true
self.resultImageView.animationImages = [UIImage(named: "scissors")!,
UIImage(named: "rock")!,
UIImage(named: "paper")!]
self.resultImageView.animationDuration = 0.5
self.resultImageView.startAnimating()
}
private func stopAnimation() {
self.resultDescriptionLabel.isHidden = false
self.resultImageView.stopAnimating()
}
4. 완성 코드
import UIKit
class ViewController: UIViewController {
/// Enum Properties
enum ResultState: String {
case win = "win"
case draw = "draw"
case lose = "lose"
}
enum SRPState {
case scissors
case rock
case paper
var num: Int {
switch self {
case .scissors: return 0
case .rock: return 1
case .paper: return 2
}
}
}
/// IBOutlet Properties
@IBOutlet weak var resultImageView: UIImageView!
@IBOutlet weak var resultDescriptionLabel: UILabel!
@IBOutlet weak var scissors: UIButton!
@IBOutlet weak var rock: UIButton!
@IBOutlet weak var paper: UIButton!
@IBOutlet weak var coverView: UIView!
@IBOutlet weak var stageTextField: UITextField!
@IBOutlet weak var logoImageView: UIImageView!
/// Properties
var winCount = 0
var loseCount = 0
var stage: Int = 0
/// Override Methods
override func viewDidLoad() {
super.viewDidLoad()
self.initView()
}
private func initView() {
self.stageTextField.delegate = self
}
/// IBAction Methods
@IBAction func didTappedScissors(_ sender: UIButton) {
self.startProcessing(.scissors)
}
@IBAction func didTappedRock(_ sender: UIButton) {
self.startProcessing(.rock)
}
@IBAction func didTappedPaper(_ sender: UIButton) {
self.startProcessing(.paper)
}
@IBAction func didTappedStartButton(_ sender: UIButton) {
self.gameStart()
}
}
/// MARK:- Process
extension ViewController {
/// 결과 출력
///
/// Parameters:
/// input - 입력한 데이터 값
private func startProcessing(_ input: SRPState) {
guard let computerOutput = self.computingState() else {
print("return value is nil")
return
}
switch input {
case .scissors:
switch computerOutput {
case .scissors: self.resultDescriptionLabel.text = ResultState.draw.rawValue
case .rock:
self.resultDescriptionLabel.text = ResultState.lose.rawValue
self.loseCount += 1
case .paper:
self.resultDescriptionLabel.text = ResultState.win.rawValue
self.winCount += 1
}
case .rock:
switch computerOutput {
case .scissors:
self.resultDescriptionLabel.text = ResultState.win.rawValue
self.winCount += 1
case .rock: self.resultDescriptionLabel.text = ResultState.draw.rawValue
case .paper:
self.resultDescriptionLabel.text = ResultState.lose.rawValue
self.loseCount += 1
}
case .paper:
switch computerOutput {
case .scissors:
self.resultDescriptionLabel.text = ResultState.lose.rawValue
self.loseCount += 1
case .rock:
self.resultDescriptionLabel.text = ResultState.win.rawValue
self.winCount += 1
case .paper: self.resultDescriptionLabel.text = ResultState.draw.rawValue
}
}
self.stopAnimation()
self.stageCount()
}
/// 컴퓨터의 결과 처리
///
private func computingState() -> SRPState? {
let computingValue = Int.random(in: 0...2)
switch computingValue {
case SRPState.scissors.num:
self.resultImageView.image = UIImage(named: "scissors")
return .scissors
case SRPState.rock.num:
self.resultImageView.image = UIImage(named: "rock")
return .rock
case SRPState.paper.num:
self.resultImageView.image = UIImage(named: "paper")
return .paper
default:
return nil
}
}
/// 판 수 설정
///
private func stageCount() {
if self.winCount > self.stage / 2 {
self.coverView.isHidden = false
self.logoImageView.image = UIImage(named: "win")
} else if self.loseCount > self.stage / 2 {
self.coverView.isHidden = false
self.logoImageView.image = UIImage(named: "lose")
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
self.startAnimation()
}
}
/// 게임 시작
///
private func gameStart() {
guard let textField = self.stageTextField.text, !textField.isEmpty else {
let alert = UIAlertController(title: "", message: "판 수를 설정해 주십시오!", preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
return
}
self.coverView.isHidden = true
self.stage = Int(textField) ?? 0
self.winCount = 0
self.loseCount = 0
self.startAnimation()
}
/// 애니메이션 시작
///
private func startAnimation() {
self.resultDescriptionLabel.isHidden = true
self.resultImageView.animationImages = [UIImage(named: "scissors")!,
UIImage(named: "rock")!,
UIImage(named: "paper")!]
self.resultImageView.animationDuration = 0.5
self.resultImageView.startAnimating()
}
/// 애니메이션 스탑
///
private func stopAnimation() {
self.resultDescriptionLabel.isHidden = false
self.resultImageView.stopAnimating()
}
}
/// MARK:- UITextField Delegate
extension ViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
5. 실행 하기
이렇게 해서 가위 바위 보 게임을 마치겠습니다.
추가로 몇 가지 기능을 추가하시고 싶으신 분은 다양하게 활용하셔서 추가하시면 될 것 같습니다.
(난이도 설정이나 버그 방지를 위한 에러 처리 등)
감사합니다.
환경
Xcode 11.3.1
swift 5
'Swift > 데모 개발' 카테고리의 다른 글
[Swift] 아날로그 시계 어플을 만들어보자! (0) | 2020.06.01 |
---|---|
[Swift] 달력 App 만들어보기 (4) | 2020.04.27 |
[Swift] 가위 바위 보 게임 만들기 - Step 1 (0) | 2020.04.05 |
[Swift] StopWatch 만들어보기 - Step 2 (0) | 2020.03.07 |
[Swift] StopWatch 만들어보기 - Step 1 (0) | 2020.03.07 |