前面两章通过元素/视图架构完成了一个贪吃蛇游戏,但这个游戏还有些不足,首先,游戏以吃到10个食物为胜利条件,而在游戏中用户却不知道游戏到底进行到哪一步了,其次,游戏的界面有些单调,比如蛇的身体,如果有些色彩会好看不少,所以对上上一章的游戏做些改进,大致上会是下面这个样子
从图上可以看出,每个食物上多了一个数字,这样可以提示用户游戏的精度,同时蛇的身体有了色彩上的变化,而实现这些功能,需要子类化QGraphicsItem。Qt提供了大量的QGraphicsItem的子类以供我们使用,但有时候出现要求比较特殊,Qt的默认类没办法满足我们的需求时,就必须子类化QGraphicsItem来实现。
首先看食物,上一章的食物使用的是QGraphicsRectItem,这里将会用一个自定义的FoodItem类来代替他,FoodItem继承自QGraphicsItem,QGraphicsItem里有两个纯虚函数需要实现.,首先看下FoodItem的头文件
class FoodItem : public QGraphicsItem
{
private:
int number_int; //该值用于记录当前的数字(即游戏中第几个食物)
public:
FoodItem(int nu , QGraphicsItem* parent = 0);
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget); //paint()和boundingRect()这两个是必须重写的纯虚函数
QRectF boundingRect()const;
QPainterPath shape()const; //这个函数用于显示外形,关于外形和外框稍后再述,这里这个函数可以暂时不用实现
void updateNumber(int nu); //这个自定义的函数用于更新食物上的数字
};
绘制函数的实现
void FoodItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
Q_UNUSED(option) //该函数不需要使用option和widget这两个参数,这里使用Q_UNUSED宏来避免编译器出现各种warning
Q_UNUSED(widget)
painter->setBrush(QBrush(Qt::yellow));
painter->drawRect(1,1,MAP_SIZE_SNAKE-2,MAP_SIZE_SNAKE-2); //绘制背景
painter->setPen(QPen(QColor(Qt::red)));
QFont ft;
ft.setPointSize(15);
painter->setFont(ft); //设置字体的颜色和大小,然后把数字绘制,写在item上
painter->drawText(QRect(1,1,MAP_S