Skip to content

Latest commit

 

History

History
227 lines (190 loc) · 8.03 KB

211216.md

File metadata and controls

227 lines (190 loc) · 8.03 KB

Day 71

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

블럭 낙하 게임 완성

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
import time
import random

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.scoresig.connect(self.ScoreDisplay)
        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.index = 0
        self.high_score, self.score, self.tsugi = 0, 0, 0
        
        self.next_cat = QLabel(self)
        self.next_cat.move(710, 128)
        self.next_cat.resize(78, 78)

        self.scorelabel = QLabel(self)
        self.scorelabel.setText(str(0))
        self.scorelabel.move(680, 100)
        self.scorelabel.resize(50, 50)

        self.high_score_label = QLabel(self)
        self.high_score_label.resize(60, 60)
        self.high_score_label.setFont(QFont('Times New Roman', 20))
        self.high_score_label.move(680, 50)
        self.high_score_label.setText(str(0))

        self.neko = []
        self.check = []
        for i in range(10):
            self.neko.append([0, 0, 0, 0, 0, 0, 0, 0])
            self.check.append([0, 0, 0, 0, 0, 0, 0, 0])

        # 딕셔너리가 아닌 리스트로 하니까 같은 메모리 영역을 공유하는 라벨 객체만 만들어져서 제대로 표현이 안되고 있었던 것
        self.labels = {}
        for y in range(10):
            for x in range(8):
                txt = str(x) + str(y)
                self.labels[txt] = QLabel(self)
                self.labels[txt].resize(78, 78)
                self.labels[txt].setMouseTracking(True)
                self.labels[txt].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')

    def mouseMoveEvent(self, e):
        self.mouse_x = e.x()
        self.mouse_y = e.y()
        self.visualize_cursor()

    def mousePressEvent(self, e):
        if self.neko[self.cursor_y][self.cursor_x] == 0:
            if (24 <= self.mouse_x) and (self.mouse_x < 24 + 72 * 8) and (24 <= self.mouse_y) and (self.mouse_y < 24 + 72 * 10):
                if self.over_neko() == False:
                    self.neko[self.cursor_y][self.cursor_x] = self.tsugi
                    self.tsugi = random.randint(1, 6)
                    self.set_neko()
                    self.draw_next()
                else:
                    for y in range(10):
                        for x in range(8):
                            self.neko[y][x] = 0
                    self.score = 0
                    self.tsugi = 0
                    self.high_score_label.setText(str(self.high_score))
        
        
    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):
                txt = str(x) + str(y)
                if self.neko[y][x] > 0:
                    img = self.cat_img[self.neko[y][x]]
                    self.labels[txt].setPixmap(img)
                else:
                    self.labels[txt].setPixmap(QPixmap())

    @pyqtSlot(int)
    def ScoreDisplay(self, sc):
        self.score += sc
        self.scorelabel.setText(str(self.score))


    def check_neko(self):
        for y in range(10):
            for x in range(8):
                self.check[y][x] = self.neko[y][x]

        for y in range(1, 9):
            for x in range(8):
                if self.check[y][x] > 0:
                    if self.check[y - 1][x] == self.check[y][x] and self.check[y + 1][x] == self.check[y][x]:
                        self.neko[y - 1][x] = 7
                        self.neko[y][x] = 7
                        self.neko[y + 1][x] = 7

        for y in range(10):
            for x in range(1, 7):
                if self.check[y][x] > 0:
                    if self.check[y][x - 1] == self.check[y][x] and self.check[y][x + 1] == self.check[y][x]:
                        self.neko[y][x - 1] = 7
                        self.neko[y][x] = 7
                        self.neko[y][x + 1] = 7
        
        for y in range(1, 9):
            for x in range(1, 7):
                if self.check[y][x] > 0:
                    if self.check[y - 1][x - 1] == self.check[y][x] and self.check[y + 1][x + 1] == self.check[y][x]:
                        self.neko[y - 1][x - 1] = 7
                        self.neko[y][x] = 7
                        self.neko[y + 1][x + 1] = 7
                    if self.check[y + 1][x - 1] == self.check[y][x] and self.check[y - 1][x + 1] == self.check[y][x]:
                        self.neko[y + 1][x - 1] = 7
                        self.neko[y][x] = 7
                        self.neko[y - 1][x + 1] = 7

    def sweep_neko(self):
        num = 0
        for y in range(10):
            for x in range(8):
                if self.neko[y][x] == 7:
                    self.neko[y][x] = 0
                    num = num + 1
        return num

    def over_neko(self):
        for x in range(8):
            if self.neko[0][x] > 0:
                if self.high_score < self.score:
                    self.high_score = self.score
                return True
        return False

    def draw_next(self):
        if self.tsugi > 0:
            self.next_cat.setPixmap(self.cat_img[self.tsugi])

    def set_neko(self):
        result = [random.randint(0, 7) for i in range(4)]
        for x in result:
            self.neko[0][x] = random.randint(0, 6)



class Cat(QThread):
    psignal = pyqtSignal()
    scoresig = pyqtSignal(int)

    def __init__(self, parent):
        super().__init__(parent)
        self.parent = parent
        
    
    def run(self):
        while(True):
            self.drop_cat()
            self.psignal.emit()
            if self.drop_cat() == False:
                self.parent.check_neko()
                sc = self.parent.sweep_neko()
                self.scoresig.emit(sc * 10)

            time.sleep(0.1)

    def drop_cat(self):
        flg = False
        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
                    flg = True
        return flg


if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_W = WindowClass()
    sys.exit(app.exec_())

저번에 한 것에 마무리로 최고 점수와 블럭이 3개 이상 이어졌으면 사라지게하는 것을 추가했으며, 난이도 조정을 위해 클릭 할 때마다 랜덤으로 4개 열에 랜덤한 고양이가 떨어지는 것을 추가했고, 다음으로 나올 고양이가 무엇인지 알 수 있게 되었다.

원래 책에서는 인덱스에 따른 진행을 사용했는데 여기서는 나는 그 방법을 쓰지 않았다.