본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 4. · 19 Views
플랫포머 게임 프로젝트 셋업 완벽 가이드
Phaser를 사용하여 플랫포머 게임 프로젝트를 처음부터 체계적으로 구축하는 방법을 다룹니다. 프로젝트 구조 설계부터 버전 관리까지, 게임 개발을 시작하기 전에 알아야 할 모든 것을 담았습니다.
목차
1. 프로젝트 구조 설계
김개발 씨는 오랫동안 꿈꿔왔던 플랫포머 게임을 만들기로 결심했습니다. 유튜브에서 본 멋진 인디 게임처럼 캐릭터가 점프하고 적을 물리치는 게임을 만들고 싶었습니다.
하지만 막상 프로젝트를 시작하려니 어디서부터 손을 대야 할지 막막했습니다.
프로젝트 구조란 게임을 구성하는 모든 파일과 폴더를 체계적으로 정리하는 방법입니다. 마치 잘 정돈된 서재처럼, 어떤 파일이 어디에 있는지 한눈에 알 수 있어야 합니다.
처음부터 구조를 잘 잡아두면 프로젝트가 커져도 혼란 없이 개발을 이어갈 수 있습니다.
다음 코드를 살펴봅시다.
// 플랫포머 게임 프로젝트 폴더 구조
my-platformer/
├── index.html // 게임 진입점
├── package.json // 프로젝트 설정
├── vite.config.js // 빌드 도구 설정
├── src/
│ ├── main.js // 게임 초기화
│ ├── config.js // 게임 설정값
│ ├── scenes/ // 게임 씬 모음
│ │ ├── BootScene.js
│ │ ├── MenuScene.js
│ │ └── GameScene.js
│ ├── sprites/ // 게임 오브젝트
│ │ ├── Player.js
│ │ └── Enemy.js
│ └── utils/ // 유틸리티 함수
└── public/
└── assets/ // 게임 리소스
├── images/
├── audio/
└── tilemaps/
김개발 씨는 입사 3개월 차 주니어 개발자입니다. 웹 개발 경험은 있지만 게임 개발은 처음이었습니다.
처음에는 모든 코드를 하나의 파일에 작성하기 시작했습니다. 그런데 코드가 500줄을 넘어가자 어디가 어딘지 알 수 없게 되었습니다.
선배 개발자 박시니어 씨가 다가와 화면을 보더니 한숨을 쉬었습니다. "개발 씨, 게임 개발도 웹 개발이랑 똑같아요.
구조가 먼저예요." 그렇다면 좋은 프로젝트 구조란 무엇일까요? 쉽게 비유하자면, 프로젝트 구조는 마치 아파트의 평면도와 같습니다.
거실, 침실, 주방이 제각각 흩어져 있으면 생활하기 불편하듯이, 코드 파일도 역할에 따라 잘 분류되어 있어야 합니다. scenes 폴더에는 게임의 각 화면을, sprites 폴더에는 게임 캐릭터들을, assets 폴더에는 이미지와 사운드를 모아둡니다.
구조 없이 개발하면 어떤 일이 벌어질까요? 처음에는 빠르게 진행되는 것처럼 보입니다.
하지만 기능이 추가될수록 문제가 생깁니다. "저 함수가 어디 있었지?" "이 이미지 파일 이름이 뭐였더라?" 매번 파일을 뒤져야 하고, 시간은 점점 늘어납니다.
더 큰 문제는 팀원과 협업할 때 발생합니다. 서로 다른 곳에 같은 기능을 만들어버리는 일이 비일비재합니다.
바로 이런 문제를 해결하기 위해 표준화된 프로젝트 구조가 필요합니다. src 폴더 아래에는 모든 소스 코드가 들어갑니다.
main.js는 게임의 시작점으로, Phaser 게임 인스턴스를 생성합니다. config.js에는 화면 크기, 물리 엔진 설정 같은 게임 설정값을 모아둡니다.
설정을 따로 분리해두면 나중에 값을 수정할 때 여러 파일을 돌아다닐 필요가 없습니다. scenes 폴더는 게임의 각 화면을 담당합니다.
부팅 화면, 메뉴 화면, 실제 게임 화면을 각각 별도의 파일로 관리합니다. 이렇게 하면 메뉴를 수정하고 싶을 때 MenuScene.js만 열면 되고, 게임 로직을 수정하고 싶을 때는 GameScene.js만 보면 됩니다.
sprites 폴더에는 플레이어, 적, 아이템 같은 게임 오브젝트 클래스가 들어갑니다. 각 캐릭터의 움직임, 애니메이션, 충돌 처리 등을 해당 클래스 안에서 관리합니다.
public/assets 폴더는 코드가 아닌 리소스를 담습니다. 이미지, 사운드, 타일맵 파일이 여기에 위치합니다.
코드와 리소스를 분리해두면 디자이너가 이미지를 교체할 때 개발자의 코드를 건드릴 필요가 없습니다. 실제 현업에서는 이 구조를 기반으로 확장합니다.
규모가 큰 게임이라면 managers 폴더를 추가해 사운드 매니저, 세이브 매니저 등을 관리하기도 합니다. constants 폴더에 상수값을 모아두는 팀도 많습니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 조언을 듣고 프로젝트를 다시 정리한 김개발 씨는 놀라운 경험을 했습니다.
코드를 찾는 시간이 절반으로 줄었고, 새로운 기능을 추가하는 것도 훨씬 수월해졌습니다. "구조가 이렇게 중요한 거였군요!"
실전 팁
💡 - 프로젝트 시작 전에 폴더 구조를 먼저 만들어두세요
- 파일 하나가 300줄을 넘으면 분리를 고려하세요
- 팀 프로젝트라면 구조에 대한 문서를 README에 남겨두세요
2. 에셋 준비하기
프로젝트 구조를 잡은 김개발 씨는 이제 게임에 들어갈 이미지와 사운드를 준비해야 했습니다. 인터넷에서 이미지를 다운로드받아 아무 폴더에나 넣었더니, 나중에 어떤 이미지가 어디에 쓰이는지 알 수 없는 혼란이 벌어졌습니다.
에셋이란 게임에서 사용하는 이미지, 사운드, 폰트 같은 리소스를 말합니다. 마치 영화 촬영에 필요한 소품과 배경처럼, 게임에도 캐릭터 스프라이트, 배경 이미지, 효과음 등이 필요합니다.
에셋을 체계적으로 관리하면 개발 효율이 크게 향상됩니다.
다음 코드를 살펴봅시다.
// public/assets 폴더 구조
assets/
├── images/
│ ├── characters/
│ │ ├── player.png // 플레이어 스프라이트시트
│ │ └── enemy-slime.png // 슬라임 적 스프라이트
│ ├── tiles/
│ │ ├── tileset.png // 타일셋 이미지
│ │ └── background.png // 배경 이미지
│ └── ui/
│ ├── button-play.png // 플레이 버튼
│ └── health-bar.png // 체력바
├── audio/
│ ├── bgm/
│ │ └── level1.mp3 // 배경음악
│ └── sfx/
│ ├── jump.wav // 점프 효과음
│ └── coin.wav // 코인 획득 효과음
└── tilemaps/
└── level1.json // Tiled 맵 데이터
김개발 씨는 처음에 모든 이미지를 하나의 폴더에 넣어두었습니다. player.png, bg.png, btn.png, enemy1.png...
파일이 30개를 넘어가자 원하는 파일을 찾는 데만 몇 분씩 걸렸습니다. "분명 배경 이미지 있었는데..." 하며 폴더를 뒤지는 시간이 아까웠습니다.
박시니어 씨가 조언했습니다. "에셋도 코드처럼 분류해야 해요.
나중에 본인이 고생합니다." 에셋 관리의 핵심은 일관성 있는 명명 규칙입니다. 마치 도서관에서 책을 분류하듯이, 에셋도 카테고리별로 정리해야 합니다.
이미지라면 characters, tiles, ui로 나누고, 오디오라면 bgm과 sfx로 구분합니다. 이렇게 하면 "플레이어 이미지 어디 있지?"라는 질문에 바로 "images/characters 폴더에 있어요"라고 답할 수 있습니다.
파일 이름도 중요합니다. player-idle.png, player-run.png, player-jump.png처럼 대상-상태 형식으로 이름을 지으면 파일 목록만 봐도 내용을 알 수 있습니다.
반대로 img1.png, new_final_v2.png 같은 이름은 나중에 반드시 혼란을 일으킵니다. 스프라이트시트는 게임 개발에서 특히 중요한 개념입니다.
캐릭터의 걷기 애니메이션이 8프레임이라면, 8개의 파일 대신 하나의 이미지에 8개 프레임을 나란히 배치합니다. 이렇게 하면 파일 수가 줄어들고, 게임 로딩 속도도 빨라집니다.
타일맵은 레벨 디자인의 핵심입니다. Tiled라는 무료 도구를 사용하면 타일셋 이미지를 기반으로 게임 맵을 만들 수 있습니다.
만들어진 맵은 JSON 파일로 내보내서 tilemaps 폴더에 저장합니다. 오디오 파일 형식도 신경 써야 합니다.
배경음악은 용량이 크므로 MP3나 OGG 형식을 사용합니다. 효과음은 짧으므로 WAV 형식도 괜찮습니다.
웹 브라우저마다 지원하는 형식이 다르니, 중요한 사운드는 여러 형식으로 준비해두는 것이 좋습니다. 무료 에셋을 구할 수 있는 곳도 알아두면 좋습니다.
OpenGameArt, itch.io, Kenney.nl 같은 사이트에서 상업적으로도 사용 가능한 에셋을 구할 수 있습니다. 단, 라이선스는 반드시 확인하세요.
김개발 씨는 에셋을 정리하고 나서 개발 속도가 눈에 띄게 빨라졌습니다. 필요한 파일을 찾는 시간이 줄었고, 새로운 에셋을 추가할 때도 어디에 넣어야 할지 고민할 필요가 없었습니다.
실전 팁
💡 - 스프라이트시트는 TexturePacker나 무료 도구로 만들 수 있습니다
- 에셋 파일명에 한글이나 공백은 피하세요
- 사용하지 않는 에셋은 정기적으로 정리하세요
3. 게임 설정 파일
김개발 씨는 게임 화면 크기를 800x600으로 설정했습니다. 그런데 테스트하다 보니 600x400이 더 나을 것 같았습니다.
코드 여러 곳에 흩어진 숫자를 하나씩 찾아 바꾸다가 결국 하나를 놓쳐서 버그가 발생했습니다.
설정 파일은 게임 전체에서 사용하는 설정값을 한 곳에 모아둔 파일입니다. 화면 크기, 물리 엔진 설정, 색상 값 등을 중앙에서 관리하면 수정이 필요할 때 한 곳만 바꾸면 됩니다.
마치 건물의 총괄 관리실처럼, 모든 설정을 한눈에 파악하고 제어할 수 있습니다.
다음 코드를 살펴봅시다.
// src/config.js - 게임 설정 파일
export const GAME_CONFIG = {
// 화면 설정
width: 800,
height: 600,
backgroundColor: '#1d1d1d',
// 물리 엔진 설정
physics: {
gravity: { x: 0, y: 800 },
debug: true // 개발 중에는 true
},
// 플레이어 설정
player: {
speed: 200,
jumpForce: -400,
lives: 3
},
// 적 설정
enemy: {
speed: 100,
damage: 1
}
};
// src/main.js - Phaser 설정에 적용
import Phaser from 'phaser';
import { GAME_CONFIG } from './config.js';
const config = {
type: Phaser.AUTO,
width: GAME_CONFIG.width,
height: GAME_CONFIG.height,
backgroundColor: GAME_CONFIG.backgroundColor,
physics: {
default: 'arcade',
arcade: GAME_CONFIG.physics
}
};
김개발 씨가 겪은 문제는 많은 초보 개발자가 겪는 전형적인 실수입니다. 코드 곳곳에 800, 600 같은 숫자를 직접 적어두면 처음에는 간편해 보입니다.
하지만 그 숫자를 바꿔야 할 때 진짜 문제가 시작됩니다. 박시니어 씨가 말했습니다.
"이런 걸 매직 넘버라고 해요. 코드에 의미 없이 떠다니는 숫자들이죠.
나중에 본인도 왜 그 숫자를 썼는지 기억 못 해요." 설정 파일을 만드는 이유는 간단합니다. 한 곳에서 모든 것을 제어하기 위해서입니다.
마치 자동차 계기판처럼, 설정 파일은 게임의 모든 주요 수치를 한눈에 보여줍니다. 플레이어 속도가 너무 빠른가요?
config.js를 열어 player.speed 값만 바꾸면 됩니다. 중력이 너무 강한가요?
physics.gravity.y 값을 조절하면 됩니다. GAME_CONFIG 객체 안에는 관련 있는 설정끼리 그룹으로 묶어둡니다.
화면 관련 설정, 물리 엔진 설정, 플레이어 설정, 적 설정 등으로 나누면 찾기도 쉽고 관리도 편합니다. 특히 debug 설정은 개발 중에 매우 유용합니다.
이 값을 true로 설정하면 물리 엔진의 충돌 영역이 화면에 표시됩니다. 캐릭터가 왜 벽을 통과하는지, 왜 적과 충돌이 안 되는지 눈으로 확인할 수 있습니다.
게임을 배포할 때는 false로 바꾸면 됩니다. 설정 파일의 또 다른 장점은 밸런스 조절이 쉬워진다는 것입니다.
게임 개발에서 밸런스는 매우 중요합니다. 플레이어 점프력, 적의 이동 속도, 대미지 수치 등을 여러 번 조절해가며 최적의 값을 찾아야 합니다.
설정 파일이 있으면 이 과정이 훨씬 수월해집니다. main.js에서는 이 설정값을 불러와서 Phaser 설정에 적용합니다.
import 문으로 config.js를 불러오고, GAME_CONFIG 객체의 값들을 Phaser가 이해하는 형식으로 전달합니다. 주의할 점도 있습니다.
설정 파일에 모든 것을 넣으려고 하면 오히려 파일이 너무 커집니다. 여러 곳에서 공유하는 값만 설정 파일에 넣고, 특정 클래스에서만 사용하는 값은 해당 클래스 안에 두는 것이 좋습니다.
김개발 씨는 설정 파일을 만든 후로 밸런스 테스트가 즐거워졌습니다. 숫자 하나 바꾸고 새로고침만 하면 바로 결과를 확인할 수 있었기 때문입니다.
실전 팁
💡 - 개발용 설정과 배포용 설정을 분리해두면 편리합니다
- 설정값에는 반드시 의미 있는 이름을 붙이세요
- 설정 파일도 버전 관리에 포함하세요
4. Scene 구조 계획
김개발 씨는 모든 게임 로직을 하나의 파일에 작성했습니다. 메뉴 화면, 게임 화면, 게임 오버 화면이 뒤섞여 있었습니다.
코드가 1000줄을 넘어가자 어디서부터 손을 대야 할지 막막해졌습니다.
Scene은 Phaser에서 게임의 각 화면을 독립적으로 관리하는 단위입니다. 마치 연극의 막처럼, 게임도 여러 장면으로 나뉩니다.
부팅, 메뉴, 게임 플레이, 게임 오버 등 각 장면을 별도의 Scene으로 만들면 코드가 깔끔해지고 관리가 쉬워집니다.
다음 코드를 살펴봅시다.
// src/scenes/BootScene.js - 리소스 로딩
export default class BootScene extends Phaser.Scene {
constructor() {
super('BootScene'); // Scene 고유 키
}
preload() {
// 모든 에셋을 여기서 로드
this.load.image('player', 'assets/images/characters/player.png');
this.load.image('tileset', 'assets/images/tiles/tileset.png');
this.load.audio('bgm', 'assets/audio/bgm/level1.mp3');
// 로딩 진행률 표시
this.load.on('progress', (value) => {
console.log(`Loading: ${Math.floor(value * 100)}%`);
});
}
create() {
// 로딩 완료 후 메뉴로 이동
this.scene.start('MenuScene');
}
}
// src/scenes/GameScene.js - 실제 게임 플레이
export default class GameScene extends Phaser.Scene {
constructor() {
super('GameScene');
}
create() {
// 게임 오브젝트 생성
this.player = this.physics.add.sprite(100, 100, 'player');
// ... 게임 로직
}
}
김개발 씨의 1000줄짜리 파일을 본 박시니어 씨는 고개를 저었습니다. "이건 스파게티 코드예요.
Phaser의 Scene 시스템을 활용하면 훨씬 깔끔해질 거예요." Scene이란 무엇일까요? 영화관에서 영화를 볼 때를 떠올려보세요.
영화는 여러 장면으로 구성되어 있습니다. 주인공이 집에 있는 장면, 학교에 가는 장면, 악당과 싸우는 장면.
게임도 마찬가지입니다. 로딩 화면, 메뉴 화면, 게임 화면, 게임 오버 화면 등 여러 장면으로 나뉩니다.
Phaser는 이 개념을 Scene 클래스로 구현합니다. 각 Scene은 독립적인 세계입니다.
메뉴 Scene에서 일어나는 일은 게임 Scene에 영향을 주지 않습니다. 이렇게 분리해두면 메뉴를 수정할 때 게임 로직을 건드릴 걱정이 없습니다.
플랫포머 게임의 기본적인 Scene 구조를 살펴봅시다. BootScene은 게임의 시작점입니다.
이 Scene에서는 게임에 필요한 모든 에셋을 로드합니다. 이미지, 사운드, 타일맵 등을 미리 메모리에 올려두는 작업을 합니다.
로딩이 끝나면 다음 Scene으로 자동 전환됩니다. MenuScene은 게임 시작 전 메뉴 화면입니다.
게임 타이틀, 시작 버튼, 설정 버튼 등이 여기에 위치합니다. 플레이어가 시작 버튼을 누르면 GameScene으로 이동합니다.
GameScene은 실제 게임이 진행되는 곳입니다. 플레이어 캐릭터, 적, 플랫폼, 아이템 등 모든 게임 오브젝트가 이 Scene에서 활동합니다.
플레이어가 죽으면 GameOverScene으로 이동합니다. GameOverScene은 게임 종료 화면입니다.
점수, 재시작 버튼, 메뉴로 돌아가기 버튼 등을 표시합니다. Scene 간 이동은 this.scene.start() 메서드로 합니다.
start() 메서드를 호출하면 현재 Scene은 종료되고 지정한 Scene이 시작됩니다. 만약 현재 Scene을 유지하면서 다른 Scene을 추가로 실행하고 싶다면 **this.scene.launch()**를 사용합니다.
이 방법은 게임 중에 일시정지 메뉴를 띄울 때 유용합니다. 각 Scene 클래스에는 Phaser가 자동으로 호출하는 메서드들이 있습니다.
**preload()**는 에셋 로딩, **create()**는 초기화, **update()**는 매 프레임 실행됩니다. 이 생명주기를 이해하면 코드를 어디에 작성해야 할지 명확해집니다.
김개발 씨는 하나의 파일을 4개의 Scene으로 분리했습니다. 각 파일이 200줄 내외로 줄어들자 코드를 이해하기가 훨씬 쉬워졌습니다.
"이제야 내 코드가 내 코드 같아요!"
실전 팁
💡 - Scene 이름은 고유해야 합니다. 중복되면 오류가 발생합니다
- 복잡한 게임은 Scene을 더 세분화하세요 (LevelSelectScene, ShopScene 등)
- Scene 간에 데이터를 전달할 때는 this.scene.start('Scene', { data }) 형식을 사용하세요
5. 개발 워크플로우
김개발 씨는 코드를 수정할 때마다 브라우저를 새로고침하고, 처음부터 게임을 다시 시작해야 했습니다. 3단계 보스 테스트를 하려면 매번 1단계부터 플레이해야 했습니다.
테스트 한 번에 5분씩 걸리니 진도가 나가지 않았습니다.
개발 워크플로우란 코드 작성부터 테스트까지의 반복 과정을 효율적으로 만드는 방법입니다. 마치 공장의 생산 라인처럼, 각 단계가 매끄럽게 연결되어야 합니다.
좋은 워크플로우는 개발 시간을 크게 단축시킵니다.
다음 코드를 살펴봅시다.
// package.json - 개발 스크립트 설정
{
"scripts": {
"dev": "vite", // 개발 서버 실행
"build": "vite build", // 프로덕션 빌드
"preview": "vite preview" // 빌드 결과 미리보기
},
"devDependencies": {
"vite": "^5.0.0"
},
"dependencies": {
"phaser": "^3.70.0"
}
}
// vite.config.js - Vite 설정
import { defineConfig } from 'vite';
export default defineConfig({
base: './', // 상대 경로 사용
build: {
outDir: 'dist'
},
server: {
port: 3000,
open: true // 서버 시작 시 브라우저 자동 열기
}
});
// 디버깅용 Scene 바로가기 (개발 중에만 사용)
// src/main.js에 추가
if (import.meta.env.DEV) {
window.goToScene = (sceneName) => {
game.scene.start(sceneName);
};
}
김개발 씨는 매번 수동으로 새로고침하고, 처음부터 게임을 시작하는 비효율적인 과정을 반복하고 있었습니다. 하루의 절반을 테스트 준비에 쓰고 있었던 것입니다.
박시니어 씨가 물었습니다. "개발 서버 쓰고 계신 거예요?" 김개발 씨는 고개를 저었습니다.
그냥 HTML 파일을 브라우저에서 열고 있었습니다. 개발 서버는 게임 개발의 필수품입니다.
개발 서버는 마치 유능한 비서와 같습니다. 코드를 저장하면 자동으로 브라우저를 새로고침해줍니다.
에러가 나면 화면에 바로 표시해줍니다. 덕분에 개발자는 코드 작성에만 집중할 수 있습니다.
Vite는 현재 가장 인기 있는 프론트엔드 개발 도구입니다. 설정이 간단하고 속도가 빠릅니다.
npm create vite@latest 명령어로 프로젝트를 생성하면 기본 설정이 자동으로 완료됩니다. package.json의 scripts 섹션을 살펴봅시다.
npm run dev를 실행하면 개발 서버가 시작됩니다. 브라우저가 자동으로 열리고, 코드를 수정할 때마다 즉시 반영됩니다.
이것을 **Hot Module Replacement (HMR)**라고 부릅니다. 테스트 효율을 높이는 비법도 있습니다.
개발 모드에서만 활성화되는 디버그 기능을 추가하는 것입니다. 위 코드의 window.goToScene 함수는 브라우저 콘솔에서 특정 Scene으로 바로 이동할 수 있게 해줍니다.
3단계 보스를 테스트하고 싶다면 콘솔에 goToScene('Level3Scene')만 입력하면 됩니다. 비슷한 방식으로 다양한 디버그 기능을 추가할 수 있습니다.
무적 모드, 아이템 무한 획득, 특정 위치로 텔레포트 등. 이런 기능들은 import.meta.env.DEV 조건문 안에 넣어서 개발 모드에서만 작동하게 합니다.
빌드된 게임에는 포함되지 않으니 안심하세요. 빌드는 게임을 배포 가능한 형태로 변환하는 과정입니다.
npm run build를 실행하면 dist 폴더에 최적화된 파일들이 생성됩니다. 이 파일들을 웹 서버에 업로드하면 누구나 게임을 플레이할 수 있습니다.
vite.config.js에서 몇 가지 설정을 조정할 수 있습니다. **base: './'**는 빌드된 파일이 상대 경로를 사용하도록 합니다.
이렇게 하면 어떤 경로에 배포해도 정상 작동합니다. server.port는 개발 서버 포트, server.open은 서버 시작 시 브라우저 자동 열기 옵션입니다.
김개발 씨는 개발 환경을 구축한 후 생산성이 두 배로 늘었습니다. 코드 저장만 하면 바로 결과를 볼 수 있었고, 특정 Scene으로 바로 이동해서 테스트할 수 있었습니다.
"왜 진작 이렇게 안 했을까요!"
실전 팁
💡 - 개발 중에는 항상 브라우저 개발자 도구를 열어두세요
- 자주 테스트하는 상황은 디버그 함수로 만들어두세요
- 빌드 후에는 반드시 dist 폴더에서 테스트해보세요
6. 버전 관리 설정
김개발 씨는 새로운 기능을 추가하다가 기존 코드를 망가뜨렸습니다. "원래 어땠더라?" 기억을 더듬어봐도 떠오르지 않았습니다.
결국 처음부터 다시 작성해야 했습니다. 3시간 동안 작업한 코드가 허공으로 사라졌습니다.
버전 관리란 코드의 변경 이력을 기록하고 관리하는 시스템입니다. 마치 문서의 수정 기록처럼, 누가 언제 무엇을 바꿨는지 추적할 수 있습니다.
Git을 사용하면 실수로 코드를 망가뜨려도 언제든 이전 상태로 돌아갈 수 있습니다.
다음 코드를 살펴봅시다.
// .gitignore - Git에서 제외할 파일 목록
# 의존성 폴더
node_modules/
# 빌드 결과물
dist/
# 환경 설정 (민감 정보 포함 가능)
.env
.env.local
# 에디터 설정
.vscode/
.idea/
# 운영체제 파일
.DS_Store
Thumbs.db
# 로그 파일
*.log
# Git 기본 명령어 사용 예시
# 저장소 초기화
git init
# 파일 추가 및 커밋
git add .
git commit -m "feat: 플레이어 점프 기능 추가"
# 브랜치 생성 및 이동
git checkout -b feature/double-jump
# 원격 저장소에 푸시
git remote add origin https://github.com/user/my-platformer.git
git push -u origin main
김개발 씨가 3시간치 작업을 날린 후, 박시니어 씨가 다가왔습니다. "Git 안 쓰세요?" 김개발 씨는 Git이라는 말을 들어본 적은 있지만, 어렵게만 느껴져서 미뤄두고 있었습니다.
"Git은 개발자의 타임머신이에요. 과거로 돌아갈 수 있게 해주죠." Git은 버전 관리 시스템입니다.
코드의 스냅샷을 찍어두고, 필요할 때 그 시점으로 돌아갈 수 있습니다. 마치 게임의 세이브 포인트처럼, 중요한 시점마다 저장해두면 실수해도 복구할 수 있습니다.
Git을 시작하려면 먼저 git init 명령어로 저장소를 초기화합니다. 이 명령어를 실행하면 프로젝트 폴더에 .git 폴더가 생성됩니다.
이 폴더 안에 모든 버전 정보가 저장됩니다. .gitignore 파일은 Git이 추적하지 않을 파일 목록입니다.
node_modules 폴더는 수천 개의 파일을 포함하고 있어서 Git에 넣으면 저장소가 무거워집니다. 어차피 package.json만 있으면 npm install로 언제든 다시 설치할 수 있으니 제외합니다.
dist 폴더도 마찬가지입니다. 빌드 결과물은 소스 코드로부터 언제든 다시 만들 수 있습니다.
커밋은 코드의 스냅샷을 저장하는 것입니다. git add 명령어로 저장할 파일을 선택하고, git commit 명령어로 스냅샷을 만듭니다.
커밋 메시지는 무엇을 변경했는지 명확하게 적어야 합니다. "수정"이나 "업데이트" 같은 모호한 메시지는 나중에 도움이 되지 않습니다.
커밋 메시지에는 관례가 있습니다. **feat:**는 새 기능, **fix:**는 버그 수정, **refactor:**는 리팩토링을 의미합니다.
이런 접두어를 붙이면 커밋 이력만 봐도 프로젝트의 변경 흐름을 파악할 수 있습니다. 브랜치는 평행 세계를 만드는 것과 같습니다.
새로운 기능을 개발할 때 브랜치를 만들면, 기존 코드에 영향을 주지 않고 실험할 수 있습니다. 기능이 완성되면 main 브랜치에 병합하고, 실패하면 브랜치를 삭제하면 됩니다.
GitHub는 Git 저장소를 온라인에 보관하는 서비스입니다. 코드를 클라우드에 백업할 수 있고, 다른 개발자와 협업하기도 쉽습니다.
git push 명령어로 로컬 변경사항을 GitHub에 올리고, git pull로 다른 사람의 변경사항을 가져옵니다. 김개발 씨는 Git을 배운 후로 과감하게 실험할 수 있게 되었습니다.
새로운 기능을 시도하다 망쳐도 git checkout으로 이전 상태로 돌아가면 그만이었습니다. "Git은 정말 타임머신이네요!"
실전 팁
💡 - 하나의 기능 단위로 커밋하세요. 너무 크거나 작은 커밋은 피하세요
- 커밋하기 전에 git diff로 변경 내용을 확인하세요
- 중요한 작업 전에는 브랜치를 만들어두세요
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
서비스 메시 완벽 가이드
마이크로서비스 간 통신을 안전하고 효율적으로 관리하는 서비스 메시의 핵심 개념부터 실전 도입까지, 초급 개발자를 위한 완벽한 입문서입니다. Istio와 Linkerd 비교, 사이드카 패턴, 실무 적용 노하우를 담았습니다.
EFK 스택 로깅 완벽 가이드
마이크로서비스 환경에서 로그를 효과적으로 수집하고 분석하는 EFK 스택(Elasticsearch, Fluentd, Kibana)의 핵심 개념과 실전 활용법을 초급 개발자도 쉽게 이해할 수 있도록 정리한 가이드입니다.
Grafana 대시보드 완벽 가이드
실시간 모니터링의 핵심, Grafana 대시보드를 처음부터 끝까지 배워봅니다. Prometheus 연동부터 알람 설정까지, 초급 개발자도 쉽게 따라할 수 있는 실전 가이드입니다.
분산 추적 완벽 가이드
마이크로서비스 환경에서 요청의 전체 흐름을 추적하는 분산 추적 시스템의 핵심 개념을 배웁니다. Trace, Span, Trace ID 전파, 샘플링 전략까지 실무에 필요한 모든 것을 다룹니다.
CloudFront CDN 완벽 가이드
AWS CloudFront를 활용한 콘텐츠 배포 최적화 방법을 실무 관점에서 다룹니다. 배포 생성부터 캐시 설정, HTTPS 적용까지 단계별로 알아봅니다.