안녕하세요! 이번 강좌에서는 PyQt를 활용하여 간단한 2D 게임을 제작하는 방법에 대해 자세히 알아보겠습니다. PyQt는 Python에서 GUI 애플리케이션을 개발할 수 있게 해주는 강력한 툴킷입니다. 우리는 QTimer를 활용하여 게임의 업데이트 루프를 관리하고, 기본적인 게임 요소를 구현해보겠습니다.
1. PyQt 소개
PyQt는 Qt라는 크로스 플랫폼 애플리케이션 개발 프레임워크의 Python 바인딩입니다. PyQt는 파이썬으로 GUI 애플리케이션을 손쉽게 만들 수 있는 많은 기능을 제공합니다. 우리는 PyQt를 사용하여 게임의 UI, 입력 처리, 그리고 그래픽을 관리할 것입니다.
2. 게임 기획
이번 강좌에서는 간단한 2D 게임을 만들어 보겠습니다. 게임의 주제는 플레이어가 움직이는 사각형을 조종하여 적을 피하고 점수를 획득하는 것입니다. 게임의 주요 기능은 다음과 같습니다:
- 플레이어 캐릭터: 사용자가 조종할 수 있는 사각형입니다.
- 적 캐릭터: 랜덤으로 생성되어 이동하는 사각형입니다.
- 점수 시스템: 플레이어가 적을 피할 때마다 점수를 획득합니다.
3. PyQt 설치
먼저, PyQt를 설치해야 합니다. 아래의 커맨드를 사용하여 PyQt5를 설치할 수 있습니다:
pip install PyQt5
4. 기본 구조
게임 개발 시, 기본적으로 설정해야 할 구조가 있습니다. 우리는 게임의 메인 윈도우와 게임 루프를 관리할 클래스들을 만들어야 합니다. 다음은 그 구조의 예입니다:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import QTimer
class Game(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(100, 100, 800, 600)
self.setWindowTitle('Simple 2D Game')
# QTimer 설정
self.timer = QTimer(self)
self.timer.timeout.connect(self.updateGame)
self.timer.start(16) # 약 60 FPS
def updateGame(self):
pass # 게임 로직 업데이트
if __name__ == '__main__':
app = QApplication(sys.argv)
game = Game()
game.show()
sys.exit(app.exec_())
5. 게임 요소 구현
이제 게임의 기본 요소를 구현해보겠습니다. 먼저 플레이어와 적 캐릭터를 추가합니다.
from PyQt5.QtGui import QPainter, QColor, QRect
import random
class Game(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
self.player_pos = [400, 300] # 플레이어의 초기 위치
self.enemy_pos = [random.randint(0, 780), random.randint(0, 580)] # 적의 초기 위치
self.score = 0 # 초기 점수
def initUI(self):
# 생략
pass
def updateGame(self):
self.enemy_pos[0] += random.choice([-1, 1]) * 5 # 적의 이동
self.enemy_pos[1] += random.choice([-1, 1]) * 5
# 게임 경계 설정
self.enemy_pos[0] = min(max(self.enemy_pos[0], 0), 780)
self.enemy_pos[1] = min(max(self.enemy_pos[1], 0), 580)
self.checkCollision() # 충돌 체크
self.update() # 화면 갱신
def checkCollision(self):
player_rect = QRect(self.player_pos[0], self.player_pos[1], 20, 20)
enemy_rect = QRect(self.enemy_pos[0], self.enemy_pos[1], 20, 20)
if player_rect.intersects(enemy_rect):
self.score += 1 # 충돌 시 점수 증가
def paintEvent(self, event):
painter = QPainter(self)
painter.setBrush(QColor(0, 255, 0)) # 플레이어 색상
painter.drawRect(self.player_pos[0], self.player_pos[1], 20, 20)
painter.setBrush(QColor(255, 0, 0)) # 적 색상
painter.drawRect(self.enemy_pos[0], self.enemy_pos[1], 20, 20)
painter.drawText(10, 20, f'Score: {self.score}') # 점수 표시
6. 사용자 입력 처리
플레이어의 조작을 위해 키 입력을 처리해야 합니다. PyQt에서는 keyPressEvent
와 keyReleaseEvent
를 오버라이드하여 키 입력을 처리할 수 있습니다.
class Game(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
self.keys = {} # 눌린 키를 저장할 사전
def keyPressEvent(self, event):
self.keys[event.key()] = True # 키 눌림 상태 기록
def keyReleaseEvent(self, event):
if event.key() in self.keys:
del self.keys[event.key()] # 키 놓임 상태 제거
def updateGame(self):
# 플레이어 이동 로직 추가
if Qt.Key_Left in self.keys and self.player_pos[0] > 0:
self.player_pos[0] -= 5
if Qt.Key_Right in self.keys and self.player_pos[0] < 780:
self.player_pos[0] += 5
if Qt.Key_Up in self.keys and self.player_pos[1] > 0:
self.player_pos[1] -= 5
if Qt.Key_Down in self.keys and self.player_pos[1] < 580:
self.player_pos[1] += 5
# 게임 로직 업데이트
self.enemy_pos[0] += random.choice([-1, 1]) * 5
self.enemy_pos[1] += random.choice([-1, 1]) * 5
# 경계 설정 및 충돌 체크
self.checkCollision()
self.update() # 화면 갱신
7. QTimer를 활용한 게임 업데이트
QTimer는 특정 간격으로 함수를 호출할 수 있게 해줍니다. 우리는 게임의 업데이트 루프를 관리하기 위해 QTimer를 사용할 것입니다. updateGame
메소드는 계속해서 호출되어야 하며, 우리는 이곳에서 게임의 상태를 업데이트하고 화면을 갱신합니다.
self.timer = QTimer(self)
self.timer.timeout.connect(self.updateGame)
self.timer.start(16) # 약 60 FPS
8. 최종 코드
위의 모든 내용을 통합하여 최종 게임 코드를 완성해보겠습니다.
import sys
import random
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtGui import QPainter, QColor, QRect
from PyQt5.QtCore import QTimer, Qt
class Game(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
self.player_pos = [400, 300]
self.enemy_pos = [random.randint(0, 780), random.randint(0, 580)]
self.score = 0
self.keys = {}
def initUI(self):
self.setGeometry(100, 100, 800, 600)
self.setWindowTitle('Simple 2D Game')
self.timer = QTimer(self)
self.timer.timeout.connect(self.updateGame)
self.timer.start(16)
def keyPressEvent(self, event):
self.keys[event.key()] = True
def keyReleaseEvent(self, event):
if event.key() in self.keys:
del self.keys[event.key()]
def updateGame(self):
if Qt.Key_Left in self.keys and self.player_pos[0] > 0:
self.player_pos[0] -= 5
if Qt.Key_Right in self.keys and self.player_pos[0] < 780:
self.player_pos[0] += 5
if Qt.Key_Up in self.keys and self.player_pos[1] > 0:
self.player_pos[1] -= 5
if Qt.Key_Down in self.keys and self.player_pos[1] < 580:
self.player_pos[1] += 5
self.enemy_pos[0] += random.choice([-1, 1]) * 5
self.enemy_pos[1] += random.choice([-1, 1]) * 5
self.enemy_pos[0] = min(max(self.enemy_pos[0], 0), 780)
self.enemy_pos[1] = min(max(self.enemy_pos[1], 0), 580)
self.checkCollision()
self.update()
def checkCollision(self):
player_rect = QRect(self.player_pos[0], self.player_pos[1], 20, 20)
enemy_rect = QRect(self.enemy_pos[0], self.enemy_pos[1], 20, 20)
if player_rect.intersects(enemy_rect):
self.score += 1
def paintEvent(self, event):
painter = QPainter(self)
painter.setBrush(QColor(0, 255, 0))
painter.drawRect(self.player_pos[0], self.player_pos[1], 20, 20)
painter.setBrush(QColor(255, 0, 0))
painter.drawRect(self.enemy_pos[0], self.enemy_pos[1], 20, 20)
painter.drawText(10, 20, f'Score: {self.score}')
if __name__ == '__main__':
app = QApplication(sys.argv)
game = Game()
game.show()
sys.exit(app.exec_())
9. 결론
이번 강좌에서는 PyQt를 이용하여 간단한 2D 게임을 만드는 방법을 살펴보았습니다. QTimer를 활용한 게임 업데이트와 기본적인 키 입력 처리 방법도 함께 배웠습니다. 이를 통해 PyQt의 강력한 기능을 활용하여 재미있는 게임을 만들어보시기 바랍니다.
앞으로 더 나아가 다양한 기능을 추가해보거나, 자체적인 게임 아이디어를 개발해보시면 좋을 것입니다. PyQt는 사용자 인터페이스를 쉽게 개발할 수 있도록 도와주므로, 더 많은 학습과 실험을 통해 다양한 프로젝트를 시도해보시기 바랍니다.
감사합니다!