Skip to content

Latest commit

 

History

History
132 lines (107 loc) · 4.5 KB

211214.md

File metadata and controls

132 lines (107 loc) · 4.5 KB

Day 69

파이썬으로 배우는 게임 개발 입문편

블럭 낙하 구현

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로 매칭되도록 구성했다.