[swift2.1] Swiftris - swift로 만드는 테트리스

Swift 2015. 12. 29. 22:18

Swiftris는 Swift 언어 버전의 iOS 테트리스 게임입니다. Swift 언어 학습을 위해 개발되었으며 완전한 소스는 GitHub 페이지에서 확인하실 수 있습니다. 간단하지만 임팩트 있는 앱을 만들면서 Swift를 재미있게 공부해보세요.



1. Swiftris 영상








2. 게임조작

  • Play: play 버튼 터치.
  • Pause: pause 버튼 터치.
  • Stop: stop 버튼 터치.

  

  • Move Left: 벽돌의 왼쪽 영역 터치.
  • Move Right: 벽돌의 오른쪽 영역 터치.
  • Rotate : 벽돌의 상단 영역 터치.
  • Drop: 화면 롱 터치.



3. 소스코드 저장소




4. 클래스 구조


  • ViewController.swift
  • Swiftris.swift
  • GameView.swift
    • GameBoard.swift
    • GameScore.swift
    • NextBrick.swift
    • Brick.swift
  • GameTimer.swift
  • SoundManager.swift


GameBoard

  • GameBoard는 22행 x 10열로 구성된 UIColor의 이차원 배열입니다.
class GameBoard: UIView {
    static let rows = 22
    static let cols = 10

    ...
    var board = [[UIColor]]()
    ...
}




Brick

  • 벽돌은 모양을 본따 I, J, L, T, Z, S, O 로 7가지 종류가 있습니다.
  • 벽돌종류는 고유의 색을 가진 enum 타입으로 정의됩니다.
enum BrickType {
    case I(UIColor)
    case J(UIColor)
    case L(UIColor)
    case T(UIColor)
    case Z(UIColor)
    case S(UIColor)
    case O(UIColor)
}  

class Brick: NSObject {

    ...
    static var bricks = [
        BrickType.I(UIColor(red:0.40, green:0.64, blue:0.93, alpha:1.0)),
        BrickType.J(UIColor(red:0.31, green:0.42, blue:0.80, alpha:1.0)),
        BrickType.L(UIColor(red:0.81, green:0.47, blue:0.19, alpha:1.0)),
        BrickType.T(UIColor(red:0.67, green:0.45, blue:0.78, alpha:1.0)),
        BrickType.Z(UIColor(red:0.80, green:0.31, blue:0.38, alpha:1.0)),
        BrickType.S(UIColor(red:0.61, green:0.75, blue:0.31, alpha:1.0)),
        BrickType.O(UIColor(red:0.88, green:0.69, blue:0.25, alpha:1.0))
    ]
    ...    
}




Swiftris

  • 게임로직과 인터렉션 처리.
class Swiftris: NSObject {

    ...

    // 터치 - 벽돌 왼쪽,오른쪽 이동, 벽돌 드랍 
    func touch(touch:UITouch!) {
        guard self.gameState == GameState.PLAY else { return }
        guard let curretBrick = self.gameView.gameBoard.currentBrick else { return }

        let p = touch.locationInView(self.gameView.gameBoard)

        let half = self.gameView.gameBoard.centerX

        let top  = curretBrick.top()
        let topY = CGFloat( (Int(top.y) + curretBrick.ty) * GameBoard.brickSize )

        if p.y > topY  {
            if p.x > half {
                self.gameView.gameBoard.updateX(1)
            } else if p.x < half {
                self.gameView.gameBoard.updateX(-1)
            }
        } else   {
            self.gameView.gameBoard.rotateBrick()
        }
    }

    // 롱프레스 - 벽돌 드랍 
    func longPressed(longpressGesture:UILongPressGestureRecognizer!) {
        if self.gameState == GameState.PLAY {

            if longpressGesture.state == UIGestureRecognizerState.Began {
                self.gameView.gameBoard.dropBrick()
            }
        }
    }

}


GameScore

  • 게임점수는 클리어되는 라인수에 따라 10점, 30점, 60점, 100점이 지급됩니다.
  • 예제에서는 레벨클리어 기능을 제공하지 않았지만, 자신만의 레벨클리어 기능을 구현해보세요.

class GameScore: UIView {

    ...
    var scores = [0, 10, 30, 60, 100]  

    func lineClear(noti:NSNotification!) {
        if let userInfo = noti.userInfo as? [String:NSNumber] {
            if let lineCount = userInfo["lineCount"] {
                self.lineClearCount += lineCount.integerValue
                self.gameScore += self.scores[lineCount.integerValue]
                self.update()
            }
        }
    }

    ...
}





NextBrick

  • 게임 play중 다음으로 사용할 수 있는 벽돌 3개를 미리 볼수 있습니다.


class Brick: NSObject {
    ...
    static var nextBricks = [Brick]()
    static var nextBrickCount = 3

    // 벽돌 대기열에서 첫번째(index 0) 벽돌을 사용하고, 대기열을 3개로 채웁니다.
    static func generate() -> Brick! {
        while self.nextBricks.count < self.nextBrickCount {
            self.nextBricks.append(self.newBrick())
        }
        let brick = self.nextBricks.removeAtIndex(0)
        self.nextBricks.append(self.newBrick())
        return brick
    }
    ...

}



SoundManager

  • 게임의 생생함을 더하기 위해 몇가지 효과음을 제공합니다.
  • 게임 배경음, 벽돌 떨어지는음, 게임오버음.
class SoundManager: NSObject {

    var bgmPlayer:AVAudioPlayer?
    var effectPlayer:AVAudioPlayer?
    var gameOverPlayer:AVAudioPlayer?
    ...
}



5. 피드백






  • 이이이 2016.01.27 14:26 ADDR 수정/삭제 답글

    블로그를 이리저리 둘러 보며 정말 많은걸 배우고 갑니다 정말정말 감사합니다