오늘은 RPG 게임 개발 과제를 진행하면서,
Dart에 대한 이해를 더욱 심화할 수 있었다.
오전에는 팀원들과
아티클을 공유하고 토론했으며,
이후 차기 팀원들과 사업 관련 논의를 했다.
점심을 먹고 난 후
본격적으로 과제에 집중했으며,
저녁에는 네트워킹에 참여했다.
하루가 빠르게 지나갔고,
정말 빠르게 지나갔고,
과제를 대충 끝내고
나의 아이템 구상을 하려고 했으나
예상치 못한 문제들로
오늘도 그냥 이렇게 보냈다.

(중간에 그림그리느라 시간 보낸 건 비밀)
Ⅰ. 과제 진행 내용 정리
과제 주제: Dart로 전투 RPG 게임 개발
📌 과제 주제: Dart로 전투 RPG 게임 개발
과제에서는
객체 지향 프로그래밍(OOP) 개념을 적용하여,
캐릭터와 몬스터 간의
전투 시스템을 구현해야 했다.
특히 파일 입출력,
랜덤 값 생성, 게임 흐름 제어 등의
기능을 다루는 것이 핵심이었다.
📌 구현한 기능
✅ 파일 입출력
- characters.txt에서 캐릭터 정보를 불러오는 기능
- monsters.txt에서 몬스터 리스트를 읽어오는 기능
- 게임 종료 후 결과(result.txt) 저장 기능
✅ 객체 지향 설계
- Character 클래스: 플레이어 캐릭터의 속성 및 공격/방어 메서드 구현
- Monster 클래스: 몬스터의 속성 및 랜덤 공격력 설정
- Game 클래스: 게임의 시작 및 전투 흐름 관리
✅ 전투 시스템
- battle() 메서드에서 플레이어가 공격 또는 방어를 선택할 수 있도록 구현
- getRandomMonster()를 활용하여 랜덤 몬스터와 전투
- 체력이 0이 되면 게임 종료
✅ 예외 처리
- 잘못된 파일 형식일 경우 예외 발생 방지
- 사용자 입력값 검증 (예: 캐릭터 이름에 특수문자 포함 여부 체크)
트러블슈팅 (문제 해결 과정)
문제 1️⃣: 파일 입출력 시 비동기 처리가 필요할까?
📍 상황:
파일에서
데이터를 읽어오는 과정에서
readAsStringSync()를 사용할지,
await을 활용한 비동기 방식을
사용할지 고민이 됐다.
📍 해결:
- readAsStringSync()는 동기적으로 파일을 읽지만, 게임 실행 속도에는 크게 영향이 없으므로 동기 방식을 선택.
- 다만, 대규모 데이터 처리가 필요한 경우 async를 고려해야 함.
📍 배운 점:
비동기가 항상 정답은 아니며, 상황에 따라 동기와 비동기를 적절히 선택하는 것이 중요하다.
--
문제 2️⃣: 몬스터의 랜덤 공격력 설정 문제
📍 상황:
Monster 클래스에서
공격력을 랜덤으로 설정해야 하는데,
방어력보다 작지 않도록 해야 했다.
📍 해결:
this.attack = Random().nextInt(maxAttack - defense) + defense;
- Random().nextInt()를 사용하여 방어력 이상의 값이 나오도록 보정.
- 최소값을 defense 이상으로 설정하여 방어력이 공격력보다 높은 비정상적인 경우 방지.
📍 배운 점:
- 랜덤값을 사용할 때도 논리적 오류를 방지하기 위한 조건 설정이 중요하다.
문제 3️⃣: 게임 종료 후 결과 저장 오류
📍 상황:
게임이 끝난 후
결과를 파일에 저장할 때,
이전 실행 기록이 덮어씌워지는
문제가 발생했다.
정확히는,
나는 과제에 일반/도전 2가지 버전을
기록하려고 노력한다.
이유는,
나의 과정을 전문가들에게
용이하게 보여주기 위함이 첫째,
둘째는 GPT사용으로
로직이 달라지는 경우를 방지하고자 함이다.
백업용이라고나 할까나..
무튼 도전 과제가 일반 과제에
덮어씌어진 실수를 했지만
해결하긴 했다.
📍 해결:
final file = File('result.txt');
file.writeAsStringSync('캐릭터: $name, 남은 체력: $health, 결과: $result\n', mode: FileMode.append);
- FileMode.append를 사용하여 기존 내용 유지하면서 새로운 결과 추가.
📍 배운 점:
파일을 다룰 때 writeAsStringSync() 기본 모드는 덮어쓰기이므로, 로그를 저장할 경우 append 모드를 사용해야 한다.
Ⅱ. 오늘의 느낀 점 & 개선할 점
객체 지향 프로그래밍(OOP)의 실전 적용이 생각보다 흥미로웠다.
이번 과제를 진행하면서
객체 지향 프로그래밍(OOP) 개념이
단순히 개념적으로만
존재하는 것이 아니라,
실제로 어떻게 활용될 수 있는지
실감할 수 있었다.
특히,
Character, Monster, Game
클래스를 분리하여 만들면서
각각의 역할을
명확히 분리하는 것이
얼마나 중요한지 깨달았다.
- 처음에는 모든 기능을 Game 클래스 내부에서 처리하려고 했지만, 유지보수성과 확장성을 고려하면 각 역할을 분리하는 것이 더 효율적이었다.
- 예를 들어, attackMonster()와 같은 공격 로직을 Character 클래스 내부에 두는 것이 직관적이며, Monster의 공격력 계산도 해당 클래스에서 처리하도록 변경했다.
- 이는 향후 새로운 기능을 추가할 때도 코드의 변경 범위를 최소화할 수 있는 장점을 제공했다.
또한 객체 간의 상호작용을
다루는 것이 생각보다 어렵고,
로직을 세밀하게
고민해야 한다는 점을 체감했다.
- 몬스터의 랜덤 공격력 설정, 전투 결과 반영, 체력 업데이트 등은 작은 실수만으로도 게임 밸런스를 무너뜨릴 수 있다.
- 이러한 경험을 통해 OOP의 강점이 단순히 "코드를 보기 좋게 만드는 것"이 아니라 게임 로직을 보다 체계적으로 구성하고, 확장성을 높이는 데 기여한다는 점을 직접 느낄 수 있었다.
파일 입출력과 예외 처리의 중요성
이번 과제에서는
파일 입출력(File I/O)을 활용하여
캐릭터와 몬스터 데이터를 불러오고,
결과를 저장하는 기능을 추가했다.
이는 단순한 터미널 기반 RPG 게임을
한 단계 더 실제 게임답게 만들었다.
📌 구현 과정에서 배운 점
- dart:io 라이브러리를 활용하여 파일을 읽어오는 방식에는 동기(Sync)와 비동기(Async) 방식이 존재한다.
- 게임 로딩 속도에는 큰 영향을 미치지 않으므로 동기 방식(readAsStringSync())을 선택했다.
- 다만, 대규모 데이터(예: 수십 개의 몬스터 리스트)를 처리할 경우 비동기(await file.readAsString()) 방식이 필요할 것으로 보인다.
📌 트러블슈팅 (예외 처리)
파일 입출력을 다루면서 예외 처리의 중요성을 다시 한 번 실감했다.
- 파일이 존재하지 않을 경우 프로그램이 즉시 종료되는 문제가 있었는데, try-catch 블록을 추가하여 예외를 잡고 기본값을 설정하도록 개선했다.
- 사용자가 입력한 캐릭터 이름이 빈 문자열이거나 특수문자가 포함된 경우 오류가 발생할 수 있어 정규표현식(RegExp) 검증을 추가했다.
- 게임 결과를 저장할 때 기존 데이터가 덮어씌워지는 문제를 해결하기 위해 FileMode.append 옵션을 사용했다.
📌 앞으로 개선할 점
- 비동기 처리를 적용하면 파일 로딩이 게임 시작과 동시에 자연스럽게 이루어질 수 있을 것으로 보인다.
- 파일 데이터를 JSON 형식으로 저장하여 보다 유연한 데이터 구조를 만들 수도 있을 것 같다.
UI 고민: RPG 게임과 여행 앱, 어떻게 UI 설계를 진행할 것인가?
이번 과제를 진행하면서
UI를 어떻게 설계해야 할지에 대한
고민이 깊어졌다.
사실 나는 나의 캐릭터가 있고,
이를 GIF, MP4 등의 형태로
구현하는 것은 어렵지 않아서
활용할 예정인데,
게임의 구현 방식과 비슷할 것 같아
함께 찾아보았다.
- 현재는 터미널 기반 CLI 게임이지만, 이를 실제 사용자 인터페이스(UI)가 있는 형태로 확장하려면 어떻게 해야 할까?
- 그리고 내가 개발 중인 여행 일정 관리 앱의 UI 또한 어떻게 구체화해야 할까?
📌 1. RPG 게임을 UI 기반 앱으로 만들려면?
현 단계에서는
단순히 터미널에서 print()를 사용해
출력을 보여주고 있지만,
이를 UI가 있는 게임 형태로 만들려면
몇 가지 요소를 고려해야 한다.
✅ Flutter를 활용한 UI 적용
- Dart 기반 게임이므로, Flutter를 활용하여 UI를 구성하는 것이 적절할 것 같다.
- Column, ListView 등을 활용해 전투 로그를 화면에 출력하고,
- 버튼을 활용한 사용자 입력 (공격/방어 선택 등) 기능을 추가하는 방식으로 확장할 수 있다.
✅ RPG 게임의 UI 요소 정리
- 전투 화면: 현재 플레이어와 몬스터의 상태 표시 (체력, 공격력 등)
- 액션 버튼: 공격 / 방어 / 아이템 사용 등 선택 가능한 행동 UI
- 전투 로그: 게임 진행 상황을 출력하는 텍스트 로그
- 결과 화면: 승리 또는 패배 시 결과 표시
이런 방식으로
UI를 추가하면 기존 CLI 기반 게임을 보다
직관적이고 인터랙티브한
게임으로 발전시킬 수 있을 것 같다.
음.. 상업용 유료 에셋으로
한 번 구현해볼까..?

📌 2. 여행 일정 관리 앱 UI 설계 고민
지금 개발하려는
여행 일정 관리 앱도
마찬가지로 UI 설계가 핵심이다.
현재 UI 예시 이미지(캘린더 스타일 템플릿)를
참고하면서 몇 가지 의문점이 생겼다.
✅ UI에서 우선 구현할 기능은?
- 여행 일정을 주별, 일자별로 정리할 수 있어야 한다.
- 기존 UI 예시처럼 시각적으로 깔끔한 다이어리 형태로 구성하는 것이 좋을 것 같다.
- 예산 관리 기능도 추가해야 하는데, 이 부분을 어떻게 UI로 표현할지 고민이 필요하다.
✅ UI/UX 적용 방향성
- Flutter에서 캘린더 UI를 어떻게 구현할 것인가?
- TableCalendar 패키지를 활용할 수 있을지 검토
- 사용자가 원하는 형식(주별/일별)로 일정을 쉽게 입력하도록 구성
- 예산 관리 UI는?
- 여행 경비를 입력하는 UI를 TextField 기반으로 만들 것인가?
- 혹은 자동 환율 계산 기능을 포함해야 하는가?
- 기존 UI 예시와 차별화할 포인트는?
- 단순한 일정 관리가 아닌, 여행 중에도 실시간으로 변경할 수 있는 기능이 필요할까?
- 사용자가 직접 여행 후기를 기록하는 메모 기능이 필요할까?
이처럼 UI 설계를
구체화하는 과정에서
기능을 어떻게 나누고,
어떤 부분을
우선 개발할 것인지에
대한 고민이 깊어졌다.
현실적으로
MVP(최소 기능 제품)를
어떻게든 먼저 개발하고,
점진적으로
추가하는 방식이 가장 적절할 것 같다.
다음 단계: 개선할 점과 학습 방향 정리
이번 과제를 통해
Dart의 기본기를 다지는 것은 물론,
프로젝트를 기획하고 확장하는 방법까지 고민할 수 있었다.
이제 이를 바탕으로 다음 단계를 준비해야 한다.
✅ 게임 개선 방향
- 터미널 기반이 아닌, Flutter UI를 활용한 인터페이스 적용 가능성 검토
- 추가 기능(아이템 시스템, 몬스터 AI 강화) 도입 검토
✅ 여행 일정 관리 앱 MVP 기획 정리
- UI 템플릿을 어떻게 구성할지 피그마로 정리
- 우선 개발할 기능 리스트 정리 후, Flutter에서 구현 가능성 검토
✅ 추가 학습
- Flutter에서 캘린더 UI 구현 방법 조사
- Dart의 비동기 처리(async, await) 활용법 심화 학습
이번 과제를 통해
단순히 코드를 작성하는 것에서 벗어나,
실제 제품으로 발전시키기 위한
기획, UI/UX 고민, 기능 확장성까지
고민할 수 있어 의미 있는 시간이었다. 🚀
Ⅲ. 내일의 목표
1️⃣ 팀원들과 프로젝트 논의 (Flutter 적용 가능성 검토)
2️⃣ 게임 로직 개선 (추가 기능 적용 가능 여부 분석)
3️⃣ ReadMe 정리 및 코드 리팩토링
오늘 하루도 RPG 게임 개발을 하면서
Dart에 대한 실전 경험을 쌓을 수 있어서 유익했다.
너무 시간이 빨리 지나가는게 흠이다.
앞으로 Flutter를 배우면서
이 게임을 UI가 있는 앱 형태로
확장할 수 있을지 고민해봐야겠다. 🚀
'스파르타코딩클럽(앱 개발 창업) > 스파르타코딩클럽 TIL' 카테고리의 다른 글
[250321] 창업 멘토링 & 비즈니스 시장 분석의 중요성 (0) | 2025.03.21 |
---|---|
[250319] 오늘의 TIL: 3D 캐릭터 애니메이션 적용 & 트러블슈팅 (0) | 2025.03.19 |
[250317] 오늘의 TIL: 스타트업과 Dart 학습, 그리고 MVP 고민 (0) | 2025.03.17 |
[250219 Flutter 창업 6기DAY+8] Lean Startup & 예비창업패키지 준비 (1) | 2025.02.19 |
[250218 Flutter 창업 6기DAY+6, 7] Flutter 학습 및 오류 해결 기록 (1) | 2025.02.18 |