이코노딩

[Flutter Project] 벌칙 모드 구현하기 본문

프로젝트/애미티

[Flutter Project] 벌칙 모드 구현하기

떼이로 2023. 3. 23. 18:09

✔️ 게임 진행에 재미를 위해 벌칙모드를 만들기로 했다.

 

✅구상 기능

1️⃣벌칙모드를 끄고 킬수 있는 스위치

2️⃣벌칙이 무엇인지 볼 수 있는 바텀시트 및 리스트

3️⃣벌칙을 추가하거나 삭제 할 수 있는 기능

4️⃣기본 벌칙 리스트로 초기화 할 수 있는 리스트

5️⃣shared_preference로 종료후에도 계속 저장 될 수 있는 기능

6️⃣벌칙모드를 키고 게임 오버시 리스트 중 랜덤한 벌칙 지정

 

✅ 구현하기

 

1️⃣벌칙모드를 끄고 킬수 있는 스위치

☑️Code

Widget penaltySetting(){
    return Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
           Icon(Icons.auto_awesome, color: const Color(0xffaecdff), size: 24.r,),
           SizedBox(width: 10.w,),
           Text('벌칙 모드', style: TextStyle(fontSize: 16.sp),),
          Obx(()=>
              Row(
                children: [
                  IconButton(
                      onPressed: () => Get.put(PenaltyController()).penaltyInfo(),
                      icon:  Icon(Icons.question_mark_rounded, size: 24.r,color: const Color(0xffaecdff),) ),
                  Padding(
                      padding:  EdgeInsets.all(16.r),
                      child: Switch(
                        activeColor: const Color(0xffaecdff),
                        onChanged: (bool value) {
                          changePenalty(value);
                        },
                        value: penaltyMode.value,
                      )
                  ),
                ],
              ),
          ),
        ]);
  }

 

기본 지원되는 위젯 중 Switch Widget 을 사용하고 옆에

IconButton을 이용해 벌칙모드 설정 페이지로 라우팅되게 구현 하였다.

 

2️⃣벌칙이 무엇인지 볼 수 있는 바텀시트 및 리스트

3️⃣벌칙을 추가하거나 삭제 할 수 있는 기능

4️⃣기본 벌칙 리스트로 초기화 할 수 있는 리스트

☑️Code

void penaltyInfo() {
    Get.bottomSheet(
      isScrollControlled: true,
            WillPopScope(
              onWillPop: (){
                if(customizing.value){
                  Get.put(DialogController()).customAlert('저장 후 나가주세요.');
                }else{
                  Get.back();
                }
                return Future(() => false);
              },
              child: SingleChildScrollView(
                physics: const ScrollPhysics(),
                child: Container(
                  padding: EdgeInsets.fromLTRB(16.w, 16.h, 16.w, 0),
                  height: Get.height * 0.8,
                  decoration: const BoxDecoration(
                    color: Colors.white,
                    border: Border(
                      top: BorderSide(
                          color: Color(0xffaecdff), width: 5
                      ),
                      left: BorderSide(
                          color: Color(0xffaecdff), width: 5
                      ),
                      right: BorderSide(
                          color: Color(0xffaecdff), width: 5
                      ),
                    ),
                  ),
                  child: Obx( ()=> Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                               Text('벌칙모드란 ?', style: TextStyle(fontSize: 24.sp,fontWeight: FontWeight.bold, fontFamily: 'OneTitle'),),
                              IconButton(
                                icon:  Icon(Icons.cancel, size: 40.r, color: const Color(0xffaecdff),),
                                onPressed: () {
                                  if(customizing.value){
                                    Get.put(DialogController()).customAlert('저장 후 나가주세요.');
                                  }else{
                                    Get.back();
                                  }
                                },
                              )
                            ],
                          ),
                          Padding(padding:  EdgeInsets.only(bottom: 15.h),
                            child: Divider(
                              endIndent: Get.width/2,
                              thickness: 1,
                              color: const Color(0xff6c6c6c),
                            ),),
                           Text('게임 오버 시 아래 리스트 중\n벌칙이 랜덤하게 생성되요.',style: TextStyle(fontSize: 18.sp),),
                          Align(
                            alignment: Alignment.topRight,
                            child: SizedBox(height: 50.h,
                              child: Row(
                                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                children: [
                                  Row(
                                    children: [
                                      Text('${Get.put(PenaltyController()).showList.length} 개',style:  TextStyle(fontSize: 18.sp, fontWeight: FontWeight.bold, color: Colors.blueAccent,),),
                                       SizedBox(width: 10.w,),
                                      Visibility(
                                        visible: Get.put(PenaltyController()).customizing.value,
                                        child: TextButton(onPressed: (){Get.put(DialogController()).customReset();},
                                            child:  Text('초기화',style: TextStyle(color: Colors.redAccent,fontSize: 18.sp),)),
                                      ),
                                    ],
                                  ),
                                  TextButton(onPressed: (){
                                    if(Get.put(PenaltyController()).customizing.value){
                                      if(Get.put(PenaltyController()).showList.isEmpty){
                                        Get.put(DialogController()).customAlert('벌칙리스트가 비어있습니다');
                                      }else{
                                        Get.put(PenaltyController()).savePenalty(Get.put(PenaltyController()).showList);
                                        Get.put(DialogController()).saveCustom();
                                      }
                                    }
                                    Get.put(PenaltyController()).changeCustomizing();
                                  },
                                    child:
                                    Text( Get.put(PenaltyController()).customizing.value ?
                                    '저장' : '편집하기', style:  TextStyle(fontSize: 18.sp, fontWeight: FontWeight.bold, color: Colors.blueAccent,),
                                    ),
                                  )
                                ],
                              ),),
                          ),
                        ],
                      ),
                      AnimatedContainer(
                        height: Get.put(PenaltyController()).customizing.value ? 50.h : 0,
                        duration: const Duration(milliseconds: 600),
                        child: Visibility(
                          visible: Get.put(PenaltyController()).customizing.value,
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Container(
                                height: 40.h,
                                width: Get.width - 100.h,
                                padding:  EdgeInsets.all(5.0.r),
                                child: TextField(
                                    textAlignVertical: TextAlignVertical.center,
                                    controller: Get.put(PenaltyController()).customTextController,
                                    decoration: const InputDecoration(
                                        enabledBorder: OutlineInputBorder(
                                            borderSide: BorderSide(
                                              color: Color(0xffdddddd),
                                            )
                                        ),
                                        focusedBorder: OutlineInputBorder(
                                            borderSide: BorderSide(
                                              color: Color(0xffaecdff),
                                            )
                                        )
                                    )
                                ),
                              ),
                              Expanded(
                                child: GestureDetector(
                                  onTap: (){
                                    Get.put(PenaltyController()).showList.add(Get.put(PenaltyController()).customTextController.text);
                                    //FocusScope.of(context).unfocus();
                                    Get.put(PenaltyController()).customTextController.clear();
                                  },
                                  child: Container(
                                    padding:  EdgeInsets.all(5.r),
                                    decoration: BoxDecoration(
                                        borderRadius: BorderRadius.circular(10),
                                        color: const Color(0xffaecdff)
                                    ),
                                    child: Text('입력', style: TextStyle(fontSize:10.sp, color: Colors.white),textAlign: TextAlign.center,),
                                  ),
                                ),
                              )
                            ],
                          ),
                        ),
                      ),
                      Expanded(
                        child: ListView.separated(
                            physics: const ScrollPhysics(),
                            itemBuilder: (BuildContext context, int index){
                              return Container(
                                height: 25.h,
                                alignment: Alignment.bottomLeft,
                                decoration: const BoxDecoration(
                                    border: Border(
                                        top: BorderSide(
                                            color: Color(0xffaecdff),
                                            width: 0.5
                                        )
                                    )
                                ),
                                child: Row(
                                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                  crossAxisAlignment: CrossAxisAlignment.end,
                                  children: [
                                    Text(Get.put(PenaltyController()).basicList[index], style: const TextStyle(fontSize: 18)),
                                    Visibility(
                                      visible: Get.put(PenaltyController()).customizing.value,
                                      child: IconButton(
                                        icon: const Icon(Icons.delete_forever_outlined, color: Colors.redAccent,),
                                        onPressed: (){
                                          Get.put(PenaltyController()).showList.removeAt(index);
                                        },
                                      ),)
                                  ],
                                ),
                              );
                            },
                            separatorBuilder: (BuildContext context, int index){
                              return  SizedBox(height: 7.h,);
                            },
                            itemCount: Get.put(PenaltyController()).showList.length
                        ),
                      ),
                       SizedBox(height: 10.h,),
                    ],
                  ),
                  ),
                ),
              ),
            )
    );
  }

벌칙모드의 설명과 리스트를 표시해주고 리스트가 비어있을때는 에러 방지를 위해 저장하지 못하게 구현,

그리고 저장하지 않고 나가기를 시도할 경우 알려주고 나가기를 막아놨다.

 

그 외 초기화 버튼 클릭시 경고 알람 저장 버튼 클릭시 저장 알람이 뜨도록 구현하였다.

 

❌개선 할 점

1. 텍스트 필드를 사용할 때, 키패드 외 터치 시 unfocus가 되는 기능은 필수적이라고 생각함.

하지만 GetX는 context를 사용하지 않기 때문에 unfocus하기 위한 코드가 복잡해짐. 

Class로 구현 후, transition효과를 주기로 함.

2. ListView를 사용하면 Size를 지정하든가 List의 길이에 따라 size를 정해주었는데 그냥 CustomScrollView를 사용하기로 함

3. 텍스트 필드위치를 아래쪽으로 옮겨 시각적으로 확인이 쉽게 바꾸려 함.


☑️Code

class PenaltyInfo extends StatelessWidget {
  PenaltyInfo({Key? key}) : super(key: key);
  final controller = Get.put(PenaltyController());
  @override
  Widget build(BuildContext context) { 
    return SafeArea(
      child: Scaffold(
        resizeToAvoidBottomInset: true,
        body: WillPopScope(
            onWillPop: (){
              if(controller.customizing.value){
                Get.put(DialogController()).customAlert('저장 후 나가주세요.');
              }else{
                Get.back();
              }
              return Future(() => false);
            },
            child:  GestureDetector(
              onTap: ()=> FocusScope.of(context).unfocus(),
              child: Container(
                decoration: const BoxDecoration(
                  color: Colors.white,
                  border: Border(
                    top: BorderSide(
                        color: Color(0xffaecdff), width: 5
                    ),
                    left: BorderSide(
                        color: Color(0xffaecdff), width: 5
                    ),
                    right: BorderSide(
                        color: Color(0xffaecdff), width: 5
                    ),
                  ),
                ),
                child: Column(
                  children: [
                    Expanded(
                      child: CustomScrollView(
                        controller: controller.scrollController,
                        slivers: [
                          SliverAppBar(
                            backgroundColor: const Color(0xffffffff),
                            automaticallyImplyLeading: false,
                            toolbarHeight: 130.h,
                            centerTitle: false,
                            floating: true,
                            pinned: false,
                            elevation: 0,
                            flexibleSpace: Padding(
                              padding: EdgeInsets.symmetric(horizontal: 20.w),
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Row(
                                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                    children: [
                                      Text('벌칙모드란 ?', style: TextStyle(fontSize: 24.sp,fontWeight: FontWeight.bold, fontFamily: 'OneTitle'),),
                                      IconButton(
                                        icon:  Icon(Icons.cancel, size: 40.r, color: const Color(0xffaecdff),),
                                        onPressed: () {
                                          if(controller.customizing.value){
                                            Get.put(DialogController()).customAlert('저장 후 나가주세요.');
                                          }else{
                                            Get.back();
                                          }
                                        },
                                      )
                                    ],
                                  ),
                                  Padding(padding:  EdgeInsets.only(bottom: 15.h),
                                    child: Divider(
                                      endIndent: Get.width/2,
                                      thickness: 1,
                                      color: const Color(0xff6c6c6c),
                                    ),),
                                  Text('게임 오버 시 아래 리스트 중\n벌칙이 랜덤하게 생성되요.',style: TextStyle(fontSize: 18.sp),),],
                              ),
                            ),
                          ),
                          SliverAppBar(
                              elevation: 0,
                              backgroundColor: const Color(0xffffffff),
                              automaticallyImplyLeading: false,
                                pinned: true,
                                floating: false,
                                toolbarHeight: 52.h,
                                flexibleSpace: Obx(
                                      ()=> Padding(
                                        padding: EdgeInsets.symmetric(horizontal: 20.w,vertical: 5.h),
                                        child: Row(
                                          crossAxisAlignment: CrossAxisAlignment.end,
                                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                    children: [
                                        Text('${controller.showList.length} 개',
                                          style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18.sp, color: const Color(0xffaecdf0)),),
                                        Row(
                                          crossAxisAlignment: CrossAxisAlignment.end,
                                          children: [
                                            GestureDetector(
                                              onTap: ()=> controller.changeCustomizing(),
                                              child: Text(
                                                controller.customizing.value ? '저장' : '편집',
                                                style: TextStyle(
                                                    fontSize: 20.sp,
                                                    fontWeight: controller.customizing.value ? FontWeight.bold : FontWeight.normal,
                                                    color: controller.customizing.value ? const Color(0xffaecdff) : const Color(0xffb666ff)
                                                ),
                                              ),
                                            ),
                                            SizedBox(width: 20.w,),
                                            Visibility(
                                              visible: controller.customizing.value,
                                              child: DelayedWidget(
                                                  animation: DelayedAnimations.SLIDE_FROM_LEFT,
                                                  animationDuration: const Duration(milliseconds: 500),
                                                  delayDuration: const Duration(milliseconds: 300),
                                                  child: GestureDetector(
                                                      onTap: ()=> Get.put(DialogController()).customReset(),
                                                      child: Icon(Icons.replay, size: 24.r, color: const Color(0xffFE2E2E),)
                                                  )
                                              ),
                                            ),
                                          ],
                                        )
                                    ],
                                  ),
                                      ),
                                )
                          ),
                          Obx(
                            ()=> SliverFixedExtentList(
                              itemExtent: 65.h,
                              delegate: SliverChildBuilderDelegate(
                                      (context, index) =>
                                           DelayedWidget(
                                             delayDuration: Duration(milliseconds: (100 * controller.showList.length) - (100*index)),
                                              animation: DelayedAnimations.SLIDE_FROM_LEFT,
                                              animationDuration: const Duration(milliseconds: 500),
                                        child: Padding(
                                          padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 5.h),
                                          child: Container(
                                            padding: EdgeInsets.only(left: 10.w),
                                            decoration: BoxDecoration(
                                              border: Border.all(color: const Color(0xffaecdff)),
                                              borderRadius: BorderRadius.circular(12),
                                            ),
                                            child:Row(
                                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                              crossAxisAlignment: CrossAxisAlignment.center,
                                              children: [
                                                Text(controller.showList[index], style: TextStyle(fontSize: 18.sp)),
                                                Obx(
                                                  ()=> Visibility(
                                                    visible: controller.customizing.value,
                                                    child: IconButton(
                                                      icon: const Icon(Icons.delete_forever_outlined, color: Colors.redAccent,),
                                                      onPressed: (){
                                                        controller.showList.removeAt(index);
                                                        controller.update();
                                                      },
                                                    ),),
                                                )
                                              ],
                                            ),
                                          ),
                                        )
                                  ),
                                  childCount: controller.showList.length
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                    BottomAppBar(
                      elevation: 0,
                      child: Obx(
                            ()=> AnimatedContainer(
                          alignment: Alignment.center,
                          decoration: const BoxDecoration(
                              borderRadius: BorderRadius.only(topLeft: Radius.circular(15), topRight: Radius.circular(15)),
                              color: Color(0xffaecdff)
                          ),
                          duration: const Duration(milliseconds: 600),
                          height: controller.customizing.value ? 60.h : 0.h,
                          width: Get.width,
                          child: SingleChildScrollView(
                            physics: const NeverScrollableScrollPhysics(),
                            child: Padding(
                              padding: EdgeInsets.symmetric(horizontal: 10.w),
                              child: Row(
                                children: [
                                  Expanded(
                                    child: TextField(
                                        maxLength: 20,
                                        textAlignVertical: TextAlignVertical.center,
                                        style: TextStyle(fontSize: 16.sp, color: Colors.white),
                                        controller: controller.customTextController,
                                        cursorColor: const Color(0xffffffff),
                                        decoration: InputDecoration(
                                            counter: Container(),
                                            enabledBorder:const UnderlineInputBorder(
                                                borderSide: BorderSide(
                                                  color: Color(0xffdddddd),
                                                )
                                            ),
                                            focusedBorder: const UnderlineInputBorder(
                                                borderSide: BorderSide(
                                                  color: Color(0xffaecdff),
                                                )
                                            )
                                        )
                                    ),
                                  ),
                                  GestureDetector(
                                    onTap: (){
                                      controller.showList.insert(0,controller.customTextController.text);
                                      controller.customTextController.clear();
                                      controller.scrollController.animateTo(
                                          controller.scrollController.position.minScrollExtent,
                                          duration: const Duration(milliseconds: 500),
                                          curve: Curves.fastOutSlowIn);
                                      },
                                    child: Container(
                                      padding: EdgeInsets.all(5.r),
                                      decoration: BoxDecoration(
                                        color: const Color(0xffffffff),
                                        border: Border.all(color: const Color(0xffaecdff)),
                                        shape: BoxShape.circle,
                                      ),
                                      alignment: Alignment.center,
                                      child: const Icon(Icons.arrow_upward, color: Color(0xffaecdff),),
                                    ),
                                  )
                                ],
                              ),
                            ),
                          ),
                        ),
                      ),
                    )
                  ],
                ),
              ),
            ),
        ),
      ),
    );
  }
}

 

5️⃣shared_preference로 종료후에도 계속 저장 될 수 있는 기능 및 함수

☑️Code

  @override
 void onInit(){ //init
    super.onInit();
    loadPenalty();
    basicList = ['무반주 댄스 30초 동안 추기', '노래 3소절 부르기',
      '옆 테이블(모르는 사람)한테 인사하기', '이번만 봐줄게', '숨겨왔던 썰 하나만',
      '오른쪽에 앉은 사람 부탁 하나 들어주기', '왼쪽 사람한테 딱밤 맞기', '인디언 밥!',
      '귀여운척 한번 해줘','자신있는 성대모사 하기', '왼쪽 사람이 골라주는 노래 맞춰 춤추기',
      '첫사랑 이야기 해줘',
    ];
    //after prefs load
    if(customList.isEmpty){
      showList.value = basicList;
    }else{
      showList.value = customList;
    }
  }
  
//reset btn F
  void resetList(){
    showList.clear();
    basicList = ['무반주 댄스 30초 동안 추기', '노래 3소절 부르기',
      '옆 테이블(모르는 사람)한테 인사하기', '이번만 봐줄게', '숨겨왔던 썰 하나만',
      '오른쪽에 앉은 사람 부탁 하나 들어주기', '왼쪽 사람한테 딱밤 맞기', '인디언 밥!',
      '귀여운척 한번 해줘','자신있는 성대모사 하기', '왼쪽 사람이 골라주는 노래 맞춰 춤추기',
      '첫사랑 이야기 해줘',
    ];
    showList.addAll(basicList);
    savePenalty(basicList);
  }

  loadPenalty() async{
    prefs = await SharedPreferences.getInstance();
    customList = (prefs?.getStringList('custom') ?? []);
  }

  savePenalty(List<String> list) async{
    prefs = await SharedPreferences.getInstance();
    prefs?.setStringList('custom', list);
  }

Controller가 생성될 때 shared_preference를 이용해 load할 데이터가 있는 지 확인 후 데이터가 없으면 기본 벌칙리스트가 보여지고 있다면 load된 데이터가 보여지도록 하였다.

 

basicList를 함수마다 초기화 해주었는데, 삭제 가능한 부분이다.

 

6️⃣벌칙모드를 키고 게임 오버시 리스트 중 랜덤한 벌칙 지정

☑️Code

void gameOver(int n){
    audio.audioGameover();
    Get.dialog(
        WillPopScope(
          onWillPop: ()=>Future(() => false),
          child: AlertDialog(
      backgroundColor: Colors.transparent,
      content: Container(
          height: 370.h,
          width: Get.width * 0.8,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(15),
            color: Colors.white,
          ),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
               Icon(Icons.warning, color: Colors.red,size: 35.r,),
               Text('GameOver', style: TextStyle(fontSize: 20.sp,fontWeight: FontWeight.bold, color: Colors.red),),
               SizedBox(height: 20.h,),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(Get.put(SettingController()).playerList[Get.put(WordGameController()).currentPlayer.value].name, style:  TextStyle(fontSize: 20.sp, fontWeight: FontWeight.bold),),
                   Text(' 탈락!', style: TextStyle(fontSize: 18.sp),),
                ],
              ),
               SizedBox(height: 10.h,),
              Get.put(SettingController()).penaltyMode.value ?
                  Column(
                    children: [
                       Text('▼ 벌칙 ▼',style: TextStyle(fontSize: 15.sp , color: Colors.indigoAccent),textAlign: TextAlign.right,),
                       SizedBox(height: 5.h,),
                      Text(Get.put(PenaltyController()).showList[Random().nextInt(Get.put(PenaltyController()).showList.length-1)],style:  TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold , color: Colors.red),textAlign: TextAlign.center,),
                    ],
                  ) :
               Text('다음에 더 잘해봐요!', style: TextStyle(fontSize: 18.sp),),
               SizedBox(height: 30.h,),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  GestureDetector(
                    onTap: ()=> Get.back(closeOverlays: true),
                    child: Padding(
                      padding:  EdgeInsets.symmetric(horizontal: 16.w),
                      child: Container(
                        decoration: BoxDecoration(
                          color: const Color(0xffaecdff),
                          borderRadius: BorderRadius.circular(50),
                        ),
                        padding:  EdgeInsets.fromLTRB(30.w, 20.h, 30.w, 20.h),
                        child:  Center(child: Text('나가기', style: TextStyle(fontSize: 15.sp, color: Colors.white),),),
                      ),
                    ),
                  ),
                  GestureDetector(
                    onTap: (){
                      if(n==1){
                        Get.put(WordGameController()).makeTitle();
                        Get.put(TimerController()).time.value = int.parse(Get.put(SettingController()).selectedTimer.value);
                        Get.put(TimerController()).start();
                      }else if(n==2){
                        Get.put(BombGameController()).makeTitle();
                        Get.put(TimerController()).time.value = Get.put(SettingController()).selectedRandomTime.value;
                        Get.put(TimerController()).start();
                      }
                      Get.back();
                      },
                    child: Padding(
                      padding:  EdgeInsets.only(right: 16.w),
                      child: Container(
                        decoration: BoxDecoration(
                          color: const Color(0xffaecdff),
                          borderRadius: BorderRadius.circular(50),
                        ),
                        padding:  EdgeInsets.fromLTRB(30.w, 20.h, 30.w, 20.h),
                        child:  Center(child: Text('다시하기', style: TextStyle(fontSize: 15.sp,color: Colors.white),),),
                      ),
                    ),
                  )
                ],
              ),
               SizedBox(height: 20.h,),
               Text('다시하기를 누르면 게임이', style: TextStyle(fontSize: 13.sp),),
              Text('[ ${(Get.put(SettingController()).playerList[Get.put(WordGameController()).currentPlayer.value].name)} ]님부터 시작됩니다.', style:  TextStyle(fontSize: 13.sp),),
            ],
          ),
      ),
    ),
        ));
  }

SettingController내의 벌칙모드의 bool값을 확인 후 그냥 랜덤하게 텍스트로 나오게하였다.


✅결과