GithubHelp home page GithubHelp logo

jinios / swift-cardgameapp Goto Github PK

View Code? Open in Web Editor NEW

This project forked from code-squad/swift-cardgameapp

0.0 0.0 0.0 12.53 MB

솔리테어 카드게임앱 - 코드스쿼드 미션 (2018.04 - 2018.05)

Swift 100.00%

swift-cardgameapp's Issues

animation complete후 모델이 제대로 업데이트되지 않는 문제

image

  • 그림에서 보면 맞는 위치에 드래그 후 게임 룰에 맞게 뷰가 옮겨진 것을 알 수 있음 ( A♥️, 9♦️)
  • 하지만 원래 위치에있던 카드모델이 제거되지 않았기때문에 뷰를 reload하면서 원래 위치에도 또 뷰가 그려짐
  • 바뀐 위치에 있는 카드뷰는 movableView로 removeFromSuperView되어야 하는 대상임.
  • 모델 업데이트하는 부분 수정하여 뷰와 싱크 맞추기
  • CardGameManager.ruleCheck()

Step3 PR 코멘트

  • CardStack 속성 Private으로 지정하고 Stack을 ViewController에서 사용할때 관리하는 객체 분담해보기
From JK:
- private 에서 다시 public으로 바뀐건가요? 여기에 접근하는 경우가 있다면 메소드를 만들어서 해결하는 방법을 고려해보세요.
- 여기서 사용하는 stacks 자체를 별도 객체로 만드는 건 어떨까요?
- 객체 역할과 책임에서 상위 객체에 있는 코드를 하위 객체에게 좀 더 위임해도 좋을 것 같습니다.

더블탭과 카드게임 룰 적용

  • 만약 A카드인 경우 왼쪽 상단의 비어있는 칸으로 UIImageView를 animate 시킨다.
    • 기존에 다른 A카드가 있으면 그 옆으로 이동한다.
  • K카드인 경우 스택 중에서 좌측부터 빈 칸이 있으면 빈 칸으로 이동시킨다.
  • 나머지 2이상 카드인 경우 왼쪽 상단에 같은 모양의 A가 있는 경우는 그 위로 이동시킨다.
  • 상단으로 이동할 수 없는 경우, 스택 중에서 좌측부터 앞면으로 된 카드 중 가장 위에 있는 카드와 다음 조건을 확인하고 조건에 맞으면 그 위로 이동시킨다.
    • 숫자가 하나 큰 카드가 있는지 확인한다. ex) 터치한 카드가 2인 경우 3, 10인 경우 J
    • 모양의 색이 다른지 확인한다. ex) 터치한 카드가 ♠️♣️ 이면 ♥️♦️
  • 스택에서 마지막 카드가 다른 곳으로 이동한 경우 다시 마지막 카드를 앞면으로 뒤집는다

availableFrame()의 리턴값이 CGPoint(x:0.0, y:0.0)인 문제

  • drag가 끝난지점부터 toPoint까지 animate시키는 부분에서 카드가 (0,0)위치로 animate됐다가 돌아오는 현상.
  • 원인1 : FrameCalculator.availableFrame()에서 toPoint가 (0,0)으로 리턴
  • 원인2 : ViewController의 toInfo()에서 MoveInfo의 index가 nil로 리턴

* toPoint: cardStack(or foundation)까지 카드가 옮겨질 딱 맞는 위치

deckView에서 카드를 드래그했을때 toInfo()리턴값이 nil인 문제

  • 문제상황: deckView에서 카드를 드래그했을때 앱이 종료됨
  • 원인:
    • 드래그가 끝난 지점인 currentFrame을 rootView기준으로 변환하면 nil이 리턴됨
    • nil로 값이 할당된 toInfo: MoveInfo로 rule을 체크하려고 하면 에러발생
  • 해결: rootView기준으로 origin을 변환할때 deckView에서 움직인 방향을 고려해서 변환하기

Stack카드들이 드래그로 움직였을때 도착지점(y 위치)

  • 출발 - 도착 지점이 stack - stack인 경우 y포지션이PositionY.upper.value
  • 이때 움직이는 movableCards의 마지막카드기준으로 PositionY.upper.value가 도착지점이 되어버려서 카드스택자체가 위로 올라갔다가 다시 그려짐
  • movableCards의 첫번째 카드 기준으로 y position 잡기
    image

CardImage의 Frame에서 origin을 계산하는 객체 수정- 카드 크기만 고정

StackView들을 7개로 나누면서 Deck, Foundation, StacksView에서 카드 Frame의 origin을 계산하는 방법이 달라짐. (특히 x좌표)
특히 x좌표는 PositionX라는 enum으로 저장되어있고 모든 카드이미지의 크기또한 고정값이라 매번 CardMaker클래스에서 계산할 필요성이 없어보임.

  • 카드크기또한 PositionX, PositionY처럼 고정된 값으로 놔두고 달라진 origin값만 각 뷰에서 부여하는 방식으로 CardFrame을 초기화하는 방법이 좋을 것 같다!

Card 객체에따라 카드 이미지 만들기

<관련 요구사항>

  • Card 객체에 파일명을 매치해서 해당 카드 이미지를 return 하는 메소드를 추가한다.
  • Card 객체가 앞면, 뒷면을 처리할 수 있도록 개선한다.

DeckView에 카드가 드래그되면 카드뷰가 없어지는 문제

카드덱과 관련된 위치에 카드뷰가 드래그되면 카드뷰가 사라지는 문제

  • 카드덱에 있던 카드뷰가 다른 스택, 혹은 파운데이션으로 으로 옮겨졌는데 rule에 맞지 않아 리턴되는 경우
  • 스택에 있던 카드뷰가 카드덱으로 옮겨졌는데 다시 스택으로 돌아오는 경우
  • 이때 카드모델은 그대로 존재하지만 카드뷰만 없어지는 현상임
  • 드래그 제스쳐가 끝나거나 시작한 위치가 deck인 경우 서브뷰들을 모델대로 업데이트하는 로직이 없어서 발생하는듯

DeckManageable과 StackManageable을 합치고 CardGameDelegate클래스로 구현

<이유>

  • 카드게임이 진행되기위해서는 카드 52장이 있는 하나의 카드덱으로 stack과 deck을 구성해서 게임을해야한다.
  • 지금처럼 DeckManageable(CardDeckDelegate)와 StackManageable(CardGameDelegate)을 에서 따로 cardDeck을 가지고있으면 한 게임에 두 카드덱이 존재하게된다.
  • 또한 현재 DeckManageable이 가진 기능이 많지 않으므로 따로 관리할 필요성이 없어서 합쳐서 게임을 총괄적으로 진행하는 모델인 CardGameDelegate하나로만 게임을 관리하기로했다.

MoveInfo에서 view가 Stack인경우 origin이 다 (0,0)인 문제

각 OneStack뷰들이 따로 나눠져있기때문에 7개의 OneStack뷰 모두 frame.origin은 (0,0)이며, PositionX enum으로 계산할 수 없다.
따라서 아래의 stackColumn() 메소드에서 column이 nil로 리턴되는 문제까지 연쇄적으로 일어난다.

// FrameCalculator.swift
    func stackColumn(originX: CGFloat) -> Int? {
        for x in PositionX.allValues {
            guard x.value == originX else { continue }
            return x.hashValue
        }
        return nil
    }

MoveInfo의 view가 Stack인경우, 드래그액션이 시작된 OneStack이 어떤 스택인지(origin.x값으로 알 수 있도록) 계산하는 로직을 추가한다.

1~7장의 카드가 있는 CardStack 표시

  • CardDeck 객체에서 랜덤으로 카드를 섞고, 출력 화면처럼 카드스택 형태로 보이도록 개선한다.
  • 카드스택을 관리하는 모델 객체를 설계한다.
  • 각 스택의 맨위의 카드만 앞카드로 뒤집는다.
  • 앱에서 Shake 이벤트를 발생하면 랜덤 카드를 다시 섞고 처음 상태로 다시 그리도록 구현한다.

subclass CardImageView의 사이즈는 속성으로 고정하고 VC에서 origin만 부여하여 생성하는 방법

Q. 어차피 카드 이미지의 크기는 모두 똑같고, 계산해놓은 카드 이미지 사이즈을 알 수 있기 때문에 CardImageView에 속성을 지정해놓은것처럼 사이즈도 fix시키고, VC에서는 origin만 알려주고 생성하면 더 효율적이지 않을까?

<예상되는 문제점>

  • 지금은 cardSize라는 computed property가 VC에 있기때문에, VC의 루트 뷰 frame 기준으로 카드의 가로, 세로 길이를 구한 것을 코드만 봐도 알 수 있다. 하지만 만약 이 값을 CardImageView내부에서 바로 상수로쓰면, 다른 사람은 이 값이 어떻게 구해진건지 알 수 없다.
  • 또한 루트뷰에 추가되는 서브뷰이므로 사이즈를 계산하고 부여하는게 VC에서 바로 볼 수 있는게 더 자연스러울 수도 있다.
  • 또한 만약 디바이스가 변경된다면 루트뷰의 frame이 달라지기때문에 상수로 선언한 카드사이즈가 다른 디바이스 뷰 상에서는 맞지 않을 수 있다.
  • 매번 subView의 크기를 루트뷰의 frame에 따라 계산해야한다면, subView에서는 superView의 frame을 알아와서 계산하고, 계산한 값을 init()내부에서 size로 fix할 수 있는지? 만약 가능하다면 이 방법이 자연스러운건지?_?

CGRect의 contains() 기능 확장

해당 CGRect내부에 CGPoint가 있는지 확인하는 메소드 구현하기

  • 해당 CGPoint가 어떤 뷰(CardDeck, Stacks, Foundation view중 1)인지 리턴

싱글탭이벤트 처리 flow변경

  • 현재는 DeckView내부에서 모두처리하므로 view내에 로직도 들어있는 상태임
  • 더블탭 처리flow처럼
    • DeckView에서 이벤트 받음 - CardGameDelegate에게 Notify - Deck담당 Model에게 로직실행 - 로직 실행으로 인해 변경된 상태 VC에 Notify - DeckView에게 redraw호출 로 변경할 것

CardGameDelegate클래스를 싱글톤으로 구현

  • Deck, Foundation, StacksView, OneStack 클래스에서 모두 CardGameDelegate(CardGameManageable)가 필요함.
  • 현재 상위모듈에서 하위모듈을 초기화할때 매번 객체를 넘겨주는 방식인데, 한 게임 당 하나의 CardGameDelegate가 필요하고 모든 뷰는 그 객체를 공유하면서 프로그램을 진행해야함
  • 매번 서브뷰를 초기화할때마다 객체를 넘기는 것이 아니라 싱글톤으로 만드는 것이 더 효율적임

currentFrames값을 RootView기준으로 converting하기

  • 드래그 액션이 다 끝난 지점을 뜻하는 currentFrame
  • currentFrame은 movableViews의 원래 superView기준으로 나온다 (OneStack or FoundationView)
  • RootView의 origin기준으로 변환하여 isInside(point:)를 파악한다.

CardDeck과 GameTable을 표현하는 뷰 만들기

  • CardDeck 인스턴스를 만들고 랜덤으로 카드를 섞고 출력 화면처럼 보이도록 개선한다.
  • 화면 위쪽에 빈 공간을 표시하는 UIView를 4개 추가하고, 우측 상단에 UIImageView를 추가한다.
    • 상단 화면 요소의 y 좌표는 20pt를 기준으로 한다.
    • 7장의 카드 이미지 y 좌표는 100pt를 기준으로 한다.
  • 앱에서 Shake 이벤트를 발생하면 랜덤 카드를 다시 섞고 다시 그리도록 구현한다.

우측 상단에 Stack에 표시한 카드 제외한 나머지를 CardDeck으로표시

  • 카드스택에 표시한 카드를 제외하고 남은 카드를 우측 상단에 뒤집힌 상태로 쌓아놓는다.
  • 맨위에 있는 카드를 터치하면 좌측에 카드 앞면을 표시하고, 다음 카드 뒷면을 표시한다.
  • 만약 남은 카드가 없는 경우는 우측에도 빈 카드를 대신해서 반복할 수 있다는 이미지(refresh)를 표시한다.

드래그 앤 드롭 - UIPanGestureRecognizer의 .ended구현

(이미 사용자가 뷰 내에서 원하는 곳까지 드래그를 마친 상태. 뷰만 옮겨져있음)

.ended 일때의 로직 flow

  • 카드위치 확인 - movableViews의 마지막 위치가 toFrame위치 내부에 진입했는지확인
    • (toFrame 값의 origin에서 오른쪽/하향 방향으로 카드 가로세로 위치 내부인지 확인)
  • 모델에서 확인 - 해당 toFrame에 현재 movable cards들이 위치할 수 있는지
  • 애니메이션적용 - 모델에서 확인한 값이 true이면 사용자가 드래그를 놓은 위치에서 카드스택의 맞는 위치까지 animation적용

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.