• 3912阅读
  • 2回复

贪吃蛇/QGraphicsItem的问题 [复制链接]

上一主题 下一主题
离线qazaq408
 

只看楼主 倒序阅读 楼主  发表于: 2014-12-27
我在做一个贪吃蛇,其中蛇部分我用了QGraphicsItem,然后游戏在一个网格中进行,每个小格子是20X20大小,然后蛇由若干个20X20的格子组成

class Hunter:public QGraphicsItem
{
   int long_snake;  //蛇的长度,默认为5(个格子)
   QList<QPointF> blody_snake;
.
.
};

这里我设想用一个QList<QPointF>来存放每个格子的坐标,每次蛇移动的时候在容器前段加入一个QPointf,然后删除末尾的元素
构造函数里有
  1. long_snake = 5;
  2. for(int i = 0 ; i < long_snake ; i++)  
  3. {
  4.   QPointF points(i*20,0);  //初始的蛇为水平方向上的5个格子
  5.   blody_snake.append(points);
  6. }




paint()函数很简单,就一句
  1. painter->fillPath(shape(),Qt::green);
为了获得QPainterPath,我重写了shape()函数
  1. QPainterPath Hunter::shape()const
  2. {
  3.   QPainterPath paths;
  4.   for (auto A : blody_snake)     //c++11 for范围循环
  5.    paths.addRect(A.x(),A.y(),20,20);
  6.   return paths;
  7. }
到这里(似乎/应该)一切正常,然后在父对象里为了让蛇移动,每隔1秒就会调用一次advance()函数
  1. void Hunter::advance(int i)  //这里用i代表方向
  2. {                              //1上,2下,3左 ,4右
  3.   if(i == 2)
  4.    {
  5.     QPointF heads = *(blody_snake.begin());
  6.     qreal y = heads.y() - 20;
  7.     heads.setY(y);  //设置新蛇头坐标
  8.     blody_snake.push_front(heads);//添加蛇头
  9.     blody_snake.pop_back();  //删掉蛇尾
  10.     }
  11. }
这是其中蛇向下移动的代码,然后编译完成后
程序初始是这样的

但蛇开始运动的时候。。。

我想我不是把QList<QPointF>末尾用函数删了么。。怎么脱了个尾巴出来。。。

然后我程序又式了几次,时好时坏。。

求真相。。


离线dbzhang800

只看该作者 1楼 发表于: 2014-12-27
没仔细看你的问题,我提一点,可能对你有帮助:
如果你要改变一个item的 boundingRect 大小,在改变之前,一定要通知其 scene。具体看Manual

If you want to change the item's bounding rectangle, you must first call prepareGeometryChange(). This notifies the scene of the imminent change, so that it can update its item geometry index; otherwise, the scene will be unaware of the item's new geometry, and the results are undefined (typically, rendering artifacts are left within the view).
离线qazaq408

只看该作者 2楼 发表于: 2014-12-27
回 dbzhang800 的帖子
dbzhang800:没仔细看你的问题,我提一点,可能对你有帮助:
如果你要改变一个item的 boundingRect 大小,在改变之前,一定要通知其 scene。具体看Manual
If you want to change the item's bounding rectangle, you must first call prepareGeometryChange(). This notifies the scene o .. (2014-12-27 22:39)

额。。好了。。。
是这样的,在这个类里写了advance()函数,里面会改变蛇的形状
应为我不知道prepareGeometryChange()这个函数,
所以我直接在advance()函数里最后用update()来强制刷新一个绘图事件,就是我上面描述的问题
然后我把
update();这行注释掉,换成
prepareGeometryChange();

程序就OK了,我看QTassistan上写的这个函数会调用update(),使用这个函数和直接使用update()来刷新绘图事件不一样?
快速回复
限100 字节
 
上一个 下一个