本帖最后由 lightninng 于 2021-11-20 14:47 编辑
11.4.4 方块颜色显然直接用内置的fillRect方法绘制的方块太丑了,随便上网就能找到一大把好的素材,下面说说怎么把方块变的好看一些。分析了教程的代码,可以知道方块的绘制是用draw_squre方法完成的,看看改了之后的draw_squre代码。 def draw_square(self, x, y, square_type):
shape_table = [0x000000, QPixmap(":source\Red.png"),
QPixmap(":source\Green.png"), QPixmap(":source\Blue.png"),
QPixmap(":source\Yellow.png"), QPixmap(":source\Purple.png"),
QPixmap(":source\Water_Green.png"), QPixmap(":source\Orange.png")]
color_table = [(0, 0, 0), (190, 110, 110), (160, 190, 110), (110, 140, 190),
(165, 170, 180), (150, 130, 180), (100, 180, 190), (190, 135, 80)]
# 调用get_square_width方法和get_square_height方法获取方块的长和宽
square_width, square_height = self.get_square_width(), self.get_square_height()
painter = QPainter(self)
# 绘制方块内部
painter.drawPixmap(x + 1, y + 1, square_width - 2, square_height - 2, shape_table[square_type])
# 绘制方块边框
color = QColor(*color_table[square_type])
painter.setPen(color.lighter())
painter.drawLine(x, y, x + square_width - 1, y)
painter.drawLine(x, y, x, y + square_height - 1)
painter.setPen(color.darker())
painter.drawLine(x + square_width - 1, y + 1, x + square_width - 1, y + square_height - 1)
painter.drawLine(x + 1, y + square_height - 1, x + square_width - 1, y + square_height - 1)
其实改动最大的只有一点就是我们把调用fillRect方法改为了调用drawPixmap,fillRect方法绘制一个矩形颜色块,而drawPixmap绘制一个pixmap图形。 shape_table = [0x000000, QPixmap(":source\Red.png"), ... ]
首先我们将各种不同形状的俄罗斯方块的图片读取到shape_table中。 painter.drawPixmap(x + 1, y + 1, square_width - 2, square_height - 2, shape_table[square_type])
然后调用drawPixmap方法以指定的位置和大小将pixmap对象绘制到部件上。 11.4.5 初步的成果经过上面的讨论,我们初步写了一些代码,这里面包括自适应背景图的CentralWidget部件的一些代码,以及游戏主面板(GameBoard)和显示下一个块的面板(NextBoard)的基类(Board)的代码: from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QFrame, QLabel
# from PyQt5.QtCore import
from PyQt5.QtGui import QPixmap, QImage, QPainter, QPalette, QBrush, QColor
import tetris_file
class Tetris(QMainWindow):
def __init__(self):
super(Tetris, self).__init__()
self.resize(450, 660)
self.setCentralWidget(CentralWidget()) # 设置Board为中心部件看看效果
class CentralWidget(QWidget):
def __init__(self):
super(CentralWidget, self).__init__()
# 设置背景图案
self.background = QImage(r":source\ground.png")
self.setAutoFillBackground(True)
def resizeEvent(self, event):
# 重写resizeEvent, 使背景图案可以根据窗口大小改变
QWidget.resizeEvent(self, event)
palette = QPalette()
palette.setBrush(QPalette.Window, QBrush(self.background.scaled(event.size())))
self.setPalette(palette)
class Board(QFrame):
def __init__(self, parent=None):
super(Board, self).__init__(parent)
# 设置面板边框
self.setStyleSheet("border: 1px groove gray; border-radius: 5px; ")
def get_square_width(self):
return 100
def get_square_height(self):
return 100
def paintEvent(self, event):
# 重写panitEvent,绘制一个方块在Board上看看效果
self.draw_square(self.contentsRect().width()/2, self.contentsRect().height()/2, 1)
def draw_square(self, x, y, square_type):
shape_table = [0x000000, QPixmap(":source\Red.png"),
QPixmap(":source\Green.png"), QPixmap(":source\Blue.png"),
QPixmap(":source\Yellow.png"), QPixmap(":source\Purple.png"),
QPixmap(":source\Water_Green.png"), QPixmap(":source\Orange.png")]
color_table = [(0, 0, 0), (190, 110, 110), (160, 190, 110), (110, 140, 190),
(165, 170, 180), (150, 130, 180), (100, 180, 190), (190, 135, 80)]
# 调用get_square_width方法和get_square_height方法获取方块的长和宽
square_width, square_height = self.get_square_width(), self.get_square_height()
painter = QPainter(self)
# 绘制方块内部
painter.drawPixmap(x + 1, y + 1, square_width - 2, square_height - 2, shape_table[square_type])
# 绘制方块边框
color = QColor(*color_table[square_type])
painter.setPen(color.lighter())
painter.drawLine(x, y, x + square_width - 1, y)
painter.drawLine(x, y, x, y + square_height - 1)
painter.setPen(color.darker())
painter.drawLine(x + square_width - 1, y + 1, x + square_width - 1, y + square_height - 1)
painter.drawLine(x + 1, y + square_height - 1, x + square_width - 1, y + square_height - 1)
class GameBoard(Board):
pass
class NextBoard(Board):
pass
class ScoreBoard(QLabel):
pass
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
tetris = Tetris()
tetris.show()
sys.exit(app.exec_())
为了看看我们的Board类中draw_square方法的效果,我们将其设为中心部件,并在它的paintEvent方法中调用draw_square方法绘制一个块,大小为100,100。然后可以再将CentralWidget类设为中心部件看看背景图的效果(请自行实现,改一个词而已) 截图:绘制方块和背景
有些鱼油喜欢先看效果,我把我用到的图片资源,打包好的tetris_files.py放到一个压缩文件里,需要的鱼油可以自行下载。
2021.11.20
准备用PySide2重新实现,原因见1#楼最后面更新的说明
请到129#楼,查看后续章节
|