코스 6: Five Functions - 함수와 이벤트 처리
코스 개요
이 코스에서 학생들은 함수의 고급 활용법과 이벤트 기반 프로그래밍을 배웁니다. 게임은 사용자 입력, 충돌, 시간 경과 등 다양한 이벤트에 반응해야 합니다. 이 코스를 통해 학생들은 실제 게임처럼 동작하는 인터랙티브 프로그램을 만들 수 있게 됩니다.
예상 소요 시간: 12~24시간
소요 시간은 학생의 학년, 사전 경험, 학습 속도에 따라 크게 달라집니다. 또한 기본 개념만 익히고 넘어가는 경우와 추가 실습 문제나 창의적 프로젝트를 더 진행하는 경우에 따라서도 차이가 납니다. 위 시간은 평균적인 범위이며, 자녀의 페이스에 맞추어 유연하게 진행하시기 바랍니다.
어떤 능력을 키우게 되나요?
"입력 데이터 → 처리 → 출력 데이터"의 데이터 파이프라인(Data Pipeline) 사고를 훈련합니다. 함수는 데이터를 받아서 변환하고 결과를 내보내는 데이터 처리 단위입니다. 현대 데이터 시스템은 수많은 함수가 연결된 파이프라인으로 구성됩니다.
어떤 원리를 배우나요?
- (데이터 변환) 함수는 입력 데이터를 받아 처리 후 출력 데이터를 반환합니다.
calculate_tax(price)→ 세금 계산 결과처럼, 데이터를 변환하는 블록을 만드는 법을 배웁니다. - (이벤트 기반 처리) "사용자가 클릭하면" "데이터가 도착하면" 같은 이벤트에 반응하여 데이터를 처리하는 구조를 배웁니다. 웹사이트, 앱, IoT 시스템 모두 이벤트 기반으로 동작합니다.
AI 시대 사고력: 컴퓨팅 (문제해결) | 데이터 기반 | 확률적 사고력
컴퓨팅 사고력 (Computational Thinking)
| 스킬 | 설명 | 활동 예시 |
|---|---|---|
| 📦 추상화 | 반복 작업을 함수로 묶기 | draw_star() 함수 정의 |
| 🧱 모듈화 | 독립적인 기능 단위로 분리 | 입력 처리, 그리기, 충돌 검사 분리 |
| ⚡ 이벤트 처리 | 특정 행동에 반응 | "스페이스바 누르면 점프" |
| 🔁 재귀적 사고 | 함수가 자기 자신 호출 | 미로 생성, 트리 구조 탐색 |
수학적 연결고리
| 수학 개념 | 프로그래밍 적용 | 학습 효과 |
|---|---|---|
| 함수 f(x) | def area(r): return 3.14 * r * r |
입력 → 출력 관계 |
| 매개변수 | draw_square(size) |
함수의 독립변수 |
| 반환값 | return result |
함수의 종속변수 |
| 합성함수 | f(g(x)) |
함수 안에서 다른 함수 호출 |
함수 = 수학의 함수
이벤트 기반 사고
| 이벤트 (원인) | 콜백 함수 (결과) | 게임 예시 |
|---|---|---|
| 키보드 입력 | def input(key): |
"W 키 → 전진" |
| 마우스 클릭 | def on_click(): |
"클릭 → 총알 발사" |
| 시간 경과 | def update(): |
"매 프레임 → 위치 업데이트" |
| 충돌 발생 | def on_collision(): |
"적과 닿음 → 데미지" |
재귀의 수학적 개념
💻 코드 예시 & 시각화
예시 1: 함수 정의와 호출
# 함수 정의
def greet(name):
"""인사하는 함수"""
return f"안녕하세요, {name}님!"
# 함수 호출
print(greet("철수")) # 안녕하세요, 철수님!
print(greet("영희")) # 안녕하세요, 영희님!
함수 = 기계 (입력 → 처리 → 출력):
입력 (Input)
│
▼
┌─────────────────┐
│ greet 함수 │
│ ┌───────────┐ │
│ │ name 저장 │ │
│ │ 문자열 결합│ │
│ │ return │ │
│ └───────────┘ │
└────────┬────────┘
│
▼
출력 (Output)
greet("철수") → "안녕하세요, 철수님!"
예시 2: 매개변수가 있는 함수
from ursina import *
app = Ursina()
def create_cube(x, y, z, cube_color):
"""지정한 위치와 색상으로 큐브 생성"""
return Entity(
model='cube',
color=cube_color,
position=(x, y, z)
)
# 함수 호출로 여러 큐브 생성
create_cube(0, 0, 0, color.red)
create_cube(2, 0, 0, color.blue)
create_cube(4, 0, 0, color.green)
create_cube(0, 2, 0, color.yellow)
app.run()
함수 재사용의 힘:
함수 없이: 함수 사용:
───────────────────── ─────────────────────
Entity(model='cube', create_cube(0,0,0,red)
color=red, create_cube(2,0,0,blue)
position=(0,0,0)) create_cube(4,0,0,green)
Entity(model='cube', create_cube(0,2,0,yellow)
color=blue,
position=(2,0,0))
Entity(model='cube',
color=green,
position=(4,0,0))
...
→ 코드 길이: 20줄 vs 4줄!
예시 3: 이벤트 처리 - input() 함수
from ursina import *
app = Ursina()
player = Entity(model='cube', color=color.orange)
def input(key):
"""키보드 입력 이벤트 처리"""
if key == 'space':
print("점프!")
player.y += 2
if key == 'r':
print("리셋!")
player.position = (0, 0, 0)
app.run()
이벤트 기반 프로그래밍:
flowchart TD
A[게임 실행 중<br/>키보드 입력 대기] --> B{어떤 키?}
B -->|space| C[점프! 🦘]
B -->|r| D[리셋! 🔄]
B -->|다른 키| E[무시]
C --> A
D --> A
E --> A
예시 4: update() 함수 - 게임 루프
from ursina import *
app = Ursina()
player = Entity(model='cube', color=color.red)
speed = 5
def update():
"""매 프레임마다 호출 (초당 60번)"""
# WASD 이동
if held_keys['w']:
player.z += speed * time.dt
if held_keys['s']:
player.z -= speed * time.dt
if held_keys['a']:
player.x -= speed * time.dt
if held_keys['d']:
player.x += speed * time.dt
app.run()
게임 루프 시각화:
flowchart TD
A[게임 시작] --> B[update 호출]
B --> C[1. 입력 확인<br/>held_keys]
C --> D[2. 위치 업데이트]
D --> E[3. 충돌 검사]
E --> F[4. 화면 그리기]
F --> G[1/60초 대기]
G --> B
style B fill:#f9f,stroke:#333,stroke-width:2px
초당 60번 반복 = 60 FPS
예시 5: 콜백 함수
from ursina import *
app = Ursina()
def on_click_red():
print("빨간 버튼 클릭!")
def on_click_blue():
print("파란 버튼 클릭!")
# 버튼에 콜백 함수 연결
red_button = Button(
text='빨강',
color=color.red,
on_click=on_click_red # ← 콜백 함수
)
blue_button = Button(
text='파랑',
color=color.blue,
position=(0, -0.1),
on_click=on_click_blue # ← 콜백 함수
)
app.run()
콜백 함수의 원리:
버튼 생성 시:
┌─────────────────┐
│ red_button │
│ on_click = ──────────→ on_click_red 함수
└─────────────────┘
클릭 이벤트 발생:
┌─────────────────┐ ┌─────────────────┐
│ 마우스 클릭! │ ───→ │ on_click_red() │
│ red_button 위 │ │ 실행됨! │
└─────────────────┘ └─────────────────┘
"나중에 이 일이 일어나면, 이 함수를 실행해줘"
예시 6: 재귀 함수 - 프랙탈 나무
from turtle import *
def draw_tree(length):
"""재귀적으로 나무 그리기"""
if length < 10: # 기저 조건
return
forward(length)
right(30)
draw_tree(length * 0.7) # 오른쪽 가지 (재귀)
left(60)
draw_tree(length * 0.7) # 왼쪽 가지 (재귀)
right(30)
backward(length)
# 나무 그리기 시작
left(90)
draw_tree(100)
재귀 호출 과정:
프로젝트 1: Bullet Hell - 함수와 이벤트
A. 소개
| 항목 | 내용 |
|---|---|
| 무엇을 배우나요? | 탄막 게임의 구조 이해 |
| 핵심 개념 | 게임 루프, 객체 생성, 이동 패턴 |
Bullet Hell(탄막 게임)은 대량의 총알이 패턴을 그리며 쏟아지는 장르입니다. 학생들은 게임이 매 프레임마다 반복되는 루프로 동작한다는 것을 이해합니다. 수십, 수백 개의 총알을 효율적으로 관리하려면 리스트와 함수의 조합이 필수입니다. 이 프로젝트는 이전에 배운 개념들을 실제 게임으로 통합하는 경험을 제공합니다. 완성된 게임은 플레이하는 재미와 함께 성취감을 줍니다.
B. 기본 개념 - 이벤트 처리
| 항목 | 내용 |
|---|---|
| 무엇을 배우나요? | 키보드/마우스 입력에 반응하기 |
| 핵심 개념 | 이벤트, 콜백 함수, 입력 처리 |
def input(key):는 키보드 입력이 있을 때 자동으로 호출되는 함수입니다. 학생들은 프로그램이 사용자의 행동을 기다리고 반응한다는 것을 배웁니다. "스페이스바를 누르면 총알 발사", "화살표 키로 이동" 같은 게임 컨트롤을 구현합니다. 이것은 이벤트 기반 프로그래밍의 핵심으로, 웹 개발, 앱 개발에서도 동일한 패턴이 사용됩니다. 학생들은 인터랙티브 프로그램의 기본 구조를 이해하게 됩니다.
C. 코드 이해 - update 함수
| 항목 | 내용 |
|---|---|
| 무엇을 배우나요? | 매 프레임마다 실행되는 로직 |
| 핵심 개념 | 게임 루프, 프레임, 델타 타임 |
def update():는 매 프레임(초당 60번 정도) 자동으로 호출됩니다. 게임의 모든 움직임, 충돌 체크, 상태 업데이트가 여기서 이루어집니다. 학생들은 게임이 연속적인 스냅샷의 연속이라는 것을 이해합니다 - 마치 만화 책처럼요. time.dt를 사용하여 프레임 속도에 관계없이 일정한 속도로 움직이게 합니다. 이것은 모든 실시간 게임의 핵심 구조입니다.
D. 퀴즈
| 항목 | 내용 |
|---|---|
| 무엇을 배우나요? | 개념 이해도 확인 |
| 핵심 개념 | 자기 점검, 복습 |
퀴즈를 통해 핵심 개념을 정확히 이해했는지 확인합니다. 잘못 이해한 부분을 조기에 발견하고 교정할 수 있습니다. 프로그래밍에서 개념을 정확히 이해하는 것이 코드 작성보다 먼저입니다. 학생들은 자신의 학습 상태를 객관적으로 평가하는 습관을 기릅니다. 이것은 효과적인 학습에 필수적인 메타인지 능력입니다.
프로젝트 2: Column Graph - 콜백 함수와 딕셔너리
A-D. 콜백 함수와 데이터와 시각화
| 항목 | 내용 |
|---|---|
| 무엇을 배우나요? | 함수를 인자로 전달하기 |
| 핵심 개념 | 콜백 함수, 딕셔너리, 데이터와 시각화 |
콜백 함수는 "나중에 호출해줘"라고 등록하는 함수입니다. 버튼을 클릭했을 때, 애니메이션이 끝났을 때 등 특정 이벤트 발생 시 실행됩니다. 학생들은 함수가 변수처럼 전달될 수 있다는 강력한 개념을 배웁니다. 딕셔너리는 {"이름": "값"} 형태로 키-값 쌍을 저장하는 데이터 구조입니다. 이 프로젝트에서 데이터를 막대 그래프로 시각화하며 데이터 분석의 기초를 경험합니다.
프로젝트 3: Maze Timer - 재귀 함수와 지연 호출
A-D. 재귀와 타이머
| 항목 | 내용 |
|---|---|
| 무엇을 배우나요? | 함수가 자기 자신을 호출하기 |
| 핵심 개념 | 재귀, 기저 조건, 지연 실행 |
재귀 함수는 자기 자신을 호출하는 함수입니다. 미로 생성, 트리 구조 탐색 등 반복적인 하위 문제를 풀 때 우아한 해결책이 됩니다. 학생들은 기저 조건(종료 조건)이 없으면 무한히 호출된다는 것을 배웁니다. invoke(function, delay)로 일정 시간 후에 함수를 실행하는 지연 호출도 배웁니다. 이 개념은 타이머, 애니메이션 시퀀스, 턴 기반 게임 등에 널리 활용됩니다.
프로젝트 4: Shooter - 입력 처리와 충돌
A-D. 실시간 입력과 충돌 감지
| 항목 | 내용 |
|---|---|
| 무엇을 배우나요? | 슈팅 게임 메커니즘 구현 |
| 핵심 개념 | 입력 처리, 충돌 감지, 게임 상태 |
슈팅 게임은 입력 → 행동 → 결과의 빠른 피드백 루프입니다. held_keys['w']로 키가 눌려 있는지 지속적으로 확인합니다. 충돌 감지로 "총알이 적에게 맞았는지" 판단하고, 맞으면 적을 제거하고 점수를 올립니다. 학생들은 여러 시스템(입력, 물리, 점수)이 함께 동작하는 게임 구조를 이해합니다. 이 프로젝트는 이전에 배운 모든 개념을 실제 게임으로 통합하는 경험입니다.
이 코스를 마치면...
학습 성과
학생들은 다음 능력을 갖추게 됩니다:
- 이벤트 기반 프로그래밍의 패턴을 이해하고 활용할 수 있음
- 키보드/마우스 입력에 반응하는 프로그램을 만들 수 있음
- update 함수로 게임 루프를 구현할 수 있음
- 콜백 함수를 사용하여 비동기 동작을 처리할 수 있음
- 재귀 함수의 개념을 이해하고 간단한 예제에 적용할 수 있음
- 여러 시스템이 통합된 게임을 설계하고 구현할 수 있음