영상 스타일 적용 08 | 16-bit Pixel RPG로 초음파 거리 측정을 픽셀 미션 영상으로 바꾸기

초음파 탐험가의 거리 미션

영상 스타일 적용 · 사례 08 · 16-bit Pixel RPG × 아두이노 초음파 센서

초음파 센서는 소리가 벽까지 갔다가 돌아온 시간을 잽니다. 그래서 그 시간으로 구한 거리는 왕복 거리이고, 벽까지의 거리를 알려면 반드시 2로 나눠야 합니다. 이 글은 제 교재의 초음파 거리 측정 내용을 90년대 콘솔 RPG처럼 생긴 100초짜리 픽셀 미션 영상으로 만든 과정입니다. 원작 스타일, 교재 근거, 제작 방법, 실제로 쓴 프롬프트, 완성 영상과 검산 기록을 차례로 정리했습니다.

무엇이 달라졌나

교재 186~187쪽은 '왕복의 함정'을 메아리 그림과 공식으로 설명합니다. 영상에서는 이 함정을 게임의 메뉴 선택으로 바꿨습니다. 벽까지 거리를 묻는 메뉴에 17 cm와 34 cm가 나오고, 34 cm를 고르면 화면이 흔들리며 "그건 왕복 거리!"라는 창이 뜹니다. 이어서 갈 때와 올 때의 화살표가 다시 그려집니다. 정답을 고르면 아이템 획득음과 함께 "34 ÷ 2 = 17 cm"가 표시됩니다.

두 번째로 달라진 점은 에코가 돌아오지 않을 때입니다. 교재 코드는 이때 0을 출력합니다. 영상은 이 0을 "0 cm 거리"가 아니라 "측정 실패"로 정리합니다. 화면 색이 한 단계씩 어두워지고, 완전한 무음 한 박이 지난 뒤 '측정 실패' 창이 뜹니다.

완성 영상의 한 장면입니다. 영상 정보: 1920×1080 · 24fps · 100초 · 음성 내레이션 없음(대화창 자막형) · 직접 합성한 칩튠과 효과음. 화면 속 메뉴 선택은 연출이며, 클릭해서 조작하는 게임은 아닙니다.

원본 스타일 예시

우리 사례 번호사례 08 (AI오토마타 '영상 스타일 적용' 연재 번호이며 원본 사이트의 공식 순번이 아닙니다)
원본 스타일16-bit Pixel RPG · 식별자 pixel-rpg · 분류 Games
원작 예시 영상The Last Save Point (0:54)
원작자Lemomo / LemoLab (Lemo-Opuscar 프로젝트)
확인한 버전저장소 커밋 413a6bd(2026-10-24), STYLE.md 마지막 변경 3961ddb · 확인일 2026-10-25

위 영상은 원작자 Lemomo/LemoLab의 작품입니다(데모 영상 CC BY 4.0). 재업로드하지 않고 공식 주소를 연결했습니다.

원작은 마지막 세이브 포인트 앞에 선 주인공이 세이브 파일을 열어 지난 여정을 떠올리는 54초 영상입니다. 320×180 픽셀 화면, 대화창 자막, 세이브 파일 목록, 시대별로 색 수가 줄어드는 회상이 특징입니다. 스타일 지침이 강조하는 점은 게임의 시스템 자체를 이야기의 언어로 쓰라는 것입니다. 이번 영상은 그 가운데 메뉴, 시스템 창, 상태창, 팔레트 변화를 가져왔고, 원작의 이야기·캐릭터·세이브 회상 구조는 쓰지 않았습니다.

교재 근거

교재『주니어 공학 교실 아두이노의 기초』 185~195쪽
그림그림 3.9 초음파 센서(HC-SR04, 185쪽) · 그림 3.10 트리거와 에코의 역할(186쪽) · 그림 3.11 실제 거리 계산(187쪽)
회로(188쪽)Trig → 4번 핀, Echo → 3번 핀, Vcc → 5V, Gnd → GND (회로 그림의 선을 확대해 확인)
코드(190쪽)CODE 3.5 거리 측정기 코드, 19줄 long dist = (pulseIn(ECHO, HIGH)) / 58.2;
58.2 설명(194~195쪽)340 m/s로 계산하면 1 ÷ 0.017 ≈ 58.82. 약 20℃의 약 343 m/s를 기준으로 하면 약 58.2
학습 목표① 센서가 잰 시간이 왕복 시간임을 설명한다. ② μs와 m/s를 맞춰 거리를 cm로 계산한다. ③ 교재 코드의 58.2와 long의 소수점 버림을 이해한다. ④ 에코가 없을 때의 0을 거리와 구분한다.
TR HC-SR04 벽 갈 때 d올 때 d Echo HIGH 시간 t 동안 소리가 간 길 = 2d 그래서 d = c × t ÷ 2 초음파는 눈에 보이지 않습니다. 화살표는 소리가 간 길을 그린 모형입니다.
자체 도식 ① 왕복 경로도. 센서가 재는 Echo 시간 동안 소리는 벽까지 갔다가 돌아옵니다.

교재 187쪽의 공식 '거리(cm) = (시간 × 340) / 2'는 시간 단위를 적지 않았습니다. 그래서 영상의 계산 장면은 단위를 끝까지 씁니다. 먼저 1000 μs를 0.001초로 바꾸고, 340 m/s를 곱해 왕복 0.34 m를 구한 다음 반으로 나눠 0.17 m, 곧 17 cm를 얻습니다. 마이크로초를 그대로 쓰려면 '시간(μs) × 340 ÷ 20000'으로 하면 됩니다.

340 m/s 계산과 교재 코드의 58.2(약 343 m/s 기준)는 서로 다른 화면에서 보여 줍니다. 같은 1000 μs라도 343 m/s로 계산하면 17.15 cm가 됩니다. 두 값을 한 화면에 섞으면 학생이 어느 쪽이 맞는지 헷갈리기 때문입니다.

단계340 m/s (설명 계산)교재 코드 (58.2) ① 시간t = 1000 μs = 0.001 spulseIn → 1000 ② 왕복 거리340 × 0.001 = 0.34 m— ③ ÷ 20.34 ÷ 2 = 0.17 m = 17 cm1000 ÷ 58.2 = 17.18… ④ 한 줄 식cm = μs × 340 ÷ 20000cm = μs ÷ 58.2 ⑤ 저장17 cmlong → 17 (소수 버림) ⑥ 에코 없음계산하지 않음0 → '측정 실패'로 처리 58.2는 약 343 m/s(약 20℃) 기준. 340 m/s면 58.82
자체 도식 ② 시간 단위 변환과 거리 계산표. 1000 μs는 계산 확인용 가상 입력이며 실측값이 아닙니다.

실제 적용 방법

원본 저장소에는 설치형 스킬이 있지만 이번 작업은 그 스킬을 설치하거나 호출하지 않았습니다. 저장소를 내려받아 STYLE.md 전문과 원작자의 작업 안내(AGENTS.md·DIRECTOR.md·TECHNIQUE.md)를 읽고 그 규칙대로 직접 만들었습니다. 정확히 말하면 '스타일 지침을 읽어 적용'한 사례입니다.

원본의 JavaScript 렌더링 엔진도 쓰지 않았습니다. 지침에 적힌 규칙대로 Python 렌더러를 새로 작성했습니다. 320×180 크기의 팔레트 번호 배열에 그림을 그리고, 번호를 색으로 바꾼 뒤 6배로 늘려 1920×1080을 만듭니다. 색은 자체 32색만 쓰고, 그라디언트는 반투명 대신 점무늬(디더)로 표현합니다. 초음파 경로의 청록색은 어떤 페이드에도 바뀌지 않는 '보호색'으로 정했습니다.

항목이번 사례에서 확인된 값
AIClaude (이 작업 세션 설정 모델 claude-opus-5-5)
그림·영상Python 3.13, NumPy, Pillow, ffmpeg 6.1.1 (최근접 확대 ×6, H.264)
한국어 픽셀 글꼴Galmuri v2.40.4 (Lee Minseo, SIL OFL 1.1) — Galmuri11 12px. 320×180에서 한글이 깨지지 않는지 먼저 확인
소리음성 없음. 칩튠·효과음을 NumPy로 직접 합성(샘플·기존 게임 음원 없음)
코드 검증avr-gcc 7.3.0 + Arduino AVR 코어, simavr 1.6 시뮬레이터
비용·계정유료 결제·새 계정 없음. Claude 요금제 조건은 확인하지 않음
원본 규칙(STYLE.md)적용한 장면변형과 그 이유
320×180, 정수 배율 확대전 장면그대로 (×6)
제한된 팔레트, 디더 그라디언트, 알파 금지전 장면원작의 공개 팔레트 대신 자체 32색
보호색초음파 경로·Echo 신호에코 청록 1색. 에코가 오지 않는 장면에서는 이 색이 사라짐
대화창이 곧 자막전 대사원작의 자체 글꼴은 한글이 없어 Galmuri로 바꿈, 타이핑은 한국어에 맞춰 초당 16자
게임 UI로 이야기퀘스트 창, 상태창, 메뉴, 저장 화면원작의 세이브 파일 회상 대신 퀘스트 한 편 구조
팔레트 = 감정교재 코드 방(세피아 교체), 측정 실패(4단계 페이드)시대별 색 깊이 변화는 쓰지 않음(내용과 무관)
칩튠·메아리, 진짜 무음전 구간, 90.2~91.0초음성 대신 글자 블립. 초음파를 '삐' 소리로 들려주지 않음

입력 파일과 제작 단계

  1. 교재 쪽 확인 — PDF 183~197쪽을 이미지로 렌더링해 그림·식·코드를 대조했습니다. 188쪽 회로 그림은 300dpi로 확대해 초록 선(Trig)이 4번, 주황 선(Echo)이 3번 핀에 연결된 것을 확인했습니다.
  2. 원본 확인 — STYLE.md 전문을 읽고 커밋과 해시를 기록했습니다. 원작 영상은 1초 간격으로 모든 장면을 확인했고, 라이선스와 CREDITS를 읽었습니다.
  3. 글꼴 점검 — 한국어 픽셀 글꼴 Galmuri의 라이선스(OFL)를 확인한 뒤, 320×180 화면에서 안티앨리어싱 없이 또렷하게 찍히는 크기(12px)를 골랐습니다.
  4. 구성안 작성 — 후보 구조 세 가지 가운데 '퀘스트 한 편'을 골라 장면표를 썼습니다. 원작 데모 설명은 이 구성안을 쓴 뒤에 기법만 참고했습니다.
  5. 렌더링 — 장면별 그림 함수, 대화창, 효과음 이벤트를 한 시간표(film.py)에서 관리하고 100초를 렌더링했습니다.
  6. 검증과 수정 — 계산·문자열·자막 시간을 스크립트로 검사하고, 교재 코드를 컴파일해 시뮬레이터로 실행했습니다. 전 구간 프레임을 보고 고친 뒤 다시 렌더링했습니다.

최초·점검·수정·확장 프롬프트 전문

자체 응용문아래 네 개는 AI오토마타가 이번 사례를 위해 쓴 요청문입니다. 원본 STYLE.md를 번역한 글이 아니며, 원본 지침은 위 링크로 첨부해 사용합니다.

1. 최초 제작 프롬프트
이 폴더의 lemo-opuscar 저장소와 styles/pixel-rpg/STYLE.md를 끝까지 읽고 작업하라.
사용한 모델·실행 환경·읽은 파일과 커밋을 먼저 밝혀라. 파일을 못 읽으면 추정으로 대체하지 말라.

[교재 입력 — 원문 이미지로 대조할 것]
『주니어 공학 교실 아두이노의 기초』 185~195쪽: 그림 3.9 HC-SR04, 그림 3.10 Trig·Echo 역할, 그림 3.11 실제 거리 계산,
188쪽 회로(Trig→4번 핀, Echo→3번 핀, Vcc→5V, Gnd→GND), 190쪽 CODE 3.5(long dist = (pulseIn(ECHO, HIGH)) / 58.2;),
191~195쪽 pulseIn·delayMicroseconds·58.2 설명(340 m/s로는 58.82, 약 20℃·343 m/s 기준으로 약 58.2).
회로 그림의 선 색과 핀 번호를 이미지로 직접 확인하라. 흔히 쓰는 핀 배치를 원문이라고 추정하지 말라.

[목표] "센서가 잰 시간은 왕복 시간이라 ÷2를 해야 한다"를 75~100초의 독창적 픽셀 게임 미션으로 보여 준다.
- 캐릭터는 센서를 점검하는 안내자다. 초음파를 눈에 보이는 것처럼 그리지 말고 '그림으로 나타낸 모형'임을 밝힌다.
- 이동 장면에 '시간 확대 모형'을 계속 표시하고, 화면 속 초를 실제 마이크로초라고 하지 않는다.
- 가상 입력 Echo=1000 μs, c=340 m/s로 d = 340×0.001÷2 = 0.17 m = 17 cm를 단위와 함께 계산한다. 실측값이 아님을 화면에 적는다.
- 교재 코드의 58.2(약 343 m/s)와 long의 소수점 버림(17.18…→17)은 340 계산과 다른 화면에서 설명한다. 340과 343을 한 화면에 섞지 않는다.
- 메뉴 17 cm / 34 cm에서 오답이면 왕복 경로를 다시 그린다. 실제로 누를 수 없으면 '조작형 게임'이라 쓰지 않는다.
- 에코가 오지 않으면 pulseIn이 0을 돌려주고 교재 코드는 0을 출력한다. 이것을 0 cm 거리로 보이지 말고 '측정 실패'로 정리한다.
- 장면: 0~12초 미션 → 12~35초 송신·반사·수신(왕복 2d) → 35~60초 계산 → 60~80초 메뉴 → 80~100초 미수신 정리.

[스타일] STYLE.md를 고정 규칙으로: 320×180 인덱스 프레임버퍼, ×6 최근접 확대, 32색 이내 팔레트(기존 게임·공개 팔레트 복제 금지 시 자체 팔레트),
디더 그라디언트(알파 금지), 팔레트 교체로 분위기 변화, 보호색 1개, 대화창이 곧 자막(층 테두리·디더 채움·32×32 초상화·타이핑·▼),
상단 시스템 창, 메뉴 커서(머뭇거릴 때 멈춤), 모자이크 전환, 화면 흔들림 3-2-1px, 팔레트 단계 페이드. 기존 게임의 이름·캐릭터·UI·글꼴·음악 금지.
한국어 픽셀 글꼴은 라이선스와 320×180에서의 가독성을 먼저 확인하고, 원본의 '자체 글꼴' 규칙을 바꾸면 기록하라.

[소리] 칩튠을 직접 작곡·합성(펄스·4비트 삼각·LFSR 노이즈·메아리). 음성 TTS는 넣지 말고 글자 블립만. 초음파를 들리는 '삐' 소리로 표현하지 말라.
[산출] 1920×1080 24fps MP4, 렌더링 소스, TREATMENT.md, SRT, 대표 프레임 3장, 검산 기록. TREATMENT.md를 먼저 쓰고 그 뒤에만 DEMO.md를 읽어라.
2. 점검 프롬프트
만든 영상과 소스를 아래 순서로 점검하고 통과/실패를 숫자로 표에 남겨라. 이전 사례의 통과 기록을 가져오지 말라.
1) 계산: 거리(cm)=시간(μs)×c/20000으로 340 m/s 1000 μs→17 cm, 2000 μs→34 cm, 343 m/s 1000 μs→17.15 cm. 20000÷58.2, 1000÷58.2와 long 결과.
2) 화면 문자열: 340 장면과 343/58.2 장면이 섞이지 않았는지, '가상 입력·실측 아님', '시간 확대 모형' 표기가 있는지.
3) 교재 원문 대조: CODE 3.5 19줄, #define ECHO 3 / TRIG 4, 188쪽 회로 그림의 선.
4) 코드 실행: 교재 코드를 UNO용으로 컴파일하고, 시뮬레이터에 가상 Echo 펄스(1000/2000 μs, 없음)를 넣어 시리얼 출력을 확인하라.
   컴파일·시뮬레이션·회로 시뮬레이션·실물 실험을 각각 따로 적고, 하지 않은 것은 하지 않았다고 적어라.
5) 자막: 대화창마다 표시 시간, 타이핑 후 유지 시간, 줄 너비.
6) MP4: 크기·fps·프레임 수·길이, blackdetect, ebur128, silencedetect. 1초 간격 전 구간과 주요 순간 0.2초 간격 확인.
3. 수정 프롬프트 (이번 제작에서 실제로 낸 요청)
1) 타이밍 창이 초음파 호·화살표와 겹치고 보드 위 "4 3" 숫자가 "43"으로 읽힌다 → 센서를 아래로 옮기고 호를 납작하게, 보드 숫자는 지우고 선 옆 'Trig→4 / Echo→3'만 남겨라.
2) 대화창 20개 중 8개가 읽기 시간 기준(공백 제외 글자÷9+1초, 타이핑 후 1초 이상 유지)에 못 미친다 → 100초를 넘기지 말고 문장을 줄여라.
3) 3장 큰 '17 cm'가 마지막 줄(공식)과 겹친다 → 마지막 줄이 나올 때 큰 글씨를 작은 금색 줄로 바꿔라.
4) 페이드 장면에서 대화창 글자가 함께 어두워져 안 읽힌다 → 글자는 보호색 흰색으로.
5) "측정 실패" 창 뒤로 타이밍 창이 비친다 → 그 장면에서는 타이밍 창을 숨겨라.
6) "(기본 최대 1초)" 글자가 진행 막대와 겹친다 → 창 오른쪽 위로 옮겨라.
4. 확장 프롬프트 (다음 실습용, 아직 실행 전)
같은 스타일·엔진으로 교재 196~197쪽 '자동차 후방 감지기'(CODE 3.6, 부저 11번 핀)를 이어서 만들어라.
- 회로 그림·코드를 먼저 이미지로 대조한다. 거리 구간(10/20/30 cm)마다 경고음 간격이 달라지는 것을 '레벨 표시창'으로 보여 준다.
- dist가 0(에코 없음)일 때 CODE 3.6이 'dist < 10' 조건에 걸려 가장 급한 경고를 울린다는 점을 계산으로 확인하고, 측정 실패를 따로 처리하는 확장 코드를 제안·컴파일·시뮬레이션하라.
- 소리 박자는 코드의 delay 값과 실제로 같게 하되, 화면 이동은 시간 확대 모형으로 표시한다. 길이 60~80초, 자막형.

실제 영상과 대표 프레임

아래 세 장은 완성 영상에서 뽑은 프레임입니다. 원작과 그림·캐릭터·음악을 공유하지 않고, 픽셀 화면과 게임 UI라는 '문법'만 같습니다.

송신·반사·수신 장면: 왕복 = 2d, 갈 때 d + 올 때 d
대표프레임 01 (27.6초) — 시간 확대 모형. 타이밍 창의 Echo HIGH 길이가 왕복 시간 t이고, 아래 화살표는 갈 때 d와 올 때 d입니다.
상태창 거리 계산: 1000 μs, 340 m/s, 0.34 m, 0.17 m, 17 cm
대표프레임 02 (49.6초) — 가상 입력 1000 μs로 단위를 맞춰 계산한 상태창.
측정 실패 화면: 에코 없음은 0 cm가 아님
대표프레임 03 (93.6초) — 에코가 오지 않아 pulseIn이 0을 돌려준 경우를 '측정 실패'로 정리한 화면.

검산·오류·연습

검산 결과

  • 계산(90개 항목 통과): 340 m/s에서 1000 μs → 17 cm, 2000 μs → 34 cm. 343 m/s에서 1000 μs → 17.15 cm. 20000 ÷ 58.2 = 343.6 m/s. 1000 ÷ 58.2 = 17.18… → long 17. 340 장면과 58.2 장면이 섞이지 않았는지도 확인했습니다.
  • 교재 대조: CODE 3.5 19줄과 핀 정의(ECHO 3, TRIG 4)가 교재 원문과 일치합니다.
  • 컴파일: 교재 코드를 Arduino UNO(ATmega328P)용으로 컴파일했습니다(3,986바이트).
  • 시뮬레이션: 시뮬레이터에 가상 Echo 펄스를 넣었더니 1000 μs → 17, 2000 μs → 34, 에코 없음 → 0이 출력되었습니다. 에코가 없을 때는 pulseIn이 최대 1초를 기다리느라 0이 약 0.8초 간격으로 찍혔습니다.
  • 하지 않은 것: 실물 센서 실험, 회로 시뮬레이션, 온도별 실측은 하지 않았습니다. 영상의 숫자는 모두 계산 확인용 가상 입력입니다.

제작 중 실제로 생긴 오류 6건

오류해결
타이밍 창이 초음파 그림과 겹치고, 보드 위 핀 숫자 '4 3'이 '43'으로 읽힘센서와 초음파 호를 재배치하고 보드 숫자를 지워, 선 옆의 'Trig→4 / Echo→3'만 남김
대화창 20개 중 8개가 읽을 시간이 부족함100초 안에서 문장을 줄여 20개 모두 기준 통과
계산 화면의 큰 '17 cm'와 마지막 공식 줄이 겹침공식 줄이 나올 때 큰 글씨를 작은 금색 줄로 바꿈
화면이 어두워지는 단계에서 대화 글자도 같이 어두워짐대화 글자를 보호색 흰색으로 바꿈
'측정 실패' 창 뒤로 타이밍 창이 비침그 장면에서 타이밍 창을 숨김
'(기본 최대 1초)' 글자가 진행 막대와 겹침최종 파일 전수 확인에서 발견, 위치를 옮기고 다시 렌더링

독자 연습과 평가 기준

  1. Echo 시간이 1500 μs일 때 340 m/s로 거리를 구하세요. (기준: 340 × 0.0015 ÷ 2 = 0.255 m = 25.5 cm)
  2. 같은 1500 μs를 교재 코드에 넣으면 시리얼 모니터에 무엇이 찍힐까요? (기준: 1500 ÷ 58.2 = 25.77… → long 25)
  3. 센서를 벽에서 34 cm 떨어뜨리면 Echo 시간은 대략 얼마일까요(340 m/s)? (기준: 왕복 0.68 m ÷ 340 = 2000 μs)
  4. 교재 코드에 에코가 없을 때를 따로 처리하는 if 문을 추가해 보세요. (기준: if (dist == 0)일 때 '측정 실패'를 출력하고, 0 cm로 해석하지 않을 것)

한계

이 영상은 원본 라이브러리의 엔진이 아니라 지침을 읽고 새로 작성한 렌더러로 만들었습니다. 그래서 원작보다 캐릭터 동작이 단순합니다(숨쉬기와 가리키기만 있음). 내레이션이 없으므로 수업에서는 교수자가 함께 설명하는 방식을 권합니다. 교재 코드처럼 0을 측정 실패로 판단하는 방법은 가장 단순한 처리입니다. 실제 센서에서는 너무 가까운 거리나 비스듬한 면에서도 값이 불안정할 수 있습니다.

출처

원작 영상은 Lemomo/LemoLab의 작품이며 공개 주소로 연결만 했습니다. 이 글의 영상·도식·한국어 프롬프트는 AI오토마타가 새로 만들었고, 원작의 캐릭터·그림·음악은 쓰지 않았습니다. 교재 원본 그림과 PDF는 싣지 않았습니다.

자료 ID: ART-STYLE-08 · 영상 스타일 적용 사례 08

댓글

이 블로그의 인기 게시물

📄 [제미나이 활용법 3편] PDF 보고서를 1분 안에 요약하는 방법

📄 [업무 자동화] 생성형 AI로 10초 만에 회의록 완성하는 법

[제미나이 활용법 2편] 복잡한 뉴스 기사, 5분 만에 회의 자료로 바꾸는 법