콘텐츠로 이동

코스 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)) 함수 안에서 다른 함수 호출

함수 = 수학의 함수

수학:  f(x) = x² + 2x + 1

프로그래밍:
def f(x):
    return x**2 + 2*x + 1

호출:
f(3) → 9 + 6 + 1 = 16

이벤트 기반 사고

이벤트 (원인) 콜백 함수 (결과) 게임 예시
키보드 입력 def input(key): "W 키 → 전진"
마우스 클릭 def on_click(): "클릭 → 총알 발사"
시간 경과 def update(): "매 프레임 → 위치 업데이트"
충돌 발생 def on_collision(): "적과 닿음 → 데미지"

재귀의 수학적 개념

팩토리얼: n! = n × (n-1)!

def factorial(n):
    if n == 1:       # 기저 조건
        return 1
    return n * factorial(n-1)  # 재귀 호출

factorial(5) = 5 × 4 × 3 × 2 × 1 = 120
💻 코드 예시 & 시각화

예시 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)

재귀 호출 과정:

draw_tree(100)
├── forward(100)
├── right(30)
├── draw_tree(70)        ← 재귀!
│   ├── forward(70)
│   ├── draw_tree(49)    ← 재귀!
│   │   └── ...
│   └── draw_tree(49)    ← 재귀!
│       └── ...
└── draw_tree(70)        ← 재귀!
    └── ...

결과 (프랙탈 나무):
        🌿  🌿
       🌿🌿🌿🌿
         │ │
         │ │


프로젝트 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 함수로 게임 루프를 구현할 수 있음
  • 콜백 함수를 사용하여 비동기 동작을 처리할 수 있음
  • 재귀 함수의 개념을 이해하고 간단한 예제에 적용할 수 있음
  • 여러 시스템이 통합된 게임을 설계하고 구현할 수 있음