반응형
LinkedIn 개발자로 성장하면서 남긴 발자취들을 확인하실 수 있습니다.
Github WWDC Student Challenge 및 Cherish, Tiramisul 등 개발한 앱들의 코드를 확인하실 수 있습니다.
개인 앱 : Cherish 내 마음을 들여다보는 시간, 체리시는 디자이너와 PM과 함께 진행 중인 1인 개발 프로젝트입니다.
10년 후, 20년 후 나는 어떤 스토리 텔러가 되어 있을지 궁금하다. 내가 만약에 아직 조금 더 탐구하고 싶은 게 있고, 궁금한 게 있다면, 그게 설사 지금 당장의 내 인생에 도움이 안 되는 것 같더라도 경험해보자. 그 경험들을 온전히 즐기며 내 것으로 만들고, 내 일에 녹여내고... 그러다보면 그 점들이 모여 나란 사람을 그려내는 선이 될 테니까.

Recent Posts
Recent Comments
Total
관리 메뉴

꿈꾸는리버리

슬롯 머신 구현하기 본문

오뚝이 개발자/SwiftUI

슬롯 머신 구현하기

rriver2 2024. 4. 17. 17:32
반응형

프로젝트하다가 사용하게 된 슬롯머신 구현!!!

생각보다 재밌었고,, 재밌었고 뿌듯했다 !! ㅎㅎ,,

 

 🍀 결과물 

 

 

lastRolledMachineCount은 슬롯을 돌릴 숫자이다. 이건 선호에 맞게 바꿔서 쓰면 된다.

그리고 finalNumberList는 마지막에 보여주고자 하는 숫자의 리스트이다. 나는 [3,4,5]로 돌렸는데, 만약에 [1,5,2,6,4]를 넣으면 5개의 박스가 돌아가고 마지막에 1,5,2,6,4 순서대로 초록박스가 공개된다!

 🍀 고민 Point 

처음에 어떻게 만들지.. 할 때는 ScrollView가 생각났다. ScrollView로 구현하고 위 아래를 막아서 일부만 보여주면 될 것 같다는 생각.

그래서 ScrollView에서 버튼을 눌렀을 때 ScrollView가 스크롤 되게 구현했다. 자동으로 스크롤때 멈추는 숫자가 박스마다 다르면 자연스럽게 따로 돌아가는 느낌이 날 것 같아서 숫자를 랜덤으로 불러오게 했다. 그리고 ScrollView 위로 frame 크기를 세워서 일부만 보이도록 하게 했다. lastRolledMachineCount와 rolledMachineCount(현재 돌아간 숫자)가 같다면, 그때는 finalNumberList에 해당하는 숫자를 박스에 보여주고, 배경을 초록색으로 바꾼다.

 

이렇게 하니까 얼추 비쥬얼은 완료가 되었다.

 

그리고 마지막으로는 버튼을 삭제하고, timer를 설정해서 0.7초마다  머신이 자동으로 돌아가게 했다. 

 

 🍀 코드 

struct SlotMachineView: View {
    
    @State private var finalNumberList: [Int]
    @State private var rolledMachineCount: Int = 0
    @State private var timer: Timer?
    
    @State private var isFinished: Bool = false
    
    /// 슬롯머신을 자동으로 돌릴 횟수
    private let lastRolledMachineCount = 4
    
    init(finalNumberList: [Int]) {
        self.finalNumberList = finalNumberList
    }
    
    var body: some View {
        VStack {
            HStack {
                ForEach(finalNumberList.indices, id: \.self) { index in
                    ScrollView {
                        ScrollViewReader { proxy in
                            ForEach(0..<10) { index in
                                Text(index.description)
                                    .frame(width: 31, height: 31)
                                    .background(isFinished ? .subGreen : .gray700)
                                    .foregroundStyle(.white)
                                    .cornerRadius(4)
                                    .padding(.horizontal, 2)
                                    .padding(.vertical, 4)
                                    .id(index)
                            }
                            .onChange(of: rolledMachineCount, { _, newValue in
                                withAnimation(.spring()) {
                                    if isFinished {
                                        timer?.invalidate()
                                        proxy.scrollTo(finalNumberList[index], anchor: .center)
                                    } else {
                                        proxy.scrollTo(Int.random(in: 1..<10), anchor: .center)
                                    }
                                }
                            })
                        }
                    }
                    .frame(height: 40)
                }
            }
            .padding(.bottom, 100)
            .onAppear {
                self.timer = Timer.scheduledTimer(withTimeInterval: 0.7, repeats: true) { timer in
                    rolledMachineCount += 1
                    if rolledMachineCount == lastRolledMachineCount {
                        isFinished = true
                    }
                }
            }
        }
    }
}

#Preview {
    SlotMachineView(finalNumberList: [3,4,5])
}

 

반응형
Comments