본문 바로가기
IT/swift

100 days of SwiftUI - Day34

by 가능성1g 2024. 11. 29.
반응형

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

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

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()
}

 

무언가 멋진데!

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

반응형