from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
import time
class WindowClass(QWidget):
def __init__(self):
super().__init__()
self.setMouseTracking(True)
self.setupUI()
self.worker = Cat(self)
self.worker.psignal.connect(self.draw_cat)
self.worker.start()
self.show()
def setupUI(self):
self.setGeometry(100, 100, 912, 768)
self.mouse_x = 0
self.mouse_y = 0
self.cursor_x = 0
self.cursor_y = 0
self.neko = [
[1, 0, 0, 0, 0, 0, 7, 7],
[0, 2, 0, 0, 0, 0, 7, 7],
[0, 0, 3, 0, 0, 0, 0, 0],
[0, 0, 0, 4, 0, 0, 0, 0],
[0, 0, 0, 0, 5, 0, 0, 0],
[0, 0, 0, 0, 0, 6, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 2, 3, 4, 5, 6]
]
self.labels = [[None] * 8] * 10
for y in range(10):
for x in range(8):
self.labels[y][x] = QLabel(self)
self.labels[y][x].move(x * 72 + 21, y * 72 + 21)
# 커서 이미지
pixmap = QPixmap('Python_workspace\\mini_game\\image_dir\\neko_cursor.png')
self.cursor_image = QLabel(self)
self.cursor_image.setPixmap(pixmap)
self.cursor_image.move(24, 24)
# 배경 이미지
oImage = QImage('Python_workspace\\mini_game\\image_dir\\neko_bg.png')
sImage = oImage.scaled(QSize(912, 768))
palette = QPalette()
palette.setBrush(10, QBrush(sImage))
self.setPalette(palette)
self.cat_img = [None] * 8
# 고양이 이미지
for i in range(1,7):
self.cat_img[i] = QPixmap(f'Python_workspace\\mini_game\\image_dir\\neko{i}.png')
self.cat_img[7] = QPixmap('Python_workspace\\mini_game\\image_dir\\neko_niku.png')
self.k = QLabel(self)
self.k.resize(100, 100)
self.k.move(200, 200)
self.draw_cat()
def mouseMoveEvent(self, e):
self.mouse_x = e.x()
self.mouse_y = e.y()
self.visualize_cursor()
txt = str(self.mouse_x) + ', ' + str(self.mouse_y)
self.k.setText(txt)
def visualize_cursor(self):
if (24 <= self.mouse_x) and (self.mouse_x < 24 + 72 * 8) and (24 <= self.mouse_y) and (self.mouse_y < 24 + 72 * 10):
self.cursor_x = int((self.mouse_x - 24) / 72)
self.cursor_y = int((self.mouse_y - 24) / 72)
self.cursor_image.move(self.cursor_x * 72 + 21, self.cursor_y * 72 + 21)
@pyqtSlot()
def draw_cat(self):
for y in range(10):
for x in range(8):
if self.neko[y][x] > 0:
img = self.cat_img[self.neko[y][x]]
self.labels[y][x].setPixmap(img)
self.labels[y][x].move(x * 72 + 21, y * 72 + 21)
self.labels[y][x].setMouseTracking(True)
class Cat(QThread):
psignal = pyqtSignal()
def __init__(self, parent):
super().__init__(parent)
self.parent = parent
def run(self):
while(True):
self.drop_cat()
self.psignal.emit()
time.sleep(0.1)
def drop_cat(self):
for y in range(8, -1, -1):
for x in range(8):
if self.parent.neko[y][x] != 0 and self.parent.neko[y + 1][x] == 0:
self.parent.neko[y + 1][x] = self.parent.neko[y][x]
self.parent.neko[y][x] = 0
if __name__ == "__main__":
app = QApplication(sys.argv)
main_W = WindowClass()
sys.exit(app.exec_())
QThread와 signal과 slot을 사용해서 구현하는 것에 성공했다.
실시간 처리를 하려고 계속 고민 중이었는데 signal과 slot을 발견하고 성공할 수 있었다.
Cat을 QThread를 상속하는 Thread로 만들고 Cat에서 무한 반복하면서 인자로 준 클래스에 있는 neko를 낙하시키는 구조이다.
이때 반복하면서 signal을 발생시키고 이것을 self.worker.psignal.connect(self.draw_cat)으로 발생하면 draw_cat 함수를 실행시키도록 하여 고양이가 낙하하는 것을 구현할 수 있었다.
또한 고양이 위치는 8 * 10의 2차원 배열을 하나 만들고 2중 반복문으로 QLabel을 원소로 넣고 이동시켰다. 그렇게하여 neko 배열과 1:1로 매칭되도록 구성했다.