본문 바로가기
카테고리 없음

Python : 한글 폰트 ㅁ 깨짐으로 표시되는 문제 해결

by 마인쥬리 2025. 10. 17.

 

import pygame
import math
import random
import sys
import os

# 게임 초기화
pygame.init()
pygame.mixer.init()

# 상수 정의
SCREEN_WIDTH = 1024
SCREEN_HEIGHT = 768
FPS = 60

# 색상 정의
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)

 

# import 후 상수 정의 이후에 safe_font 함수 추가

 

def safe_font(size=16):
    pygame.font.init()
    # 한국어 표시 가능한 폰트 우선 탐색
    candidates = [
        "Malgun Gothic", "NanumGothic", "Noto Sans CJK KR", "Apple SD Gothic Neo",
        "맑은 고딕", "나눔고딕", "Noto Sans KR", None  # None -> 기본 시스템 폰트
    ]
    for name in candidates:
        try:
            return pygame.font.SysFont(name, size)
        except:
            continue
    return pygame.font.SysFont(None, size)

 

 

# 클래스 안  def __init__(self) 내 self. 부분에 추가

 

# UI with safe font
        self.font = safe_font(size=24)
        self.big_font = safe_font(size=48) 
        self.small_font = safe_font(size=16)

 

 

# 예시) 함수 안에서 사용할 때

# 한글 폰트가 사용되는 함수 안에  font = safe_font(size=10) 추가

def draw_ui(self):
        # 핫바 그리기
        hotbar_x = WINDOW_WIDTH // 2 - (HOTBAR_SLOTS * 40) // 2
        hotbar_y = WINDOW_HEIGHT - 60
        
        for i in range(HOTBAR_SLOTS):
            slot_x = hotbar_x + i * 40
            color = YELLOW if i == self.player.selected_hotbar_slot else WHITE
            pygame.draw.rect(self.screen, color, (slot_x, hotbar_y, 35, 35), 2)
            
            slot = self.player.hotbar[i]
            if slot.item:
                #font = pygame.font.Font(None, 24)
                font = safe_font(size=10)
                text = font.render(slot.item.name[:1].upper(), True, WHITE)
                self.screen.blit(text, (slot_x + 5, hotbar_y + 5))
                
                if slot.quantity > 1:
                    qty_text = font.render(str(slot.quantity), True, WHITE)
                    self.screen.blit(qty_text, (slot_x + 20, hotbar_y + 20))
        
        # 플레이어 상태 표시
        #font = pygame.font.Font(None, 24)
        font = safe_font(size=10)
        health_text = font.render(f"체력: {self.player.health}/{self.player.max_health}", True, WHITE)
        hunger_text = font.render(f"허기: {self.player.hunger}/{self.player.max_hunger}", True, WHITE)
        weather_text = font.render(f"날씨: {self.world.weather.current_weather.value}", True, WHITE)
        
        self.screen.blit(health_text, (10, 10))
        self.screen.blit(hunger_text, (10, 35))
        self.screen.blit(weather_text, (10, 60))
        
        # 인벤토리 표시
        if self.show_inventory:
            self.draw_inventory()

 

 

 

# 클래스가 아니고 함수 def main() 함수일때

def main():

 

    font = safe_font(size=24)
    small_font = safe_font(size=16)

 

    # 게임 루프 위에 추가
    while True:
        for event

 

 

# 클래스 내에서 

class Game:
    def __init__(self):
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption("폰트 예제")
        self.clock = pygame.time.Clock()
        self.state = GameState.MENU
        self.sound_manager = SoundManager()
        
        # 게임 데이터
        self.units = []
        self.buildings = []
        self.particles = []
        self.projectiles = []
        self.terrain_map = [[TerrainType.GRASS for _ in range(MAP_WIDTH)] for _ in range(MAP_HEIGHT)]
        
        # 카메라
        self.camera_x = 0
        self.camera_y = 0
        
        # 선택
        self.selection_start = None
        self.selected_units = []
        self.selected_building = None
        
        # 자원
        self.player_gold = 2000
        self.player_wood = 1000
        self.player_oil = 500
        self.player_food = 5
        self.player_food_cap = 20
        
        self.ai_gold = 2000
        self.ai_wood = 1000
        self.ai_oil = 500
        
        # 업그레이드
        self.player_upgrades = set()
        
        # 건설 모드
        self.build_mode = None
        
        # UI
        # self.font = pygame.font.Font(None, 24)        # << 보통 이렇게 사용하는데 한글 사각형 깨짐이 발생
        # self.small_font = pygame.font.Font(None, 18) # 아래 코드로 수정하면 한글이 제대로 표시됩니다.
        # self.large_font = pygame.font.Font(None, 36)


       # 위에서 설명한 def safe_font(size=16): 함수를 상수들 정의 후 추가한 다음 아래 코드를 추가
        self.font = safe_font(size=24)
        self.large_font = safe_font(size=48)
        self.small_font = safe_font(size=16)

 

 

 

아래는 색상 코드로 보기 편하게 다시 설명 내용입니다.

import pygame
import json
import random
import math
import os
import sys
 
# Initialize pygame
pygame.init()

# Constants
SCREEN_WIDTH = 1280
SCREEN_HEIGHT = 720
FPS = 60

# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
PURPLE = (128, 0, 128)
GRAY = (128, 128, 128)
DARK_GRAY = (64, 64, 64)
LIGHT_BLUE = (173, 216, 230)

 

상수 정의 아래 def safe_font() 함수 추가

def safe_font(size=24):
    pygame.font.init()
    # 한국어 표시 가능한 폰트 우선 탐색
    candidates = [
        "Malgun Gothic", "NanumGothic", "Noto Sans CJK KR", "Apple SD Gothic Neo",
        "맑은 고딕", "나눔고딕", "Noto Sans KR", None  # None -> 기본 시스템 폰트
    ]
    for name in candidates:
        try:
            return pygame.font.SysFont(name, size)
        except:
            continue
    return pygame.font.SysFont(None, size)

 

한글이 사용되는 모든 클래스 내 __init__ 함수 또는 def 함수 안에 아래 safe_font 함수 코드 추가.

class Game:
    def __init__(self):
# UI with safe font
        self.font = safe_font(size=24)
        self.big_font = safe_font(size=48)
        self.small_font = safe_font(size=16)

 

 

 

방법 2 :

 

Windows, macOS, Linux 모두 적용되는 폰트 함수

 

def setup_fonts(self) 함수를 메인 클래스내에 추가 후

 def __init__(self) 안에  self.setup_fonts() 추가

 

 

def setup_fonts(self):
        """한글 지원 폰트 설정"""
        import platform
        
        # 운영체제별 기본 한글 폰트 경로
        font_paths = []
        
        if platform.system() == "Windows":
            font_paths = [
                "C:/Windows/Fonts/malgun.ttf",  # 맑은 고딕
                "C:/Windows/Fonts/gulim.ttc",   # 굴림
                "C:/Windows/Fonts/batang.ttc",  # 바탕
                "C:/Windows/Fonts/NanumGothic.ttf"  # 나눔고딕
            ]
        elif platform.system() == "Darwin":  # macOS
            font_paths = [
                "/System/Library/Fonts/AppleSDGothicNeo.ttc",
                "/System/Library/Fonts/Apple Gothic.ttf",
                "/Library/Fonts/NanumGothic.ttf"
            ]
        else:  # Linux
            font_paths = [
                "/usr/share/fonts/truetype/nanum/NanumGothic.ttf",
                "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
                "/usr/share/fonts/TTF/NanumGothic.ttf"
            ]
        
        # 사용 가능한 폰트 찾기
        selected_font = None
        for font_path in font_paths:
            if os.path.exists(font_path):
                selected_font = font_path
                break
        
        # 시스템 기본 폰트 사용
        if selected_font is None:
            try:
                # 시스템 폰트에서 한글 지원 폰트 찾기
                system_fonts = pygame.font.get_fonts()
                korean_fonts = ['malgun', 'gulim', 'batang', 'nanumgothic', 'applegothic', 'dotum']
                
                for korean_font in korean_fonts:
                    for sys_font in system_fonts:
                        if korean_font in sys_font.lower():
                            selected_font = pygame.font.match_font(sys_font)
                            if selected_font:
                                break
                    if selected_font:
                        break
            except:
                pass
        
        # 폰트 객체 생성
        try:
            if selected_font:
                self.font_large = pygame.font.Font(selected_font, 48)
                self.font_medium = pygame.font.Font(selected_font, 36)
                self.font_small = pygame.font.Font(selected_font, 24)
                print(f"한글 폰트 로드 성공: {selected_font}")
            else:
                # 기본 폰트 사용 (한글 지원 안됨)
                self.font_large = pygame.font.Font(None, 48)
                self.font_medium = pygame.font.Font(None, 36)
                self.font_small = pygame.font.Font(None, 24)
                print("기본 폰트 사용 (한글 지원 제한적)")
        except Exception as e:
            print(f"폰트 로드 실패: {e}")
            # 최후의 수단으로 기본 폰트 사용
            self.font_large = pygame.font.Font(None, 48)
            self.font_medium = pygame.font.Font(None, 36)
            self.font_small = pygame.font.Font(None, 24)

 

예시 )

# 메인 게임 클래스
class CharacterGameSystem:
    def __init__(self):
        pygame.init()
        self.screen_width = 1024
        self.screen_height = 768
        self.screen = pygame.display.set_mode((self.screen_width, self.screen_height))
        pygame.display.set_caption("캐릭터 관리 & 게임 시스템")
        
        self.clock = pygame.time.Clock()
        self.running = True
        self.state = GameState.MAIN_MENU
        
        # 캐릭터 관리자
        self.character_manager = CharacterManager()
        
        # UI 요소들
        self.buttons = {}
        self.input_boxes = {}
        self.selected_sprite_path = ""
        
        # 게임 관련
        self.background_x = 0
        self.keys_pressed = {}
        
        # 한글 지원 폰트 설정
        self.setup_fonts()
        
        self.setup_ui()
    
    def setup_fonts(self):
        """한글 지원 폰트 설정"""
        import platform
        
        # 운영체제별 기본 한글 폰트 경로
        font_paths = []
        
        if platform.system() == "Windows":
            font_paths = [
                "C:/Windows/Fonts/malgun.ttf",  # 맑은 고딕
                "C:/Windows/Fonts/gulim.ttc",   # 굴림
                "C:/Windows/Fonts/batang.ttc",  # 바탕
                "C:/Windows/Fonts/NanumGothic.ttf"  # 나눔고딕
            ]
        elif platform.system() == "Darwin":  # macOS
            font_paths = [
                "/System/Library/Fonts/AppleSDGothicNeo.ttc",
                "/System/Library/Fonts/Apple Gothic.ttf",
                "/Library/Fonts/NanumGothic.ttf"
            ]
        else:  # Linux
            font_paths = [
                "/usr/share/fonts/truetype/nanum/NanumGothic.ttf",
                "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
                "/usr/share/fonts/TTF/NanumGothic.ttf"
            ]
        
        # 사용 가능한 폰트 찾기
        selected_font = None
        for font_path in font_paths:
            if os.path.exists(font_path):
                selected_font = font_path
                break
        
        # 시스템 기본 폰트 사용
        if selected_font is None:
            try:
                # 시스템 폰트에서 한글 지원 폰트 찾기
                system_fonts = pygame.font.get_fonts()
                korean_fonts = ['malgun', 'gulim', 'batang', 'nanumgothic', 'applegothic', 'dotum']
                
                for korean_font in korean_fonts:
                    for sys_font in system_fonts:
                        if korean_font in sys_font.lower():
                            selected_font = pygame.font.match_font(sys_font)
                            if selected_font:
                                break
                    if selected_font:
                        break
            except:
                pass
        
        # 폰트 객체 생성
        try:
            if selected_font:
                self.font_large = pygame.font.Font(selected_font, 48)
                self.font_medium = pygame.font.Font(selected_font, 36)
                self.font_small = pygame.font.Font(selected_font, 24)
                print(f"한글 폰트 로드 성공: {selected_font}")
            else:
                # 기본 폰트 사용 (한글 지원 안됨)
                self.font_large = pygame.font.Font(None, 48)
                self.font_medium = pygame.font.Font(None, 36)
                self.font_small = pygame.font.Font(None, 24)
                print("기본 폰트 사용 (한글 지원 제한적)")
        except Exception as e:
            print(f"폰트 로드 실패: {e}")
            # 최후의 수단으로 기본 폰트 사용
            self.font_large = pygame.font.Font(None, 48)
            self.font_medium = pygame.font.Font(None, 36)
            self.font_small = pygame.font.Font(None, 24)

 

 

방법 3 :

 

예시 )

class Game:
    def __init__(self):
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption("미스테리 월드: 동쪽으로의 여행")
        self.clock = pygame.time.Clock()
        
        # 한글 폰트 설정
        try:
            korean_fonts = [
                'malgun gothic',
                'AppleGothic', 
                'NanumGothic',
                'DejaVu Sans',
                'Arial Unicode MS'
            ]
            
            font_found = False
            for font_name in korean_fonts:
                try:
                    self.font_large = pygame.font.SysFont(font_name, 48)
                    self.font_medium = pygame.font.SysFont(font_name, 32) 
                    self.font_small = pygame.font.SysFont(font_name, 24)
                    test_surface = self.font_small.render("테스트", True, WHITE)
                    if test_surface.get_width() > 0:
                        font_found = True
                        print(f"한글 폰트 로드 성공: {font_name}")
                        break
                except:
                    continue
            
            if not font_found:
                self.font_large = pygame.font.Font(None, 48)
                self.font_medium = pygame.font.Font(None, 32)
                self.font_small = pygame.font.Font(None, 24)
                print("경고: 한글 폰트를 찾을 수 없어 기본 폰트를 사용합니다.")
                
        except Exception as e:
            self.font_large = pygame.font.Font(None, 48)
            self.font_medium = pygame.font.Font(None, 32)
            self.font_small = pygame.font.Font(None, 24)
            print(f"폰트 로드 오류: {e}")

 

###### 생략

 

# 게임 실행
if __name__ == "__main__":
    try:
        game = EastwardStyleGame()
        game.run()
    except Exception as e:
        print(f"게임 실행 중 오류 발생: {e}")
        import traceback
        traceback.print_exc()

 

 

 

 

 

방법 4 :

 

import pygame
import math
import random
import sys
import os

# 게임 초기화
pygame.init()

 

# 폰트 초기화 (한글 지원)
try:
    # 시스템 폰트 사용 (한글 지원)
    font_large = pygame.font.SysFont('malgungothic,nanumgothic,dotum,gulim', 36)
    font_medium = pygame.font.SysFont('malgungothic,nanumgothic,dotum,gulim', 24)
    font_small = pygame.font.SysFont('malgungothic,nanumgothic,dotum,gulim', 18)
except:
    # 폴백 폰트
    font_large = pygame.font.Font(None, 36)
    font_medium = pygame.font.Font(None, 24)
    font_small = pygame.font.Font(None, 18)

 

 

def draw_main_menu(screen):
    """메인 메뉴 그리기"""
    screen.fill(BLACK)
    
    # 배경 효과
    for i in range(100):
        x = random.randint(0, SCREEN_WIDTH)
        y = random.randint(0, SCREEN_HEIGHT)
        color = (random.randint(0, 50), 0, random.randint(0, 50))
        pygame.draw.circle(screen, color, (x, y), random.randint(1, 3))
    
    # 제목
    title_text = font_large.render("마계촌: 기사의 모험", True, RED)
    title_rect = title_text.get_rect(center=(SCREEN_WIDTH//2, 150))
    screen.blit(title_text, title_rect)
    
    # 부제목
    subtitle_text = font_medium.render("Ghosts 'n Goblins Style", True, WHITE)
    subtitle_rect = subtitle_text.get_rect(center=(SCREEN_WIDTH//2, 200))
    screen.blit(subtitle_text, subtitle_rect)
    
    # 메뉴 옵션
    menu_options = [
        "ENTER - 게임 시작",
        "H - 도움말",
        "ESC - 종료"
    ]
    
    for i, option in enumerate(menu_options):
        option_text = font_medium.render(option, True, WHITE)
        option_rect = option_text.get_rect(center=(SCREEN_WIDTH//2, 300 + i * 50))
        screen.blit(option_text, option_rect)

 

def draw_help_screen(screen):
    """도움말 화면 그리기"""
    screen.fill(DARK_BLUE)
    
    title_text = font_large.render("게임 도움말", True, WHITE)
    title_rect = title_text.get_rect(center=(SCREEN_WIDTH//2, 50))
    screen.blit(title_text, title_rect)
    
    help_content = [
        "조작법:",
        "  이동: ← → 또는 A D",
        "  점프: ↑ 또는 W 또는 스페이스바",
        "  공격: Z 또는 X",
        "",
        "무기 시스템:",
        "  창: 기본 무기, 직선 공격",
        "  단검: 빠른 연사, 3방향 공격",
        "  도끼: 강력하지만 느림, 포물선",
        "  화염: 매우 빠른 연사, 불꽃 효과",
        "  마법: 회전하는 마법구슬",
        "",
        "아이템:",
        "  무기상자: 새로운 무기 획득",
        "  체력팩: 생명력 회복",
        "  파워업: 일시적 강화",
        "",
        "게임 목표:",
        "  각 레벨의 모든 적을 처치하고",
        "  보스를 물리쳐 다음 레벨로!",
        "",
        "단축키:",
        "  F1: 디버그 정보 토글",
        "  M: 메인메뉴로",
        "  ESC: 종료",
        "",
        "아무 키나 눌러 돌아가기"
    ]
    
    for i, line in enumerate(help_content):
        text = font_small.render(line, True, WHITE)
        screen.blit(text, (50, 100 + i * 25))