IT/swift

100 days of SwiftUI - Day34

가능성1g 2024. 11. 29. 22:44
반응형

역시 마지막 프로젝트는 실전! 

이전 개발한 깃발 맞추기에 애니메이션을 추가하는거다

1. 선택한 깃발 회전시키기

2. 선택 안한 깃발 0.25 투명화

3. 선택 안한 깃발에 무언가 애니메이션 넣기 ( 난 스무스하게 바뀌게 했다 )

//
//  ContentView.swift
//  GuessTheFlag
//
//  Created by HanTJ on 11/18/24.
//

import SwiftUI

struct ContentView: View {
    @State private var showingScore = false
    @State private var gameEnd = false
    @State private var scoreTitle = ""
    @State private var flagTappedName = ""
    
    @State private var countries = ["Estonia", "France", "Germany", "Ireland", "Italy", "Nigeria", "Poland", "Spain", "UK", "Ukraine", "US"].shuffled()
    @State private var correctAnswer = Int.random(in:0...2)
    
    @State private var score: Int = 0
    
    @State private var gameCount = 0
    
    @State private var isSpinning = [Bool](repeating:false, count:3) //배열초기화 하기!
    @State private var opacity = [Double](repeating:1.0, count:3)
    
    var body: some View {
        ZStack{
//            LinearGradient(colors: [.blue, .black], startPoint: .top, endPoint: .bottom)
//                .ignoresSafeArea()
            RadialGradient(stops: [
                .init(color: Color(red: 0.1, green: 0.2, blue: 0.45), location: 0.3),
                .init(color: Color(red: 0.76, green: 0.15, blue: 0.26), location: 0.3)
            ], center: .top, startRadius: 200, endRadius: 400)
            .ignoresSafeArea()
            
            VStack {
                Spacer()
                Text("Guess The Flag")
                    .font(.largeTitle.bold())
                    .foregroundColor(.white)
                
                VStack(spacing: 15) {
                    VStack {
                        Text("Tap the flag of")
                            .font(.subheadline.weight(.heavy))
                            .foregroundStyle(.white)
                        
                        Text(countries[correctAnswer])
                            .font(.largeTitle.weight(.semibold))
                            .foregroundStyle(.white)
                    }
                    
                    ForEach(0..<3) { number in
                        Button {
                            flagTapped(number)
                        } label: {
                            FlagImage(flagName: countries[number])
                                .rotationEffect(.degrees(isSpinning[number] ? 360:0))
                                .opacity(opacity[number])
                                .animation(.easeInOut(duration: 2), value: opacity[number])
                               
                            /*
                            Image(countries[number])
                                .clipShape(.capsule)
                                .shadow(radius: 5)
                             */
                        }
                        
                    }
                }
                Spacer()
                Spacer()
                Text("Score: \(score)")
                    .foregroundStyle(.secondary)
                    .font(.title.bold())
                Spacer()
            }
            .frame(maxWidth: .infinity)
            .padding(.vertical, 20)
            .background(.regularMaterial)
            .clipShape(.rect(cornerRadius: 20))
            .padding()
        }
        .alert(scoreTitle, isPresented: $showingScore) {
            Button("Continue", action: askQuestion)
        } message: {
            if scoreTitle == "Wrong" {
                Text("Your Tapped Flag is \(flagTappedName)")
            }
            Text("Your score is \(score)")
        }
        .alert("GameEnd", isPresented: $gameEnd) {
            Button("Reset", action: resetGame )
        } message: {
            Text("Your Last score is \(score)")
        }
    }
    
    func flagTapped(_ number: Int) {
        isSpinning[number].toggle()
        //나머지 버튼은 25% 투명화
        opacity.enumerated().forEach { i, _ in
            if i != number {
                opacity[i] = 0.25
            }
        }
        gameCount += 1
        if number == correctAnswer {
            scoreTitle = "Correct"
            score += 100
        } else {
            scoreTitle = "Wrong"
            flagTappedName = countries[number]
        }
        if gameCount < 8 {
            showingScore = true
        } else {
            gameEnd = true
        }
    }
    
    func askQuestion() {
        countries.shuffle()
        correctAnswer = Int.random(in: 0...2)
        //투명도 원복
        opacity = [Double](repeating:1.0, count:3)
    }
    
    func resetGame() {
        score = 0
    }
}

struct FlagImage: View {
    var flagName:String
    
    var body: some View {
        Image(flagName)
            .clipShape(.capsule)
            .shadow(radius: 5)
    }
}

#Preview {
    ContentView()
}

 

무언가 멋진데!

그런데 선택한놈이 바뀔땐 훅 바뀌니 이상하군.. 

반응형