pyqt 5 러시아 블록 게임 실현

25185 단어 pyqt5러시아 블록
이 장 에서 우 리 는 러시아 블록 게임 을 만 들 려 고 한다.
Tetris
번역:호칭:사각형 은 네 개의 작은 사각형 으로 구성 되 어 있다.
러시아 블록 게임 은 세계 에서 가장 유행 하 는 게임 중의 하나 이다.Alexey Pajitnov 라 는 러시아 프로그래머 가 1985 년 에 제 작 했 는데 그때 부터 이 게임 은 각 게임 플랫폼 을 휩 쓸 었 다.
러시아 블록 은 낙하 블록 미로 게임 으로 분류 된다.게임 은 7 개의 기본 모양 이 있 습 니 다.S,Z,T,L,역방향 L,직선,사각형 으로 모든 모양 은 4 개의 사각형 으로 구성 되 고 사각형 은 최종 적 으로 화면 밑 에 떨 어 집 니 다.그래서 유 저 는 모양 의 좌우 위치 와 회전 을 제어 하여 모든 모양 을 적당 한 위치 로 떨 어 뜨 립 니 다.한 줄 이 모두 사각형 으로 채 워 지면 이 줄 은 사라 지고 득점 합 니 다.게임 이 끝 난 조건 은 화면 상단 에 모양 이 닿 았 다 는 것 이다.
사각형 전시:

PyQt 5 는 그래 픽 인터페이스 를 만 들 기 위해 만들어 진 것 으로 게임 을 만 들 기 위해 개 발 된 구성 요소 들 이 있 기 때문에 PyQt 5 는 작은 게임 을 만 들 수 있 습 니 다.
컴퓨터 게임 을 만 드 는 것 도 자신의 프로 그래 밍 능력 을 향상 시 키 는 좋 은 방법 이다.
개발 하 다.
그림 이 없어 서 스스로 그림 으로 몇 개의 그림 을 그 렸 다.게임 마다 수학 모형 이 있 는데 이것 도 그래 요.
작업 시작 전:
  • QtCore.QBasic Timer()로 게임 순환
  • 만 들 기
  • 모델 은 계속 떨 어 지 는
  • 입 니 다.
  • 모델 의 운동 은 작은 덩어리 를 바탕 으로 하 는 것 이지 픽 셀
  • 이 아니다.
  • 수학 적 의미 에서 볼 때 모델 은 한 줄 의 숫자 일 뿐이다
  • 코드 는 네 가지 유형 으로 구성 되 어 있 습 니 다.Tetris,Board,Tetrominoe 와 Shape 입 니 다.Tetris 류 는 게임 을 만 들 고 Board 는 게임 의 주요 논리 입 니 다.Tetrominoe 는 모든 벽돌 을 포함 하고 Shape 는 모든 벽돌의 코드 입 니 다.
    
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    
    """
    ZetCode PyQt5 tutorial 
    This is a Tetris game clone.
    
    Author: Jan Bodnar
    Website: zetcode.com 
    Last edited: August 2017
    """
    
    from PyQt5.QtWidgets import QMainWindow, QFrame, QDesktopWidget, QApplication
    from PyQt5.QtCore import Qt, QBasicTimer, pyqtSignal
    from PyQt5.QtGui import QPainter, QColor 
    import sys, random
    
    class Tetris(QMainWindow):
      
      def __init__(self):
        super().__init__()
        
        self.initUI()
        
        
      def initUI(self):  
        '''initiates application UI'''
    
        self.tboard = Board(self)
        self.setCentralWidget(self.tboard)
    
        self.statusbar = self.statusBar()    
        self.tboard.msg2Statusbar[str].connect(self.statusbar.showMessage)
        
        self.tboard.start()
        
        self.resize(180, 380)
        self.center()
        self.setWindowTitle('Tetris')    
        self.show()
        
    
      def center(self):
        '''centers the window on the screen'''
        
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width()-size.width())/2, 
          (screen.height()-size.height())/2)
        
    
    class Board(QFrame):
      
      msg2Statusbar = pyqtSignal(str)
      
      BoardWidth = 10
      BoardHeight = 22
      Speed = 300
    
      def __init__(self, parent):
        super().__init__(parent)
        
        self.initBoard()
        
        
      def initBoard(self):   
        '''initiates board'''
    
        self.timer = QBasicTimer()
        self.isWaitingAfterLine = False
        
        self.curX = 0
        self.curY = 0
        self.numLinesRemoved = 0
        self.board = []
    
        self.setFocusPolicy(Qt.StrongFocus)
        self.isStarted = False
        self.isPaused = False
        self.clearBoard()
        
        
      def shapeAt(self, x, y):
        '''determines shape at the board position'''
        
        return self.board[(y * Board.BoardWidth) + x]
    
        
      def setShapeAt(self, x, y, shape):
        '''sets a shape at the board'''
        
        self.board[(y * Board.BoardWidth) + x] = shape
        
    
      def squareWidth(self):
        '''returns the width of one square'''
        
        return self.contentsRect().width() // Board.BoardWidth
        
    
      def squareHeight(self):
        '''returns the height of one square'''
        
        return self.contentsRect().height() // Board.BoardHeight
        
    
      def start(self):
        '''starts game'''
        
        if self.isPaused:
          return
    
        self.isStarted = True
        self.isWaitingAfterLine = False
        self.numLinesRemoved = 0
        self.clearBoard()
    
        self.msg2Statusbar.emit(str(self.numLinesRemoved))
    
        self.newPiece()
        self.timer.start(Board.Speed, self)
    
        
      def pause(self):
        '''pauses game'''
        
        if not self.isStarted:
          return
    
        self.isPaused = not self.isPaused
        
        if self.isPaused:
          self.timer.stop()
          self.msg2Statusbar.emit("paused")
          
        else:
          self.timer.start(Board.Speed, self)
          self.msg2Statusbar.emit(str(self.numLinesRemoved))
    
        self.update()
    
        
      def paintEvent(self, event):
        '''paints all shapes of the game'''
        
        painter = QPainter(self)
        rect = self.contentsRect()
    
        boardTop = rect.bottom() - Board.BoardHeight * self.squareHeight()
    
        for i in range(Board.BoardHeight):
          for j in range(Board.BoardWidth):
            shape = self.shapeAt(j, Board.BoardHeight - i - 1)
            
            if shape != Tetrominoe.NoShape:
              self.drawSquare(painter,
                rect.left() + j * self.squareWidth(),
                boardTop + i * self.squareHeight(), shape)
    
        if self.curPiece.shape() != Tetrominoe.NoShape:
          
          for i in range(4):
            
            x = self.curX + self.curPiece.x(i)
            y = self.curY - self.curPiece.y(i)
            self.drawSquare(painter, rect.left() + x * self.squareWidth(),
              boardTop + (Board.BoardHeight - y - 1) * self.squareHeight(),
              self.curPiece.shape())
    
              
      def keyPressEvent(self, event):
        '''processes key press events'''
        
        if not self.isStarted or self.curPiece.shape() == Tetrominoe.NoShape:
          super(Board, self).keyPressEvent(event)
          return
    
        key = event.key()
        
        if key == Qt.Key_P:
          self.pause()
          return
          
        if self.isPaused:
          return
            
        elif key == Qt.Key_Left:
          self.tryMove(self.curPiece, self.curX - 1, self.curY)
          
        elif key == Qt.Key_Right:
          self.tryMove(self.curPiece, self.curX + 1, self.curY)
          
        elif key == Qt.Key_Down:
          self.tryMove(self.curPiece.rotateRight(), self.curX, self.curY)
          
        elif key == Qt.Key_Up:
          self.tryMove(self.curPiece.rotateLeft(), self.curX, self.curY)
          
        elif key == Qt.Key_Space:
          self.dropDown()
          
        elif key == Qt.Key_D:
          self.oneLineDown()
          
        else:
          super(Board, self).keyPressEvent(event)
            
    
      def timerEvent(self, event):
        '''handles timer event'''
        
        if event.timerId() == self.timer.timerId():
          
          if self.isWaitingAfterLine:
            self.isWaitingAfterLine = False
            self.newPiece()
          else:
            self.oneLineDown()
            
        else:
          super(Board, self).timerEvent(event)
    
          
      def clearBoard(self):
        '''clears shapes from the board'''
        
        for i in range(Board.BoardHeight * Board.BoardWidth):
          self.board.append(Tetrominoe.NoShape)
    
        
      def dropDown(self):
        '''drops down a shape'''
        
        newY = self.curY
        
        while newY > 0:
          
          if not self.tryMove(self.curPiece, self.curX, newY - 1):
            break
            
          newY -= 1
    
        self.pieceDropped()
        
    
      def oneLineDown(self):
        '''goes one line down with a shape'''
        
        if not self.tryMove(self.curPiece, self.curX, self.curY - 1):
          self.pieceDropped()
          
    
      def pieceDropped(self):
        '''after dropping shape, remove full lines and create new shape'''
        
        for i in range(4):
          
          x = self.curX + self.curPiece.x(i)
          y = self.curY - self.curPiece.y(i)
          self.setShapeAt(x, y, self.curPiece.shape())
    
        self.removeFullLines()
    
        if not self.isWaitingAfterLine:
          self.newPiece()
          
    
      def removeFullLines(self):
        '''removes all full lines from the board'''
        
        numFullLines = 0
        rowsToRemove = []
    
        for i in range(Board.BoardHeight):
          
          n = 0
          for j in range(Board.BoardWidth):
            if not self.shapeAt(j, i) == Tetrominoe.NoShape:
              n = n + 1
    
          if n == 10:
            rowsToRemove.append(i)
    
        rowsToRemove.reverse()
        
    
        for m in rowsToRemove:
          
          for k in range(m, Board.BoardHeight):
            for l in range(Board.BoardWidth):
                self.setShapeAt(l, k, self.shapeAt(l, k + 1))
    
        numFullLines = numFullLines + len(rowsToRemove)
    
        if numFullLines > 0:
          
          self.numLinesRemoved = self.numLinesRemoved + numFullLines
          self.msg2Statusbar.emit(str(self.numLinesRemoved))
            
          self.isWaitingAfterLine = True
          self.curPiece.setShape(Tetrominoe.NoShape)
          self.update()
          
    
      def newPiece(self):
        '''creates a new shape'''
        
        self.curPiece = Shape()
        self.curPiece.setRandomShape()
        self.curX = Board.BoardWidth // 2 + 1
        self.curY = Board.BoardHeight - 1 + self.curPiece.minY()
        
        if not self.tryMove(self.curPiece, self.curX, self.curY):
          
          self.curPiece.setShape(Tetrominoe.NoShape)
          self.timer.stop()
          self.isStarted = False
          self.msg2Statusbar.emit("Game over")
    
    
    
      def tryMove(self, newPiece, newX, newY):
        '''tries to move a shape'''
        
        for i in range(4):
          
          x = newX + newPiece.x(i)
          y = newY - newPiece.y(i)
          
          if x < 0 or x >= Board.BoardWidth or y < 0 or y >= Board.BoardHeight:
            return False
            
          if self.shapeAt(x, y) != Tetrominoe.NoShape:
            return False
    
        self.curPiece = newPiece
        self.curX = newX
        self.curY = newY
        self.update()
        
        return True
        
    
      def drawSquare(self, painter, x, y, shape):
        '''draws a square of a shape'''    
        
        colorTable = [0x000000, 0xCC6666, 0x66CC66, 0x6666CC,
               0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00]
    
        color = QColor(colorTable[shape])
        painter.fillRect(x + 1, y + 1, self.squareWidth() - 2, 
          self.squareHeight() - 2, color)
    
        painter.setPen(color.lighter())
        painter.drawLine(x, y + self.squareHeight() - 1, x, y)
        painter.drawLine(x, y, x + self.squareWidth() - 1, y)
    
        painter.setPen(color.darker())
        painter.drawLine(x + 1, y + self.squareHeight() - 1,
          x + self.squareWidth() - 1, y + self.squareHeight() - 1)
        painter.drawLine(x + self.squareWidth() - 1, 
          y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + 1)
    
    
    class Tetrominoe(object):
      
      NoShape = 0
      ZShape = 1
      SShape = 2
      LineShape = 3
      TShape = 4
      SquareShape = 5
      LShape = 6
      MirroredLShape = 7
    
    
    class Shape(object):
      
      coordsTable = (
        ((0, 0),   (0, 0),   (0, 0),   (0, 0)),
        ((0, -1),  (0, 0),   (-1, 0),  (-1, 1)),
        ((0, -1),  (0, 0),   (1, 0),   (1, 1)),
        ((0, -1),  (0, 0),   (0, 1),   (0, 2)),
        ((-1, 0),  (0, 0),   (1, 0),   (0, 1)),
        ((0, 0),   (1, 0),   (0, 1),   (1, 1)),
        ((-1, -1),  (0, -1),  (0, 0),   (0, 1)),
        ((1, -1),  (0, -1),  (0, 0),   (0, 1))
      )
    
      def __init__(self):
        
        self.coords = [[0,0] for i in range(4)]
        self.pieceShape = Tetrominoe.NoShape
    
        self.setShape(Tetrominoe.NoShape)
        
    
      def shape(self):
        '''returns shape'''
        
        return self.pieceShape
        
    
      def setShape(self, shape):
        '''sets a shape'''
        
        table = Shape.coordsTable[shape]
        
        for i in range(4):
          for j in range(2):
            self.coords[i][j] = table[i][j]
    
        self.pieceShape = shape
        
    
      def setRandomShape(self):
        '''chooses a random shape'''
        
        self.setShape(random.randint(1, 7))
    
        
      def x(self, index):
        '''returns x coordinate'''
        
        return self.coords[index][0]
    
        
      def y(self, index):
        '''returns y coordinate'''
        
        return self.coords[index][1]
    
        
      def setX(self, index, x):
        '''sets x coordinate'''
        
        self.coords[index][0] = x
    
        
      def setY(self, index, y):
        '''sets y coordinate'''
        
        self.coords[index][1] = y
    
        
      def minX(self):
        '''returns min x value'''
        
        m = self.coords[0][0]
        for i in range(4):
          m = min(m, self.coords[i][0])
    
        return m
    
        
      def maxX(self):
        '''returns max x value'''
        
        m = self.coords[0][0]
        for i in range(4):
          m = max(m, self.coords[i][0])
    
        return m
    
        
      def minY(self):
        '''returns min y value'''
        
        m = self.coords[0][1]
        for i in range(4):
          m = min(m, self.coords[i][1])
    
        return m
    
        
      def maxY(self):
        '''returns max y value'''
        
        m = self.coords[0][1]
        for i in range(4):
          m = max(m, self.coords[i][1])
    
        return m
    
        
      def rotateLeft(self):
        '''rotates shape to the left'''
        
        if self.pieceShape == Tetrominoe.SquareShape:
          return self
    
        result = Shape()
        result.pieceShape = self.pieceShape
        
        for i in range(4):
          
          result.setX(i, self.y(i))
          result.setY(i, -self.x(i))
    
        return result
    
        
      def rotateRight(self):
        '''rotates shape to the right'''
        
        if self.pieceShape == Tetrominoe.SquareShape:
          return self
    
        result = Shape()
        result.pieceShape = self.pieceShape
        
        for i in range(4):
          
          result.setX(i, -self.y(i))
          result.setY(i, self.x(i))
    
        return result
    
    
    if __name__ == '__main__':
      
      app = QApplication([])
      tetris = Tetris()  
      sys.exit(app.exec_())
    게임 은 간단 해서 이해 하기 쉽 습 니 다.프로그램 을 불 러 온 후에 게임 도 바로 시 작 됩 니 다.P 키 로 게임 을 중단 할 수 있 고 스페이스 바 는 사각형 을 맨 아래로 떨 어 뜨 릴 수 있 습 니 다.게임 의 속 도 는 고정 적 이 고 가속 기능 을 실현 하지 못 했다.점 수 는 게임 에서 제 거 된 줄 수 입 니 다.
    
    self.tboard = Board(self)
    self.setCentralWidget(self.tboard)
    Board 클래스 의 인 스 턴 스 를 만 들 고 응용 중심 구성 요소 로 설정 합 니 다.
    
    self.statusbar = self.statusBar()    
    self.tboard.msg2Statusbar[str].connect(self.statusbar.showMessage)
    세 가지 정 보 를 표시 하기 위해 statusbar 을 만 듭 니 다.제 거 된 줄 수,게임 일시 정지 상태 또는 게임 종료 상태 입 니 다.msg2Statusbar 은 사용자 정의 신호 로 Board 류(상호작용)에 사용 되 며 showMessage() 방법 은 내 장 된 것 으로 status bar 에 정 보 를 표시 하 는 방법 입 니 다.
    
    self.tboard.start()
    게임 초기 화:
    
    class Board(QFrame):
      
      msg2Statusbar = pyqtSignal(str)
    ...  
    사용자 정의 신호 msg2Statusbar 을 만 들 었 습 니 다.statusbar 에 메 시 지 를 표시 하고 싶 을 때 이 신 호 를 보 내 면 됩 니 다.
    
    BoardWidth = 10
    BoardHeight = 22
    Speed = 300
    이것들 은 Board 류 의 변수 이다.BoardWidthBoardHeight 은 각각 board 의 너비 와 높이 이다.Speed 은 게임 의 속도 로 300 ms 마다 새로운 사각형 이 나타난다.
    
    ...
    self.curX = 0
    self.curY = 0
    self.numLinesRemoved = 0
    self.board = []
    ...
    initBoard() 에서 중요 한 변 수 를 초기 화 했다.self.board 은 사각형 의 모양 과 위 치 를 정 의 했 고 수치 범 위 는 0-7 이다.
    
    def shapeAt(self, x, y):
      return self.board[(y * Board.BoardWidth) + x]
    shapeAt() 은 board 안의 사각형 의 종 류 를 결정 한다.
    
    def squareWidth(self):
      return self.contentsRect().width() // Board.BoardWidth
    board 의 크기 는 동적 으로 변 할 수 있 습 니 다.그래서 격자 의 크기 도 이에 따라 달라 져 야 한다.squareWidth() 은 각 블록 이 얼마나 많은 픽 셀 을 차지 해 야 하 는 지 계산 하고 되 돌려 줍 니 다.즉,Board.BoardWidth 입 니 다.
    
    def pause(self):
      '''pauses game'''
    
      if not self.isStarted:
        return
    
      self.isPaused = not self.isPaused
    
      if self.isPaused:
        self.timer.stop()
        self.msg2Statusbar.emit("paused")
    
      else:
        self.timer.start(Board.Speed, self)
        self.msg2Statusbar.emit(str(self.numLinesRemoved))
    
      self.update()
    pause() 방법 은 게임 을 중단 하고 시간 을 멈 추 며 statusbar 에 메 시 지 를 표시 합 니 다.
    
    def paintEvent(self, event):
      '''paints all shapes of the game'''
    
      painter = QPainter(self)
      rect = self.contentsRect()
    ...
    렌 더 링 은 paintEvent()방법 에서 발생 하 는 QPainter 으로 PyQt 5 의 모든 저급 회화 작업 을 책임 집 니 다.
    
    for i in range(Board.BoardHeight):
      for j in range(Board.BoardWidth):
        shape = self.shapeAt(j, Board.BoardHeight - i - 1)
        
        if shape != Tetrominoe.NoShape:
          self.drawSquare(painter,
            rect.left() + j * self.squareWidth(),
            boardTop + i * self.squareHeight(), shape)
    렌 더 링 게임 은 두 단계 로 나 뉜 다.첫 번 째 단 계 는 이미 맨 아래 에 떨 어 진 모든 그림 을 그 려 서 self.board 리 에 보존 하 는 것 이다.shapeAt() 을 사용 하여 이 변 수 를 볼 수 있 습 니 다.
    
    if self.curPiece.shape() != Tetrominoe.NoShape:
      
      for i in range(4):
        
        x = self.curX + self.curPiece.x(i)
        y = self.curY - self.curPiece.y(i)
        self.drawSquare(painter, rect.left() + x * self.squareWidth(),
          boardTop + (Board.BoardHeight - y - 1) * self.squareHeight(),
          self.curPiece.shape())
    두 번 째 단 계 는 더 떨 어 지 는 사각형 을 그 리 는 것 이다.
    
    elif key == Qt.Key_Right:
      self.tryMove(self.curPiece, self.curX + 1, self.curY)
    keyPressEvent() 방법 으로 사용자 가 누 른 버튼 을 얻 을 수 있 습 니 다.오른쪽 방향 키 를 누 르 면 사각형 을 오른쪽으로 이동 해 보 세 요.경계 로 이동 할 수 없 기 때 문 이 라 고 합 니 다.
    
    elif key == Qt.Key_Up:
      self.tryMove(self.curPiece.rotateLeft(), self.curX, self.curY)
    위쪽 키 는 사각형 을 왼쪽으로 돌려 줍 니 다.
    
    elif key == Qt.Key_Space:
      self.dropDown()
    스페이스 바 는 바로 아래쪽 에 사각형 을 놓 습 니 다.
    
    elif key == Qt.Key_D:
      self.oneLineDown()
    D 키 는 한 번 의 낙하 속 도 를 가속 화 합 니 다.
    
    def tryMove(self, newPiece, newX, newY):
      
      for i in range(4):
        
        x = newX + newPiece.x(i)
        y = newY - newPiece.y(i)
        
        if x < 0 or x >= Board.BoardWidth or y < 0 or y >= Board.BoardHeight:
          return False
          
        if self.shapeAt(x, y) != Tetrominoe.NoShape:
          return False
    
      self.curPiece = newPiece
      self.curX = newX
      self.curY = newY
      self.update()
      return True
    tryMove() 은 사각형 을 이동 하 는 방법 이다.사각형 이 board 의 가장자리 에 도 착 했 거나 다른 사각형 을 만 났 다 면 False 로 돌아 갑 니 다.그렇지 않 으 면 사각형 을 원 하 는 곳 으로 떨 어 뜨 릴 것 이다.
    
    def timerEvent(self, event):
      
      if event.timerId() == self.timer.timerId():
        
        if self.isWaitingAfterLine:
          self.isWaitingAfterLine = False
          self.newPiece()
        else:
          self.oneLineDown()
          
      else:
        super(Board, self).timerEvent(event)
    타이머 이벤트 에 서 는 사각형 이 떨 어 진 후에 새로운 사각형 을 만 들 거나 사각형 을 끝까지 떨 어 뜨리 거나(move a falling piece one line down).
    
    def clearBoard(self):
      
      for i in range(Board.BoardHeight * Board.BoardWidth):
        self.board.append(Tetrominoe.NoShape)
    clearBoard()방법 은 Tetrominoe.NoShape 을 통 해 broad 을 비 웁 니 다.
    
    def removeFullLines(self):
      
      numFullLines = 0
      rowsToRemove = []
    
      for i in range(Board.BoardHeight):
        
        n = 0
        for j in range(Board.BoardWidth):
          if not self.shapeAt(j, i) == Tetrominoe.NoShape:
            n = n + 1
    
        if n == 10:
          rowsToRemove.append(i)
    
      rowsToRemove.reverse()
      
    
      for m in rowsToRemove:
        
        for k in range(m, Board.BoardHeight):
          for l in range(Board.BoardWidth):
              self.setShapeAt(l, k, self.shapeAt(l, k + 1))
    
      numFullLines = numFullLines + len(rowsToRemove)
     ...
    사각형 이 바닥 에 닿 으 면 removeFullLines() 방법 으로 제거 할 수 있 는 모든 줄 을 찾 아 제거 합 니 다.제거 의 구체 적 인 동작 은 조건 에 맞 는 줄 을 제거 한 후에 그 위의 줄 을 한 줄 내 리 는 것 이다.만 행 을 제거 하 는 동작 은 거꾸로 되 어 있 습 니 다.왜냐하면 우 리 는 중력 에 따라 게임 을 표현 하기 때 문 입 니 다.그렇지 않 으 면 사각형 이 공중 에 떠 있 는 현상 이 나타 날 수 있 습 니 다.
    
    def newPiece(self):
      
      self.curPiece = Shape()
      self.curPiece.setRandomShape()
      self.curX = Board.BoardWidth // 2 + 1
      self.curY = Board.BoardHeight - 1 + self.curPiece.minY()
      
      if not self.tryMove(self.curPiece, self.curX, self.curY):
        
        self.curPiece.setShape(Tetrominoe.NoShape)
        self.timer.stop()
        self.isStarted = False
        self.msg2Statusbar.emit("Game over")
    newPiece() 방법 은 무 작위 모양 의 사각형 을 만 드 는 데 쓰 인 다.무 작위 사각형 이 미리 설 정 된 위치 에 정확하게 나타 나 지 않 으 면 게임 이 끝 납 니 다.
    
    class Tetrominoe(object):
      
      NoShape = 0
      ZShape = 1
      SShape = 2
      LineShape = 3
      TShape = 4
      SquareShape = 5
      LShape = 6
      MirroredLShape = 7
    Tetrominoe 류 는 모든 사각형 의 모양 을 보존 했다.우 리 는 또 NoShape 의 빈 모양 을 정의 했다.
    Shape 클래스 는 클래스 블록 내부 의 정 보 를 저장 합 니 다.
    
    class Shape(object):
      
      coordsTable = (
        ((0, 0),   (0, 0),   (0, 0),   (0, 0)),
        ((0, -1),  (0, 0),   (-1, 0),  (-1, 1)),
        ...
      )
    ...  
    coords Table 모듈 은 모든 사각형 모양 의 구성 을 저장 합 니 다.사각형 을 구성 하 는 좌표 모형 이다.
    
    self.coords = [[0,0] for i in range(4)]
    위 에 새 빈 좌표 배열 을 만 들 었 습 니 다.이 배열 은 사각형 의 좌 표를 저장 하 는 데 사 용 될 것 입 니 다.
    좌표계 설명도:

    위의 그림 은 우리 가 좌표 값 의 의 미 를 더욱 잘 이해 하 는 데 도움 을 줄 수 있다.예 를 들 어 원조 (0, -1), (0, 0), (-1, 0), (-1, -1) 은 Z 모양 의 사각형 을 대표 한다.이 도 표 는 이 형상 을 묘사 했다.
    
    def rotateLeft(self):
      
      if self.pieceShape == Tetrominoe.SquareShape:
        return self
    
      result = Shape()
      result.pieceShape = self.pieceShape
      
      for i in range(4):
        
        result.setX(i, self.y(i))
        result.setY(i, -self.x(i))
    
      return result
    rotateLeft() 방법 으로 오른쪽 으로 사각형 을 회전 합 니 다.정사각형 의 사각형 은 회전 할 필요 가 없 이 바로 돌 아 왔 다.다른 것 은 이 모양 이 회전 했다 는 것 을 나타 내 는 새로운 좌 표를 되 돌려 주 는 것 이다.
    프로그램 표시:

    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기