diff options
Diffstat (limited to 'examples/widgets/widgets/tetrix.py')
-rw-r--r-- | examples/widgets/widgets/tetrix.py | 498 |
1 files changed, 0 insertions, 498 deletions
diff --git a/examples/widgets/widgets/tetrix.py b/examples/widgets/widgets/tetrix.py deleted file mode 100644 index 134eec4e4..000000000 --- a/examples/widgets/widgets/tetrix.py +++ /dev/null @@ -1,498 +0,0 @@ - -############################################################################# -## -## Copyright (C) 2013 Riverbank Computing Limited. -## Copyright (C) 2016 The Qt Company Ltd. -## Contact: http://www.qt.io/licensing/ -## -## This file is part of the Qt for Python examples of the Qt Toolkit. -## -## $QT_BEGIN_LICENSE:BSD$ -## You may use this file under the terms of the BSD license as follows: -## -## "Redistribution and use in source and binary forms, with or without -## modification, are permitted provided that the following conditions are -## met: -## * Redistributions of source code must retain the above copyright -## notice, this list of conditions and the following disclaimer. -## * Redistributions in binary form must reproduce the above copyright -## notice, this list of conditions and the following disclaimer in -## the documentation and/or other materials provided with the -## distribution. -## * Neither the name of The Qt Company Ltd nor the names of its -## contributors may be used to endorse or promote products derived -## from this software without specific prior written permission. -## -## -## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -## -## $QT_END_LICENSE$ -## -############################################################################# - -"""PySide2 port of the widgets/widgets/tetrix example from Qt v5.x""" - -import random - -from PySide2 import QtCore, QtGui, QtWidgets - - -NoShape, ZShape, SShape, LineShape, TShape, SquareShape, LShape, MirroredLShape = range(8) - - -class TetrixWindow(QtWidgets.QWidget): - def __init__(self): - super(TetrixWindow, self).__init__() - - self.board = TetrixBoard() - - nextPieceLabel = QtWidgets.QLabel() - nextPieceLabel.setFrameStyle(QtWidgets.QFrame.Box | QtWidgets.QFrame.Raised) - nextPieceLabel.setAlignment(QtCore.Qt.AlignCenter) - self.board.setNextPieceLabel(nextPieceLabel) - - scoreLcd = QtWidgets.QLCDNumber(5) - scoreLcd.setSegmentStyle(QtWidgets.QLCDNumber.Filled) - levelLcd = QtWidgets.QLCDNumber(2) - levelLcd.setSegmentStyle(QtWidgets.QLCDNumber.Filled) - linesLcd = QtWidgets.QLCDNumber(5) - linesLcd.setSegmentStyle(QtWidgets.QLCDNumber.Filled) - - startButton = QtWidgets.QPushButton("&Start") - startButton.setFocusPolicy(QtCore.Qt.NoFocus) - quitButton = QtWidgets.QPushButton("&Quit") - quitButton.setFocusPolicy(QtCore.Qt.NoFocus) - pauseButton = QtWidgets.QPushButton("&Pause") - pauseButton.setFocusPolicy(QtCore.Qt.NoFocus) - - startButton.clicked.connect(self.board.start) - pauseButton.clicked.connect(self.board.pause) - quitButton.clicked.connect(qApp.quit) - self.board.scoreChanged.connect(scoreLcd.display) - self.board.levelChanged.connect(levelLcd.display) - self.board.linesRemovedChanged.connect(linesLcd.display) - - layout = QtWidgets.QGridLayout() - layout.addWidget(self.createLabel("NEXT"), 0, 0) - layout.addWidget(nextPieceLabel, 1, 0) - layout.addWidget(self.createLabel("LEVEL"), 2, 0) - layout.addWidget(levelLcd, 3, 0) - layout.addWidget(startButton, 4, 0) - layout.addWidget(self.board, 0, 1, 6, 1) - layout.addWidget(self.createLabel("SCORE"), 0, 2) - layout.addWidget(scoreLcd, 1, 2) - layout.addWidget(self.createLabel("LINES REMOVED"), 2, 2) - layout.addWidget(linesLcd, 3, 2) - layout.addWidget(quitButton, 4, 2) - layout.addWidget(pauseButton, 5, 2) - self.setLayout(layout) - - self.setWindowTitle("Tetrix") - self.resize(550, 370) - - def createLabel(self, text): - lbl = QtWidgets.QLabel(text) - lbl.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignBottom) - return lbl - - -class TetrixBoard(QtWidgets.QFrame): - BoardWidth = 10 - BoardHeight = 22 - - scoreChanged = QtCore.Signal(int) - - levelChanged = QtCore.Signal(int) - - linesRemovedChanged = QtCore.Signal(int) - - def __init__(self, parent=None): - super(TetrixBoard, self).__init__(parent) - - self.timer = QtCore.QBasicTimer() - self.nextPieceLabel = None - self.isWaitingAfterLine = False - self.curPiece = TetrixPiece() - self.nextPiece = TetrixPiece() - self.curX = 0 - self.curY = 0 - self.numLinesRemoved = 0 - self.numPiecesDropped = 0 - self.score = 0 - self.level = 0 - self.board = None - - self.setFrameStyle(QtWidgets.QFrame.Panel | QtWidgets.QFrame.Sunken) - self.setFocusPolicy(QtCore.Qt.StrongFocus) - self.isStarted = False - self.isPaused = False - self.clearBoard() - - self.nextPiece.setRandomShape() - - def shapeAt(self, x, y): - return self.board[(y * TetrixBoard.BoardWidth) + x] - - def setShapeAt(self, x, y, shape): - self.board[(y * TetrixBoard.BoardWidth) + x] = shape - - def timeoutTime(self): - return 1000 / (1 + self.level) - - def squareWidth(self): - return self.contentsRect().width() / TetrixBoard.BoardWidth - - def squareHeight(self): - return self.contentsRect().height() / TetrixBoard.BoardHeight - - def setNextPieceLabel(self, label): - self.nextPieceLabel = label - - def sizeHint(self): - return QtCore.QSize(TetrixBoard.BoardWidth * 15 + self.frameWidth() * 2, - TetrixBoard.BoardHeight * 15 + self.frameWidth() * 2) - - def minimumSizeHint(self): - return QtCore.QSize(TetrixBoard.BoardWidth * 5 + self.frameWidth() * 2, - TetrixBoard.BoardHeight * 5 + self.frameWidth() * 2) - - def start(self): - if self.isPaused: - return - - self.isStarted = True - self.isWaitingAfterLine = False - self.numLinesRemoved = 0 - self.numPiecesDropped = 0 - self.score = 0 - self.level = 1 - self.clearBoard() - - self.linesRemovedChanged.emit(self.numLinesRemoved) - self.scoreChanged.emit(self.score) - self.levelChanged.emit(self.level) - - self.newPiece() - self.timer.start(self.timeoutTime(), self) - - def pause(self): - if not self.isStarted: - return - - self.isPaused = not self.isPaused - if self.isPaused: - self.timer.stop() - else: - self.timer.start(self.timeoutTime(), self) - - self.update() - - def paintEvent(self, event): - super(TetrixBoard, self).paintEvent(event) - - painter = QtGui.QPainter(self) - rect = self.contentsRect() - - if self.isPaused: - painter.drawText(rect, QtCore.Qt.AlignCenter, "Pause") - return - - boardTop = rect.bottom() - TetrixBoard.BoardHeight * self.squareHeight() - - for i in range(TetrixBoard.BoardHeight): - for j in range(TetrixBoard.BoardWidth): - shape = self.shapeAt(j, TetrixBoard.BoardHeight - i - 1) - if shape != NoShape: - self.drawSquare(painter, - rect.left() + j * self.squareWidth(), - boardTop + i * self.squareHeight(), shape) - - if self.curPiece.shape() != 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 + (TetrixBoard.BoardHeight - y - 1) * self.squareHeight(), - self.curPiece.shape()) - - def keyPressEvent(self, event): - if not self.isStarted or self.isPaused or self.curPiece.shape() == NoShape: - super(TetrixBoard, self).keyPressEvent(event) - return - - key = event.key() - if key == QtCore.Qt.Key_Left: - self.tryMove(self.curPiece, self.curX - 1, self.curY) - elif key == QtCore.Qt.Key_Right: - self.tryMove(self.curPiece, self.curX + 1, self.curY) - elif key == QtCore.Qt.Key_Down: - self.tryMove(self.curPiece.rotatedRight(), self.curX, self.curY) - elif key == QtCore.Qt.Key_Up: - self.tryMove(self.curPiece.rotatedLeft(), self.curX, self.curY) - elif key == QtCore.Qt.Key_Space: - self.dropDown() - elif key == QtCore.Qt.Key_D: - self.oneLineDown() - else: - super(TetrixBoard, self).keyPressEvent(event) - - def timerEvent(self, event): - if event.timerId() == self.timer.timerId(): - if self.isWaitingAfterLine: - self.isWaitingAfterLine = False - self.newPiece() - self.timer.start(self.timeoutTime(), self) - else: - self.oneLineDown() - else: - super(TetrixBoard, self).timerEvent(event) - - def clearBoard(self): - self.board = [NoShape for i in range(TetrixBoard.BoardHeight * TetrixBoard.BoardWidth)] - - def dropDown(self): - dropHeight = 0 - newY = self.curY - while newY > 0: - if not self.tryMove(self.curPiece, self.curX, newY - 1): - break - newY -= 1 - dropHeight += 1 - - self.pieceDropped(dropHeight) - - def oneLineDown(self): - if not self.tryMove(self.curPiece, self.curX, self.curY - 1): - self.pieceDropped(0) - - def pieceDropped(self, dropHeight): - 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.numPiecesDropped += 1 - if self.numPiecesDropped % 25 == 0: - self.level += 1 - self.timer.start(self.timeoutTime(), self) - self.levelChanged.emit(self.level) - - self.score += dropHeight + 7 - self.scoreChanged.emit(self.score) - self.removeFullLines() - - if not self.isWaitingAfterLine: - self.newPiece() - - def removeFullLines(self): - numFullLines = 0 - - for i in range(TetrixBoard.BoardHeight - 1, -1, -1): - lineIsFull = True - - for j in range(TetrixBoard.BoardWidth): - if self.shapeAt(j, i) == NoShape: - lineIsFull = False - break - - if lineIsFull: - numFullLines += 1 - for k in range(TetrixBoard.BoardHeight - 1): - for j in range(TetrixBoard.BoardWidth): - self.setShapeAt(j, k, self.shapeAt(j, k + 1)) - - for j in range(TetrixBoard.BoardWidth): - self.setShapeAt(j, TetrixBoard.BoardHeight - 1, NoShape) - - if numFullLines > 0: - self.numLinesRemoved += numFullLines - self.score += 10 * numFullLines - self.linesRemovedChanged.emit(self.numLinesRemoved) - self.scoreChanged.emit(self.score) - - self.timer.start(500, self) - self.isWaitingAfterLine = True - self.curPiece.setShape(NoShape) - self.update() - - def newPiece(self): - self.curPiece = self.nextPiece - self.nextPiece.setRandomShape() - self.showNextPiece() - self.curX = TetrixBoard.BoardWidth // 2 + 1 - self.curY = TetrixBoard.BoardHeight - 1 + self.curPiece.minY() - - if not self.tryMove(self.curPiece, self.curX, self.curY): - self.curPiece.setShape(NoShape) - self.timer.stop() - self.isStarted = False - - def showNextPiece(self): - if self.nextPieceLabel is not None: - return - - dx = self.nextPiece.maxX() - self.nextPiece.minX() + 1 - dy = self.nextPiece.maxY() - self.nextPiece.minY() + 1 - - pixmap = QtGui.QPixmap(dx * self.squareWidth(), dy * self.squareHeight()) - painter = QtGui.QPainter(pixmap) - painter.fillRect(pixmap.rect(), self.nextPieceLabel.palette().background()) - - for int in range(4): - x = self.nextPiece.x(i) - self.nextPiece.minX() - y = self.nextPiece.y(i) - self.nextPiece.minY() - self.drawSquare(painter, x * self.squareWidth(), - y * self.squareHeight(), self.nextPiece.shape()) - - self.nextPieceLabel.setPixmap(pixmap) - - 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 >= TetrixBoard.BoardWidth or y < 0 or y >= TetrixBoard.BoardHeight: - return False - if self.shapeAt(x, y) != NoShape: - return False - - self.curPiece = newPiece - self.curX = newX - self.curY = newY - self.update() - return True - - def drawSquare(self, painter, x, y, shape): - colorTable = [0x000000, 0xCC6666, 0x66CC66, 0x6666CC, - 0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00] - - color = QtGui.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 TetrixPiece(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 _ in range(4)] - self.pieceShape = NoShape - - self.setShape(NoShape) - - def shape(self): - return self.pieceShape - - def setShape(self, shape): - table = TetrixPiece.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): - self.setShape(random.randint(1, 7)) - - def x(self, index): - return self.coords[index][0] - - def y(self, index): - return self.coords[index][1] - - def setX(self, index, x): - self.coords[index][0] = x - - def setY(self, index, y): - self.coords[index][1] = y - - def minX(self): - m = self.coords[0][0] - for i in range(4): - m = min(m, self.coords[i][0]) - - return m - - def maxX(self): - m = self.coords[0][0] - for i in range(4): - m = max(m, self.coords[i][0]) - - return m - - def minY(self): - m = self.coords[0][1] - for i in range(4): - m = min(m, self.coords[i][1]) - - return m - - def maxY(self): - m = self.coords[0][1] - for i in range(4): - m = max(m, self.coords[i][1]) - - return m - - def rotatedLeft(self): - if self.pieceShape == SquareShape: - return self - - result = TetrixPiece() - result.pieceShape = self.pieceShape - for i in range(4): - result.setX(i, self.y(i)) - result.setY(i, -self.x(i)) - - return result - - def rotatedRight(self): - if self.pieceShape == SquareShape: - return self - - result = TetrixPiece() - 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__': - - import sys - - app = QtWidgets.QApplication(sys.argv) - window = TetrixWindow() - window.show() - random.seed(None) - sys.exit(app.exec_()) |