現在要開始研究如何讓canvasitem之間的物件碰撞時,會觸發碰撞的訊息~
非常好~在QT中就內建了這一個函數!
bool QCanvasItem::collidesWith ( const QCanvasItem * other ) const [pure virtual]
這一個透過上一篇文章的例子做一些修改,可以知道這一個可以正確運作無誤~
void contentsMousePressEvent(QMouseEvent *e)
{
r->move(e->pos().x(), e->pos().y());
if (r->collidesWith(p))
t->setText("Collision");
else
t->setText("That is ok!");
}
當我按滑鼠時,程式會判斷三角型與正方型是否有碰撞~
基本上應該是要讓程式自己去偵測兩物是否有碰撞,而不是我去按滑鼠後,才去偵測~
目前我知道設定完setAdvancePeriod後,時間到後會自動呼叫advance(),
基本上偵測的function應該是要放在advance()裡面~
但是,void QCanvas::advance () [virtual slot]是父類別的function,而時間到的時候呼叫的是父類別的advance(),那麼應該如何修改,才會讓它呼叫子類別另外定義的advance哩~這是我目前需要解決的問題~明天試試看,先新建一個類別繼承QCanvas,然後,重新定義advance()試試看~有點累了~回家睡覺吧~
[2008.09.3 更新]
在今天早上研究到現在總算成功的讓每30毫秒就去判斷一次物件是否有碰撞到~
話不多說~直接把程式碼貼上來吧~我覺得我的方法還蠻笨的,沒有用到物件導向的精神~
我想當我上過這一個學期的物件導向後,應該會有更深入的認知吧~
說明主要的精神:
現在有兩個類別myqcanvas、View這兩個類別,而在main.cpp設定myqcanvas的velocity後,每30ms會呼叫advance()一次。因此我另外改寫了myqcanvas的advance,這裡有用到virtual function的觀念,請參考c++ - virtual function。
本來View、myqcanvas是兩個獨立的類別,但是,為了要讓View中的兩個圖形可以在myqcanvas的advance()判斷是否有碰撞,因此,在View中設定了三個回傳指標的public function。並在myqcanvas設定一個function可以設定這三個物件的指標。
本來每30豪秒會呼叫QCanvas::advance(),但是,因為,它是virtual function,所以,當我重新宣告一個advnace()時,就算是QCanvas指標指到MyQcanvas的物件,當透過QCanvas指標呼叫advance()時,就會是呼叫我新增的advance()了,而不是QCanvas的advance()~因此,完成了這一個碰撞的目標了~
myqcanvas.h
#ifndef MYQCANVAS_H
#define MYQCANVAS_H
#include <qcanvas.h>
class MyQCanvas:public QCanvas
{
Q_OBJECT
public:
MyQCanvas(int w=0,int h=0);
void setAddress(QCanvasPolygon*,QCanvasRectangle*,QCanvasText*); // 新增的部分,設定這三個物件的指標
protected:
void advance(); // 修改父類別的virtual function
private:
QCanvasPolygon *my_p; // 新增的變數,用來記錄多角形的指標
QCanvasRectangle *my_r; // 新增的變數,用來記錄方形的指標
QCanvasText *my_t; // 新增的變數,用來記錄文字的指標
};
#endif // MYQCANVAS_H
myqcanvas.cpp
#include "myqcanvas.h"
MyQCanvas::MyQCanvas(int w,int h):QCanvas(w,h)
{
// do nothing
}
void MyQCanvas::advance() // 新增的部分
{
if (my_r->collidesWith(my_p)) // 判斷是否有發生碰撞
my_t->setText("Collision");
else
my_t->setText("There is no Collision!");
QCanvas::advance(); // 衍生類別呼叫基底類別的advance function
}
void MyQCanvas::setAddress(QCanvasPolygon* p,QCanvasRectangle* r,QCanvasText* t)
{
my_p = p;
my_r = r;
my_t = t;
}
view.h
#ifndef VIEW_H
#define VIEW_H
#include <qcanvas.h>
class View:public QCanvasView
{
Q_OBJECT
public:
View(QCanvas& canvas);
QCanvasPolygon* getPolygon() const; // 新增的function,用來傳回多角形的指標
QCanvasRectangle* getRectangle() const; // 新增的function,用來傳回方形的指標
QCanvasText* getText() const; // 新增的function,用來傳回文字的指標
protected:
void contentsMousePressEvent(QMouseEvent *e);
private:
QCanvasPolygon *p;
QCanvasRectangle *r;
QCanvasText *t;
};
#endif // VIEW_H
view.cpp
#include <qfont.h>
#include <qimage.h>
#include "view.h"
View::View(QCanvas &canvas):QCanvasView(&canvas)
{
canvas.setBackgroundPixmap(QPixmap("logo.jpg"));
canvas.resize(370,300);
setFixedSize(sizeHint());
p = new QCanvasPolygon(&canvas);
QPointArray a;
a.setPoints(3,50,100,200,200,50,200);
p->setPoints(a);
p->setBrush(Qt::blue);
p->setZ(10);
p->show();
r = new QCanvasRectangle(100,100,50,100,&canvas);
r->setVelocity(0.5,0);
r->setBrush(Qt::red);
r->setZ(10);
r->show();
t = new QCanvasText("What will you",&canvas);
t->setFont(QFont("Helvetica",12,QFont::Bold));
t->setColor(Qt::blue);
t->setZ(20);
t->setTextFlags(AlignBottom);
t->move(5,20);
t->show();
}
void View::contentsMousePressEvent(QMouseEvent *e)
{
r->move(e->pos().x(),e->pos().y());
}
QCanvasPolygon* View::getPolygon() const
{
return p;
}
QCanvasRectangle* View::getRectangle() const
{
return r;
}
QCanvasText* View::getText() const
{
return t;
}
main.cpp
#include <qapplication.h>
#include "view.h"
#include "myqcanvas.h"
int main(int argc,char** argv)
{
QApplication app(argc,argv);
MyQCanvas canvas(0,0);
View c(canvas);
canvas.setAddress(c.getPolygon(),c.getRectangle(),c.getText()); // 新增的部分
canvas.setAdvancePeriod(30);
canvas.setDoubleBuffering(true);
app.setMainWidget(&c);
c.show();
return app.exec();
}
參考資料:回傳指標資料範例
[转]总述基金选择的步骤
16 年前
沒有留言:
張貼留言