2012-06-14 59 views
4

我有一個應用程序,你可以看到一個給定的2D遊戲回放:QGraphicsScene缺少特定項目更新

基本上,車輛行駛時在地圖上。該視圖集中在車輛上,因此地圖在重放播放時滾動,某種程度上微機 -like(這只是給出一個想法,實際的遊戲不是微機)。

http://www.randomracket.com/images/genesis-gems/micromachines.jpg

在我的場景,在車輛周圍移動地圖是靜態的。該視圖將滾動顯示重播的每一幀,以使車輛居中。 出於性能原因,地圖平鋪在幾個QGraphicsPixmapItem s。

視口更新模式設置爲QGraphicsView::BoundingRectViewportUpdate。 項目索引方法設置爲QGraphicsScene::NoIndex

在大多數情況下,一切工作正常。但是當地圖比平常大時,車輛不會更新。該視圖正在滾動,並且貼圖得到了更新;但不是車輛,除非我通過放大/縮小來觸發完整的視口更新(所以我知道該物品位置良好)。

車輛的boundingRect被永久設置一次,並且是有效的(見下文,在邏輯座標中給出)。我不繪製外部項目的邊界矩形。

調試輸出(僅第三配置不工作)的一些例子:

ok : 
vehicle->boundingRect() : QRectF(-1.9391,-1.9391 3.8782x3.8782) 
scene->sceneRect() : QRectF(-117.543,-38.3826 138.834x40.3217) 
SCENE_CACHING : 85 tiles 

ok : 
vehicle->boundingRect() : QRectF(-2.88489,-2.88489 5.76979x5.76979) 
scene->sceneRect() : QRectF(-68.8843,-18.2202 187.989x119.277) 
SCENE_CACHING : 308 tiles 

nok : vehicle won't update 
vehicle->boundingRect() : QRectF(-3.45546,-3.45546 6.91092x6.91092) 
scene->sceneRect() : QRectF(-64.2988,-107.802 188.927x187.445) 
SCENE_CACHING : 506 tiles 

我試圖調試更新通行證,確實Paint事件不包括在其中車輛是該地區...

任何人都知道爲什麼更新可能會錯過某個特定項目?

編輯:

的Qt:4.8.1,我已經看到與以前的版本問題以及

操作系統:Windows XP SP3,沒有其他OS的考驗

我沒有成功地用最小的例子來重現問題。最簡單的例子就像預期的那樣工作。在現實生活中,這裏是做什麼:

  1. 該地圖是從文件中讀取。它由多達數百個劃定地面/天空的多邊形組成(每個多邊形以圖形方式由多邊形,邊和頂點圖層構成),成千上萬的圖片和紋理然後剪切到地面或天空以及其他一些項目。

  2. 我計算所有的剪報,然後在QImage中渲染場景。圖像平鋪在幾個QGraphicsPixmapItem s添加到場景中,而前一項從場景中刪除並刪除(順便說一句,當我沒有刪除&刪除以前的項目時也發生了錯誤)。

  3. 重播啓動

我認爲Qt的圖形內部都搞砸了,但我無法弄清楚如何清理/重置。

這裏是一個圖形的例子(以說明我的意思是地面/天空)。地圖可能相當巨大。

http://kopasite.net/up/0/example.jpg

+0

你如何滾動視圖?你在使用'QGraphicsView :: centerOn'嗎? –

+0

不,我用'QGraphicsView'的滾動條爲中心,[像這樣](http://pastebin.com/vwNEFBQf) – azf

+1

我知道這是很多要問,但有沒有什麼辦法可以發佈工作最小的例子,重複的問題?另外,什麼操作系統和Qt版本? –

回答

3

從上面拿起我的評論作爲一個答案:

您需要使用QGraphicsScene::invalidate(...)無效應重繪場景的部分。

+0

感謝您的想法。有時閱讀文檔是不夠的。更確切地說,我使用了'QGraphicsScene :: invalidate(bRect,ItemLayer)',其中'bRect'是場景座標中的項目邊界矩形。而'ItemLayer'因爲我不使用背景或前景。 – azf

0

我相信這是類似於很多QGraphicsItems工作時,我有一個問題。我最終通過簡化我在屏幕上隨時顯示的QGraphicsItem的數量來解決我的問題,並且不緩存不需要緩存的QGraphicsItems。

一個簡單的方法來檢查,如果這是你的問題是:

vehicle->setCacheMode(QGraphicsItem::NoCache); 

這應該引起您車上的paint方法被稱爲每次它需要繪製。

+0

我嘗試了你的建議(即使Qt的文檔指出_默認模式是NoCache_),但沒有成功。儘管如此,只有在涉及很多項目時纔會發生。但只是渲染一次背景,然後刪除所有無用的項目。 – azf