TECH 으로 돌아가기
TECH HACKER NEWS 2026.11.06 09:43 8분 읽기 28 READS

브라우저에서 꼬물꼬물 걷는 레밍즈, CSS 스프라이트 애니메이션은 어떻게 만들까요?

'Lemmings CSS Animation'이라는 이름의 웹 데모가 공개돼 있어요. 레밍즈는 1991년 DMA Design이 내놓은 퍼즐 게임이에요. 앞만 보고 줄지어 걷는 작은 캐릭터들에게 땅 파기나 길 막기 같은 역할을 줘서 출구까지 데려가는 게임인데, 픽셀로 그려진 꼬물꼬물한 움직임이 특히 유명하죠. 참고로 DMA Design은 훗날 GTA 시리즈로 잘 알려진 Rockstar North가 된 회사예요.

데모 이름을 보면 이 움직임을 CSS 애니메이션으로 풀어낸 작품으로 보이는데요. 다만 이 글은 데모의 소스를 직접 분석한 글은 아니에요. 실제 구현은 링크를 열고 브라우저 개발자 도구로 확인해 보시고, 여기서는 이런 픽셀 캐릭터를 CSS로 움직일 때 일반적으로 쓰는 기법을 차근차근 설명해 드릴게요.

핵심은 플립북이에요

어릴 때 교과서 귀퉁이에 그림을 그려서 휘리릭 넘겨본 적 있나요? 픽셀 애니메이션도 똑같아요. 걷는 동작을 여러 장의 그림으로 나눈 뒤, 한 장의 이미지에 가로로 나란히 붙여 둔 걸 스프라이트 시트라고 불러요. 화면에는 캐릭터 크기만 한 작은 창을 두고, 그 뒤에서 이미지를 한 칸씩 밀어주면 캐릭터가 움직이는 것처럼 보이는 거죠.

여기서 중요한 게 steps()예요. CSS 애니메이션은 기본적으로 시작과 끝 사이를 부드럽게 이어주는데, 스프라이트에서는 이게 오히려 문제가 돼요. 이미지가 스르륵 미끄러지면서 프레임 사이가 그대로 보이거든요. steps(8)이라고 쓰면 여덟 번에 나눠 뚝뚝 끊어서 이동하니까 진짜 플립북처럼 보여요.

.walker {
width: 32px;
height: 32px;
background: url(walker.png) 0 0 no-repeat;
image-rendering: pixelated;
animation:
frames 0.8s steps(8) infinite,
path 12s linear infinite;
}

@keyframes frames {
to { background-position: -256px 0; }
}

@keyframes path {
from { transform: translateX(0); }
to { transform: translateX(640px); }
}

32px짜리 프레임이 8장이니 이미지를 256px만큼 밀어주면 한 바퀴가 돌아요. 눈여겨볼 점은 애니메이션을 두 개 겹쳤다는 거예요. frames는 제자리걸음을 담당하고, path는 캐릭터를 실제로 옮겨요. 이 둘을 나눠야 걸음 속도와 이동 속도를 따로 조절할 수 있거든요. image-rendering: pixelated는 작은 그림을 확대해도 뭉개지지 않고 픽셀 느낌을 유지해 주는 속성이에요.

여러 마리를 줄 세우는 요령

캐릭터가 여럿이면 CSS 변수가 유용해요. 각 요소에 --i라는 번호를 주고 animation-delay: calc(var(--i) * -1.2s)처럼 음수 지연을 걸면, 처음부터 서로 다른 위치에서 걷고 있는 것처럼 보여요. 왼쪽으로 돌아설 때는 scaleX(-1)로 이미지를 뒤집으면 되니 그림을 따로 그릴 필요도 없고요.

다만 알아둘 한계가 있어요. CSS에는 '벽에 닿으면 돌아선다' 같은 판단 능력이 없어요. 그래서 CSS만으로 만든 장면은 실시간으로 반응하는 게임이라기보다, 언제 어디로 움직일지 미리 짜둔 안무에 가까워요. @keyframes의 퍼센트 구간으로 걷기, 떨어지기, 땅 파기를 시간표처럼 이어 붙이는 거죠.

성능은 이렇게 생각하면 돼요

브라우저는 화면을 그릴 때 배치를 계산하고(레이아웃), 색을 칠하고(페인트), 층을 합치는(합성) 단계를 거쳐요. transform과 opacity는 보통 마지막 합성 단계에서 처리돼서 가벼운 편이고, background-position을 바꾸면 다시 칠하는 작업이 생겨요. 캐릭터 몇 마리라면 문제없지만 수백 마리라면 개발자 도구의 Performance 탭에서 꼭 측정해 보세요. 이럴 땐 overflow: hidden인 창 안에서 스프라이트 이미지를 transform으로 옮기는 방법도 시도해 볼 만해요. 움직임에 민감한 사용자를 위해 prefers-reduced-motion 설정을 존중하는 것도 잊지 마시고요.

다른 기술과 비교하면

단순 반복이라면 GIF나 애니메이션 WebP가 가장 쉽지만 속도나 타이밍을 코드로 제어할 수 없어요. CSS는 자바스크립트 없이 가볍게 돌아가서 로딩 화면이나 작은 장식에 잘 맞아요. 사용자 입력에 반응하고 충돌을 판정해야 한다면 Canvas로 가는 게 자연스럽고, 스프라이트가 아주 많다면 WebGL 기반의 PixiJS 같은 도구가 유리해요. 디자이너가 만든 벡터 애니메이션을 그대로 쓰고 싶다면 Lottie나 Rive가 잘 맞고요. CSS로 어디까지 표현할 수 있는지 실험하는 문화도 오래됐어요. Diana Smith의 Pure CSS Francine이나 Lynn Fisher의 A Single Div가 대표적이죠.

한국 개발자에게 주는 시사점

이 기법은 장난감처럼 보여도 실무에서 꽤 쓸모 있어요. 404 페이지, 로딩 화면, 모바일 이벤트 페이지처럼 작은 재미를 주고 싶은 곳에 라이브러리 없이 바로 넣을 수 있거든요. 주니어 개발자라면 학습 과제로도 좋아요. 캐릭터 한 마리를 걷게 만들다 보면 렌더링 과정과 애니메이션 타이밍을 몸으로 익히게 되니까요. 다만 실제 게임의 캐릭터 이미지는 저작권이 있으니, 서비스에 넣을 때는 직접 그린 그림이나 사용이 허가된 에셋을 쓰세요.

마무리

한 줄로 정리하면, 스프라이트 시트와 steps()만 알면 CSS로도 픽셀 캐릭터에 생명을 불어넣을 수 있어요. 여러분은 서비스의 어떤 화면에 이런 작은 재미를 넣어보고 싶으신가요? CSS로 만들어 본 재미있는 실험이 있다면 들려주세요.


🔗 출처: Hacker News

SOURCE · HACKER NEWS
원문 전체 보기 → https://markblah.github.io/lemmings/
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기 →
처리 중...