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)
아래는 색상 코드로 보기 편하게 다시 설명 내용입니다.
상수 정의 아래 def safe_font() 함수 추가
한글이 사용되는 모든 클래스 내 __init__ 함수 또는 def 함수 안에 아래 safe_font 함수 코드 추가.
방법 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))