내일배움캠프 Node.js 트랙 13일차
ZEP에서 이루어진 로그라이크 게임 개발 프로젝트
json을 이용해 로컬 파일에 게임 데이터를 저장해보자
미리 고백하자면 아직 세이브 기능을 완벽하게 만들진 못했기 때문에 한 번 더 되짚어 보자는 생각으로 이 글을 적어두려고 한다. 내용을 정확히 이해한 것도 아니지만 언젠가 이해할 날이 온다면…아마 오늘 내가 괴롭게 고민했던 덕분일 것이다… : )
// 새로운 js파일을 만들었다! 이곳에서 json 관련 작업을 해보자.
import fsp from 'fs/promises'; // fs/promises에서 fs를 가져온다.
먼저 node.js의 내장 모듈인 fs에 대해 말해보자면, Node.js의 기본 파일 시스템 모듈이라고 설명할 수 있겠다. 파일 읽고 쓰기, 콜백 함수 데이터 전달 받기, 디렉토리 작업 등 다양한 기능을 제공한다. 내가 이 프로젝트를 하면서 사용하게 된 모듈은 바로 이 fs의 프로미스(promises) 버전이다. 쉽게 말해 fs를 비동기식으로 처리해주는 모듈이라고 볼 수 있겠다.
// JSON 파일을 로드하는 함수
let loadJson = async (filePath) => {
try {
const data = await fsp.readFile(filePath, 'utf8');
return JSON.parse(data);
} catch (err) {
console.error('파일 읽기 오류:', err);
return null; // 파일을 읽지 못했을 경우 null 반환
}
};
json파일을 로드하는 데에 바로 이 fsp 모듈이 사용된다. filePath 경로에 있는 파일을 UTF-8 인코딩 방식으로 읽어오고 data에 그 내용이 문자열로 할당된다. JSON.parse(data)는 data 문자열을 JavaScript 객체로 파싱한 후 반환한다. try, catch 구문은 오류를 잡기 위해 쓰인 상황이다.
이를 통해서 업적 기능을 다음과 같이 만들어 보았다.
// 업적 완료하기
let unlockAchievement = async (filePath, index) => {
try {
let jsonData = await loadJson(filePath);
// 업적 수정하기 (예: 첫 번째 업적의 isUnlocked를 true로 변경)
if (jsonData && jsonData.achievements && jsonData.achievements.length > 0) {
jsonData.achievements[index].isUnlocked = true; // 업적을 unlocked로 변경
}
// 수정된 데이터를 다시 JSON 문자열로 변환
const updatedData = JSON.stringify(jsonData, null, 2);
// 파일에 다시 쓰기
await fsp.writeFile(filePath, updatedData, 'utf8');
} catch (err) {
console.error('파일 수정 오류:', err);
}
};
위에서 만든 loadJson 함수를 통해 json파일에 문자열로 저장되어 있던 데이터(현재 배열 상태)를 JavaScript 객체로 변환하여 jsonData에 저장하였다. 게임 내에서 특정한 조건을 달성했을 때 해당 업적이 있는 인덱스를 매개변수로 받아온다면 그 요소의 불리언 값을 변경할 수 있을 것이다. 이를 다시 json 문자열로 변환하여 파일에 다시 쓴다면 업적 읽고→수정하고→다시 쓰기의 과정이 완료되는 것이다.
// 완료한 업적 불러오기
async function getAchievements() {
let jsonData;
if (!jsonData) {
jsonData = await loadJson('./data.json'); // 업적 데이터 파일 경로
}
if (jsonData && jsonData.achievements) {
jsonData.achievements.forEach((achievement) => {
if (achievement.isUnlocked) {
console.log(
chalk.hex('#E8B86D')(`====================|**⁂**|====================
업적: ${achievement.name}
설명: ${achievement.description}
===============================================`),
);
}
});
} else {
console.log('업적 데이터가 없습니다.');
}
}
완료한 업적을 불러올 때는 위와 같은 함수를 사용하였다. 실제 게임을 실행한 모습은 다음과 같다.
이제 이 방법으로 세이브 기능도 완성해볼까 싶은데…당장은 해결되지 않은 문제가 있어서 내일의 과제로 남겨두기로 했다.
'개발일지 > TIL(Today I Learned)' 카테고리의 다른 글
2024-11-15 (1) | 2024.11.15 |
---|---|
2024-11-14 (1) | 2024.11.14 |
2024-11-12 (1) | 2024.11.12 |
2024-11-11 (5) | 2024.11.11 |
2024-11-08 (3) | 2024.11.08 |
댓글