모든 것이 사라졌고, 제가 모든 것이 어디에 있는지 모르겠습니다. 컴퓨터에서 파일을 어디에 두었는지도 모르겠어요. 채팅이 어디에 있는지 모르겠고요. 지난 영상들 중 마지막 두 개는 아예 만들지 않은 것 같아요. 솔직히 말해서, 저에게 묻는다면, 저희가 지난 영상에서는 실제로 아무것도 하지 않았습니다. 기본적으로 Pygame을 설정하는 방법을 보여주는 기본적인 채팅 데모 같은 것을 설정했을 뿐입니다. 하지만 우리는 파이썬 안에서 실제로 무엇을 만들어야 할지에 대해 생각해 본 적이 없습니다. 우리가 코딩할 것이 무엇인지 알아야 합니다.
2단계 다음에 1단계를 하는 식이죠. 그리고 제 다른 모든 강좌와 마찬가지로, 채널 멤버들은 이 파일들에 접근할 수 있습니다. 여러분은 그냥 이 비디오의 맨 아래 설명란에서 찾을 수 있습니다. 저와 함께 코딩하고 싶거나, 어떤 종류의 오류 메시지가 나타나서 '오, 안 돼, 이걸 어떻게 고치지?'라고 할 때, 제가 어디까지 진행했는지 보고 도움이 필요하면 제 코드를 복사하여 붙여넣을 수 있습니다. 기본적으로 저는 우리가 게임 아이디어를 생각해 낼 것이라고 생각합니다.
그리고 사실 저는 재미있을 것 같은 것을 염두에 두고 있습니다. 오랫동안 만들고 싶었던, 선술집 에뮬레이터 시뮬레이터 종류의 게임입니다. 기본적으로 우리는 중세 시대의 선술집 안에 있고, 장식을 배치할 수도 있고 돌아다닐 수도 있습니다. 손님들이 들어오고, 그들을 돌봐야 합니다. 여기서 범위를 정말 확장하기 시작하고 있지만, 기본적인 우리가 무엇을 할지에 대한 아이디어는 있습니다. 이번에는 [underwear]가 있습니다.
[웃음] 제가 속옷을 입고 있다고 말했나요? 바지는 입었어요. 좋아요, 벌써 좋은 출발이네요. 그래서, 시작하자면, 게임 내부에 몇 가지 모양(shapes)을 만들고 거기서부터 진행해야 할 것 같아요. 왜냐하면 일반적으로는 게임용 에셋(assets)을 만들기 전에 무언가를 프로토타입(prototype)으로 만들어 보는 것이 좋거든요. 에셋을 만드는 데 시간을 많이 낭비했다가 나중에 '아, 잠깐만. 사실 저 계단은 필요 없었는데...' 하고, 제가 방금 어떤 드로잉 프로그램 안에서 다섯 시간을 들여 만들었던 게 무용지물이 되는 경우를요.
여기서는 시작하자면, 그냥 들어가서 이 게임을 위한 디렉토리(directory)를 만들 거예요. 제가 말했듯이, 모든 게 사라졌거든요. 그래서 main.py라는 새로운 파일을 만들 것 같아요. 왜냐하면 이 파일이 모든 내용을 담고 있는 메인 파일이 될 거거든요. 저는 특정 목적을 가진 스크립트(scripts)를 만드는 것을 생각해야 할 것 같아요. 예를 들어 플레이어 컨트롤(player controls) 같은 거요. 이렇게 하면 메인 파일로 가져와서 사용하기가 정말 좋을 거예요. 그래서 새로운 폴더를 만들고 이름을 scripts라고 지을게요.
그 폴더 안에 player_controller라는 것을 만들 거예요. 그렇죠? 플레이어 컨트롤러가 있고, 사실 저희는 거기서 시작할 것 같아요. 작게 시작할 거예요. 저는 우리가 SIS라고 불리는 것을 가져올 수 있다고 믿어요. 음, 그리고 지금 생각해보니 실제로 환경을 구축해야 해요. 제가 이해하기로는 환경(environment)을 설정한다는 것은 기본적으로 격리된(encapsulated) 환경을 갖는다는 의미예요. 여기서 Pygame이나 다른 라이브러리 또는 프레임워크 같은 것들을 설치하기 시작하면, 그것들이 오직 그 특정 프로젝트 내에만 존재하게 됩니다.
자, 여기서 할 일은 방금 설치한 이 환경을 활성화하는 것입니다. 됐습니다. 그리고 제가 말씀드렸듯이 모든 것을 잃었기 때문에 Pygame을 다시 설치해야 합니다. 좋습니다, 이제 작동합니다. 조금 다른 방식으로 해야 했지만, 작동합니다.
다음에 할 일은 이 프로그램을 설정하기 시작하는 것입니다. 저는 실제로 ChatGPT에게 이것이 정확히 무엇을 하는지 물어보았습니다. 기본적으로 import sys는 우리가 파이썬 함수에 접근할 수 있게 해줍니다. 예를 들어 종료(exiting), 명령줄 인수 읽기(reading command line arguments), 표준 입력/출력(standard input, output)과의 상호 작용, print/오류 처리, 파이썬이 어떤 OS에서 실행되고 있는지 아는 것 등이 있습니다.
기본적으로 파이썬의 시스템 모듈입니다. 문제는 이 게임을 실행하고 단순히 exit pygame이라고 말한 다음 종료하면, 반드시 제 파이썬 프로그램 전체가 종료된 것은 아닐 수 있지만, 여기 있는 이 프로그램의 pygame 부분만 종료될 뿐일 수 있다는 것입니다. 따라서 우리는 전체 시스템을 종료해야 합니다. 또한, 이것을 설정할 때 실제로 Pygame을 임포트했는지 확인해야 하는데, 왜냐하면 그것이 우리가 여기서 사용하는 것 중 하나이기 때문입니다.
따라서 언제든지 Pygame 프로그램을 설정할 때 가장 먼저 해야 할 일은 Pygame을 초기화(initialize)하는 것입니다.
방금 임포트한 Pygame을 참조할 것입니다. 이것은 라이브러리 또는 모듈이라고 추측합니다. 이전과 마찬가지로, 창의 높이와 너비를 생성하는 것도 확인해야 합니다. 그런 다음 이전에 했던 것처럼 게임 창을 만들 것입니다. 이것은 Pygame 디스플레이를 제어하는 Pygame 내부의 모듈 중 하나입니다. 기본적으로 여기에서 다양한 매개변수를 설정할 수 있습니다. 현재는 크기(size)라는 두 가지가 있습니다. 즉, 얼마나 넓고 높게 하고 싶은지입니다. 또한 DEPTH, DISPLAY_VSYNC와 같은 플래그(flags)라고 불리는 것을 삽입할 수도 있습니다.
꽤 멋지네요. 그리고 이전과 마찬가지로 캡션(caption)도 설정할 수 있습니다. 캡션이란 기본적으로 창이 있을 때 상단에 작은 이름을 표시하는 것입니다. 이 이름은 'tavern simulator'라고 부를 수 있겠네요. 또한 프레임 속도(frame rate)를 제어하고 싶습니다. 다시 말하지만, 이것은 다음 순서들을 계속해서 처리해 주는 것과 같습니다. 자, 이제 main을 정의하겠습니다. 좋아요. 기본적으로 우리는 pygame에 해당하는 변수와 time이라는 또 다른 모듈을 만들고 싶다고 말하는 것입니다.
다음으로 할 일은 메인 게임 루프(main game loop)를 만드는 것입니다. 여기에서 복사하여 붙여넣을 것이고, 단계별로 진행할 것입니다. 이 부분은 알고 있습니다. 주석이 필요하지 않습니다. pygame.event.get()에 대해서요. 다시 말해, event는 우리가 어떤 종류의 이벤트가 있다는 것을 알려주는 모듈입니다. 이것은 완전히 기능하는 게임을 만들 수 있게 해줍니다. (중략) 기본적으로 자바스크립트(JavaScript)와 같은 이벤트 핸들러(event handler)와 같습니다. 키보드 입력을 감지하거나, 플레이어가 무언가를 클릭하거나, 사용자가 무언가를 클릭할 때, 우리가 어떤 동작을 수행하고 싶고, 이것이 바로 그 역할을 합니다. 즉, 이벤트를 듣는 것인데, [음악] 이 경우에는 키보드 누름이나 마우스로 창을 닫는 등의 상황일 수 있습니다.
따라서 이것은 게임과 상호작용하는 데 기본적으로 필요합니다. 만약 이것이 없다면 아무것도 할 수 없습니다. [음악] 플레이어가 창 모서리의 X 버튼을 클릭하면, Pygame을 종료하고 전체 프로그램을 안전하게 닫게 됩니다. 다음으로 화면을 색상으로 채우고 싶습니다. 이것은 우리 애플리케이션의 배경입니다. 어두운 회색 배경이죠. 그런 다음 화면에서 보이는 모든 것을 업데이트할 수 있습니다. 이것이 없으면 시각적으로 아무것도 변하지 않습니다. 그래서 pygame.display.flip을 사용합니다. 이는 화면의 전체 디스플레이 표면(display surface)을 업데이트하는 것입니다.
이것은 전체 디스플레이의 내용을 업데이트합니다. 좋습니다. 기본적으로 이 루프의 맨 끝에서, 우리가 이벤트를 감지하고 배경색을 변경할 수 있는 작업을 수행한 후에 말이죠. 예를 들어, 여기서 배경색을 변경하면 이것이 실제로 실행된 후에만 색상이 바뀝니다. 마치 이것이 '좋아, 여기에 있는 모든 변경 사항들을 게임에 적용해라'라고 말하는 것과 같습니다. 좋습니다. 그러면 이 모든 변경 사항들이 게임에 적용됩니다. 따라서 제가 이동(move) 버튼을 클릭하더라도, 이 특정 코드 라인이 실제로 실행되기 전까지는 캐릭터가 움직이지 않습니다.
좋습니다. 이것도 매우 중요합니다. 흥미롭게도 '플립(flip)'이라고 부릅니다. 그런 다음 우리는 게임이 초당 60 프레임에서 실행되도록 제한하고 싶습니다. 이렇게 하면 게임이 너무 빠르게 실행되는 것을 방지할 수 있습니다. 좋습니다. 따라서 clock.tick을 60으로 설정합니다. 그리고 다시 말하지만, 여기 위로 올라가서 할 수도 있습니다. 아마도 그렇게 하는 것이 좋을 것 같습니다. FPS를 추가한다고 가정해 봅시다. 이것을 60과 같게 설정하겠습니다. 대신 이 상수를 사용하겠습니다. 이렇게 하면 여기에 저장되어 모든 속성을 가지고 아래로 직접 실행할 수 있게 됩니다.
따라서 여기서 변경 사항을 만들면 프로그램에 변경이 생깁니다. 정말 멋지네요. 이를 통해 프로그램을 열고 테스트해 볼 수 있습니다. 검은색 화면이나 어두운 회색 화면 외에는 아무것도 없을 것입니다. 만약 제가 'python main.py'를 실행해 본다고 가정해 봅시다. 그게 전부입니다. 그리고 여기 'tavern simulator'라고 표시되는 것을 볼 수 있습니다. 여기서 X는 기본적으로 우리의 버튼에 들어가서 가져가는 것이고, 아래로 내려가서 pygame.quit()을 사용하면 그것을 가져와서 종료하는 것입니다.
이 코드가 실행되네요. 정말 멋집니다. 지금까지는 순조롭습니다. 이제 지난 영상에서 했던 것처럼 플레이어 캐릭터가 움직이게 하는 것만 남았습니다. 방금 깨달았는데, 오늘 우리가 한 모든 것이 사실은 지난 영상에서 했던 것을 그대로 반복하고 있다는 겁니다. [웃음] 이건 기본적으로 복사하여 붙여넣기(copy pasting)에 불과합니다.
제가 이름을 잘못 지었다는 것을 방금 깨달았습니다. 이건 'how to rename py'가 되어야 합니다. 그래서 player_controller 안에서 pygame을 다시 가져올(import) 겁니다. 이제 여기서 플레이어 캐릭터를 위한 클래스를 만들 것입니다.
기본적으로 플레이어가 무엇을 할지, 그리고 그것은 컨트롤러 부분과 관련되어야 합니다. 만약 플레이어가 특정 방식으로 행동한다면—예를 들어 적에게 맞거나 약간 튕겨져 나가는 물리적 움직임 같은 것들—우리는 이것들을 player 안에 넣고 싶지 않습니다. 이건 단지 플레이어를 제어하는 용도일 뿐이며, 다른 무언가가 플레이어의 컨트롤과 상호 작용하지 않는 한 말이죠. 우리는 이걸 여기에 넣고 싶지 않습니다. 그래서 PlayerController라는 이름의 클래스를 만들 것입니다.
단계별로 진행하고 싶어서 그냥 복사하여 붙여넣기 하겠습니다. 자, 보세요. 채팅(chat)이 우리에게 이것을 준 방식은 매우 좋은 예시입니다. 기본적으로 "아, 플레이어와 관련된 모든 것을 이 컨트롤러 안에 넣고 싶군요."라고 말합니다. 하지만 지금은 컨트롤러 안에서 또다시 player를 만들려고 시도하고 있습니다. 그리고 main.py는 게임을 실행하는 메인 스크립트 역할을 합니다. 즉, 제어(controls), 프레임 속도(frame rate), 창(window) 같은 것들이죠.
하지만 게임 내부의 모든 객체들은 아마도 게임 내의 모든 게임 객체를 렌더링하는 별도의 스크립트에 들어가야 할 것입니다. 따라서 그것을 main.py나 player_controller 안에 두는 것은 아마도 최선의 아이디어가 아닐 겁니다. 좋습니다. 이제 우리는 약간 다르게 진행할 것입니다. player_controller 안으로 들어가서 모든 것을 지우겠습니다. 왜냐하면 더 논리적인 방식으로 처리하려고 노력할 것이기 때문입니다. 그래서 대신에 저는 들어가서 새로운 스크립트를 만들려고 합니다.
그리고 이것은 renderer_start_strat_start.py가 될 것입니다. 여기서 제 목표는 이 특정 스크립트가 게임을 처음 시작할 때 로드되어야 하는 것들을 불러오는 것입니다. 즉, 플레이어 같은 자산이나 일부 UI 요소처럼 단순히 존재해야 하는 것들을 로드합니다. 기본적으로 이것이 그 역할을 담당하게 됩니다. 좋습니다.
따라서 여기에 들어가는 이 특정 함수는 새로운 renderer 객체가 생성될 때 호출된다고 말합니다. 흥미로운 점은 이것이 무엇인지 아십니까? main.py에서 생성된 메인 게임 창 서피스(surface)이며, 우리는 플레이어가 보는 모든 것을 그 위에 그리는데 이를 사용합니다. 좋습니다. 그래서 이것은 기본적으로 이 특정 함수 안에 있는 어떤 것이든 초기화할 것입니다. 왜냐하면 __init__이기 때문입니다. 이것이 파이썬이 함수를 작성하는 방식이거나, 이 경우 클래스 내부에 있기 때문에 메서드가 될 것입니다. 따라서 나중에 그 위에 그릴 수 있도록 화면에 대한 참조(reference)를 저장할 것입니다. 기본적으로 우리는 main.py 내부에서 화면을 가져오는 것일 뿐입니다. 왜냐하면 우리가 그때 화면을 초기화하고 단순히 그것을 참조하기 때문입니다.