본문 바로가기

[Pygame] 🏰 2D 타워 디펜스 게임 만들기 17강 | 스프라이트 적용

@도마22026. 2. 17. 19:00
728x90


이번 17강에서는 pygame.draw로 그리던 타워/적/총알을 스프라이트 이미지로 교체합니다.
타워는 레벨에 따라 아래 규칙으로 이미지를 바꿉니다.

  • tower1.png : 1 ~ 3레벨
  • tower2.png : 4 ~ 6레벨
  • tower3.png : 7레벨 이상

1. 이미지 준비

프로젝트 폴더에 images 폴더를 만들고 아래 파일을 넣습니다.

  • images/tower1.png
  • images/tower2.png
  • images/tower3.png
  • images/bullet.png
  • images/enemy_normal.png
  • images/enemy_fast.png
  • images/enemy_tank.png

2. 스프라이트 로드

게임 시작 시 한 번만 로드합니다.

tower1_img = pygame.image.load("images/tower1.png").convert_alpha()
tower2_img = pygame.image.load("images/tower2.png").convert_alpha()
tower3_img = pygame.image.load("images/tower3.png").convert_alpha()

bullet_img = pygame.image.load("images/bullet.png").convert_alpha()

enemy_normal_img = pygame.image.load("images/enemy_normal.png").convert_alpha()
enemy_fast_img = pygame.image.load("images/enemy_fast.png").convert_alpha()
enemy_tank_img = pygame.image.load("images/enemy_tank.png").convert_alpha()

3. 크기(스케일) 맞추기

기존 원형 크기에 맞게 스프라이트도 스케일을 맞춥니다.

  • 타워: 지름 약 TOWER_RADIUS*2
  • 적: 지름 약 enemy.radius*2
  • 총알: 지름 약 bullet.radius*2
tower_size = (TOWER_RADIUS * 2, TOWER_RADIUS * 2)
tower1_img = pygame.transform.scale(tower1_img, tower_size)
tower2_img = pygame.transform.scale(tower2_img, tower_size)
tower3_img = pygame.transform.scale(tower3_img, tower_size)

bullet_size = (8, 8)
bullet_img = pygame.transform.scale(bullet_img, bullet_size)

enemy_size = (24, 24)
enemy_normal_img = pygame.transform.scale(enemy_normal_img, enemy_size)
enemy_fast_img = pygame.transform.scale(enemy_fast_img, enemy_size)
enemy_tank_img = pygame.transform.scale(enemy_tank_img, enemy_size)

4. 타워 레벨에 따른 이미지 선택

타워 레벨에 따라 이미지를 반환하는 함수를 만듭니다.

def get_tower_image(level):
    if level >= 7:
        return tower3_img
    elif level >= 4:
        return tower2_img
    else:
        return tower1_img

5. draw()를 이미지 기반으로 교체

타워

타워의 중심 좌표(self.x, self.y) 기준으로 스프라이트가 중앙 정렬되도록 blit 합니다.
선택 테두리/사거리 원은 기존대로 유지합니다.

def draw(self, screen, selected=False, show_range=False):
    if selected:
        pygame.draw.circle(screen, (255, 255, 255), (self.x, self.y), self.radius + 3, 2)
    if show_range:
        pygame.draw.circle(screen, (120, 120, 120), (self.x, self.y), self.range, 1)

    img = get_tower_image(self.level)
    rect = img.get_rect(center=(self.x, self.y))
    screen.blit(img, rect)

    if self.target and not self.target.is_dead and not self.target.reached_end:
        pygame.draw.line(screen, (255, 255, 255), (self.x, self.y), (int(self.target.x), int(self.target.y)), 2)

적 타입에 따라 이미지를 선택합니다. (HP 바는 그대로 유지)

def draw(self, screen):
    if self.type == ENEMY_FAST:
        img = enemy_fast_img
    elif self.type == ENEMY_TANK:
        img = enemy_tank_img
    else:
        img = enemy_normal_img

    rect = img.get_rect(center=(int(self.x), int(self.y)))
    screen.blit(img, rect)

    # HP 바 유지
    bar_width = 24
    bar_height = 4
    hp_ratio = max(0, self.hp) / self.max_hp
    pygame.draw.rect(screen, (60, 60, 60), (self.x - 12, self.y - 20, bar_width, bar_height))
    pygame.draw.rect(screen, (80, 220, 80), (self.x - 12, self.y - 20, bar_width * hp_ratio, bar_height))

총알

총알도 이미지로 출력합니다.

def draw(self, screen):
    rect = bullet_img.get_rect(center=(int(self.x), int(self.y)))
    screen.blit(bullet_img, rect)

6. 실행 결과


728x90
도마2
@도마2 :: 도마의 코드노트

초보자를 위한 코딩 강의를 정리합니다. 파이썬부터 C#, Unity 게임 제작까지 차근차근 기록합니다. — 도마

목차